百度云ocr在识别每行文字个数相同,有多行的时候会出现竖着识别的情况
问题情景
两次识别均未指定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"))</code></pre>
结果:
完美截图,再次调用百度云通用文字识别,识别结果["九", "十", "十一", "十二"]
多次测试之后,也没发现问题。我以为问题得到了解决,于是把程序打包发给别人测试,结果10张图片,4张识别错误
无奈,放弃多行文字同一次识别,转而分割文本,单独识别每一行,就是大大降低了识别效率
再次猜想
和图片分辨率有关,在我1080p的分辨率,0.85缩放,字号+1的环境下没问题
但环境发生变化导致图片分辨率或字体大小产生变化,就会影响到识别结果
暂未想到不影响效率的解决办法