import os import cv2 import numpy as np def char2num(char): if char in "0123456789": num = ord(char) - ord("0") + 1 elif char in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": num = ord(char.lower()) - ord("a") + 11 else: num = 0 return num def num2char(num): chars = "_0123456789abcdefghijklmnopqrstuvwxyz" char = chars[num] # if num >=1 and num <=10: # char = chr(ord('0') + num - 1) # elif num > 10 and num <= 36: # char = chr(ord('a') + num - 11) # else: # print('error number:%d'%(num)) # exit() return char def getstr_grid(seg, box, threshold=192): pos = 255 - (seg[0] * 255).astype(np.uint8) mask_index = np.argmax(seg, axis=0) mask_index = mask_index.astype(np.uint8) pos = pos.astype(np.uint8) string, score, rec_scores, char_polygons = seg2text( pos, mask_index, seg, box, threshold=threshold ) return string, score, rec_scores, char_polygons def seg2text(gray, mask, seg, box, threshold=192): ## input numpy img_h, img_w = gray.shape box_w = box[2] - box[0] box_h = box[3] - box[1] ratio_h = float(box_h) / img_h ratio_w = float(box_w) / img_w # SE1=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) # gray = cv2.erode(gray,SE1) # gray = cv2.dilate(gray,SE1) # gray = cv2.morphologyEx(gray,cv2.MORPH_CLOSE,SE1) ret, thresh = cv2.threshold(gray, threshold, 255, cv2.THRESH_BINARY) try: _, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) except: contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) chars = [] scores = [] char_polygons = [] for i in range(len(contours)): char = {} temp = np.zeros((img_h, img_w)).astype(np.uint8) cv2.drawContours(temp, [contours[i]], 0, (255), -1) x, y, w, h = cv2.boundingRect(contours[i]) c_x, c_y = x + w / 2, y + h / 2 perimeter = cv2.arcLength(contours[i], True) epsilon = 0.01 * cv2.arcLength(contours[i], True) approx = cv2.approxPolyDP(contours[i], epsilon, True) pts = approx.reshape((-1, 2)) pts[:, 0] = pts[:, 0] * ratio_w + box[0] pts[:, 1] = pts[:, 1] * ratio_h + box[1] polygon = list(pts.reshape((-1,))) polygon = list(map(int, polygon)) if len(polygon) >= 6: char_polygons.append(polygon) # x1 = x * ratio_w + box[0] # y1 = y * ratio_h + box[1] # x3 = (x + w) * ratio_w + box[0] # y3 = (y + h) * ratio_h + box[1] # polygon = [x1, y1, x3, y1, x3, y3, x1, y3] regions = seg[1:, temp == 255].reshape((36, -1)) cs = np.mean(regions, axis=1) sym = num2char(np.argmax(cs.reshape((-1))) + 1) char["x"] = c_x char["y"] = c_y char["s"] = sym char["cs"] = cs.reshape((-1, 1)) scores.append(np.max(char["cs"], axis=0)[0]) chars.append(char) chars = sorted(chars, key=lambda x: x["x"]) string = "" css = [] for char in chars: string = string + char["s"] css.append(char["cs"]) if len(scores) > 0: score = sum(scores) / len(scores) else: score = 0.00 if not css: css = [0.0] return string, score, np.hstack(css), char_polygons # def get_tight_rect(points, start_x, start_y, image_height, image_width, scale): # points = list(points) # ps = sorted(points, key=lambda x: x[0]) # # if ps[1][1] > ps[0][1]: # px1 = ps[0][0] * scale + start_x # py1 = ps[0][1] * scale + start_y # px4 = ps[1][0] * scale + start_x # py4 = ps[1][1] * scale + start_y # else: # px1 = ps[1][0] * scale + start_x # py1 = ps[1][1] * scale + start_y # px4 = ps[0][0] * scale + start_x # py4 = ps[0][1] * scale + start_y # if ps[3][1] > ps[2][1]: # px2 = ps[2][0] * scale + start_x # py2 = ps[2][1] * scale + start_y # px3 = ps[3][0] * scale + start_x # py3 = ps[3][1] * scale + start_y # else: # px2 = ps[3][0] * scale + start_x # py2 = ps[3][1] * scale + start_y # px3 = ps[2][0] * scale + start_x # py3 = ps[2][1] * scale + start_y # # if px1 < 0: # px1 = 1 # if px1 > image_width: # px1 = image_width - 1 # if px2 < 0: # px2 = 1 # if px2 > image_width: # px2 = image_width - 1 # if px3 < 0: # px3 = 1 # if px3 > image_width: # px3 = image_width - 1 # if px4 < 0: # px4 = 1 # if px4 > image_width: # px4 = image_width - 1 # # if py1 < 0: # py1 = 1 # if py1 > image_height: # py1 = image_height - 1 # if py2 < 0: # py2 = 1 # if py2 > image_height: # py2 = image_height - 1 # if py3 < 0: # py3 = 1 # if py3 > image_height: # py3 = image_height - 1 # if py4 < 0: # py4 = 1 # if py4 > image_height: # py4 = image_height - 1 # return [px1, py1, px2, py2, px3, py3, px4, py4] def get_tight_rect(points, start_x, start_y, image_height, image_width, scale): points = list(points) ps = sorted(points, key=lambda x: x[0]) if ps[1][1] > ps[0][1]: px1 = ps[0][0] * scale + start_x py1 = ps[0][1] * scale + start_y px4 = ps[1][0] * scale + start_x py4 = ps[1][1] * scale + start_y else: px1 = ps[1][0] * scale + start_x py1 = ps[1][1] * scale + start_y px4 = ps[0][0] * scale + start_x py4 = ps[0][1] * scale + start_y if ps[3][1] > ps[2][1]: px2 = ps[2][0] * scale + start_x py2 = ps[2][1] * scale + start_y px3 = ps[3][0] * scale + start_x py3 = ps[3][1] * scale + start_y else: px2 = ps[3][0] * scale + start_x py2 = ps[3][1] * scale + start_y px3 = ps[2][0] * scale + start_x py3 = ps[2][1] * scale + start_y px1 = min(max(px1, 1), image_width - 1) px2 = min(max(px2, 1), image_width - 1) px3 = min(max(px3, 1), image_width - 1) px4 = min(max(px4, 1), image_width - 1) py1 = min(max(py1, 1), image_height - 1) py2 = min(max(py2, 1), image_height - 1) py3 = min(max(py3, 1), image_height - 1) py4 = min(max(py4, 1), image_height - 1) return [px1, py1, px2, py2, px3, py3, px4, py4]