问题情景
两次识别均未指定options参数,即使用默认参数,不检测方向;且都是文字较少的情况,长文字则没有问题。
发现问题后,使用参数,检测方向,结果仍然一样。
- 情景1:
识别结果:["四五六七", "月月月月"]。没错,百度竖着识别了。
- 情景2:
识别结果:["十", "一二"]。这次更绝,前两行的“九”、“十”都直接没了。
猜想
初步猜想为图片空白过多,导致百度竖着识别。
于是我使用python检测文字所在区域,然后截图。
代码:
def img_preprocess(gray): # 1. sobel,x方向求梯度 sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize=3) # 2. 二值化 ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY) # 3. 膨胀和腐蚀操作的核函数 element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9)) element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6)) # 4. 膨胀一次,让轮廓突出 dilation = cv2.dilate(binary, element2, iterations=1) # 5. 腐蚀一次,去掉细节。 erosion = cv2.erode(dilation, element1, iterations=1) # 6. 再次膨胀,让轮廓明显一些 dilation2 = cv2.dilate(erosion, element2, iterations=2) return dilation2 def find_text_region(source_img, img): # 1. 查找轮廓 contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) max_area = 0 max_contour = 0 # 找到最大的区域,按最大w,h截图 for i in range(len(contours)): cnt = contours[i] # 计算该轮廓的面积 area = cv2.contourArea(cnt) if area > max_area: max_area = area max_contour = cnt # 赋值max_w,max_h _, __, max_w, max_h = cv2.boundingRect(max_contour) # 找到第一个坐标 x, y, w, h = cv2.boundingRect(contours[-1]) # 这里max_h * 10是因为垂直方向并不存在多余像素,因此直接*10,超出图片宽度,保留竖直方向全部像素 img_result = source_img[y:y + max_h * 10, x:x + max_w + 10] cv2.imshow("img", img_result) cv2.waitKey(0) return img_result def detect(img): # 1. 转化成灰度图 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 2. 形态学变换的预处理,得到可以查找矩形的图片 dilation = img_preprocess(gray) # 3. 查找和筛选文字区域 crop_img = find_text_region(img, dilation) return crop_img detect(cv2.imread("answers.jpg"))
结果:
完美截图,再次调用百度云通用文字识别,识别结果["九", "十", "十一", "十二"]
多次测试之后,也没发现问题。我以为问题得到了解决,于是把程序打包发给别人测试,结果10张图片,4张识别错误。
无奈,放弃多行文字同一次识别,转而分割文本,单独识别每一行,就是大大降低了识别效率。
再次猜想:和图片分辨率有关,在我1080p的分辨率,0.85缩放,字号+1的环境下没问题。
但环境发生变化导致图片分辨率或字体大小产生变化,就会影响到识别结果。
暂未想到不影响效率的解决办法。
文章评论