接上文,已经识别出页面元素,接下来需要识别出文字,并与元素关联

https://blog.dappwind.com/2020/05/13/index.html

元素的文字识别

使用 tesseract的效果好很多,所以采用 tesseract

tesseract测试: https://github.com/yuxizhe/OCR/blob/master/tesseract.ipynb

如果用tesseract对整个图片进行文字识别的话,返回的是要么是全部的字符串,要么是每个字和每个字的坐标,很难与元素关联起来。

尝试了多种方式未果,后来决定采用对每个元素的图片进行单独识别,这样可以很方便的把文字与元素建立关联关系。

元素内文字的识别比较方便,直接调用识别即可。

表单元素前面的文字也是需要识别的,这里采用简单的方案,大概取元素 前300px 生成一个图片,对这个图片进行文字识别,结果就是表单元素的介绍文字。

把方法编写成function如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 识别元素内及元素前的文字

def element_ocr(cropped, img, x, y, w, h):
# 识别矩形中的文字
inner_text = pytesseract.image_to_string(cropped, lang='chi_sim')
print('元素内文字: '+ inner_text)

# 识别矩形前的文字 往前300
textAreaBefore = img[y:y+h,max(0,x-300):x]
cv2_imshow(textAreaBefore)

# 识别前序文字
before_text = pytesseract.image_to_string(textAreaBefore, lang='chi_sim')
print('元素前区域文字: '+before_text)

return inner_text,before_text

结果打印如下

1
2
3
4
5
6
7
组件0: Input :     before:*Bundle id:
组件1: Button : before:* 更新信息:
组件2: Input :请输入版本号 (例如: 11.31) before:* 版本号:
组件3: Input :ioS before:* 平台:
组件4: Input :雪球 before:* APP名:
组件5: Button :出 点击上传 ipa 文件 before:* 上传ipa 文件:
组件6: Input :Public before:* 包类型:

将文字显示在图片上

cv2 的 putText方法不支持直接显示中文,会出现问号乱码

参考这篇文章

https://www.cnblogs.com/vipstone/p/8998249.html

1
2
3
4
5
6
7
8
9
10
11
# 中文字体显示
from PIL import Image, ImageDraw, ImageFont

def cv2ImgAddText(img, text, left, top, textColor=(255, 0, 255), textSize=15):
if (isinstance(img, np.ndarray)): #判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img)
fontText = ImageFont.truetype(
"/content/PingFang.ttc", textSize, encoding="utf-8")
draw.text((left, top), text, textColor, font=fontText)
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)

把展示识别结果的函数修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 在图片上显示结果
# 通过ImageDataGenerator.flow 后 顺序会变化
def result_show_in_image(img, boxes, predicted_name):
newImage = img.copy()
for index in range(len(boxes)):
item = boxes[index]
box = item[0]
name = predicted_name[index]
text = '组件: ' + name + ' :'+ item[1] + ' before:'+ item[2]
print('组件'+ str(index) + ': ' + text)
# 中文字体显示
newImage = cv2ImgAddText(newImage, text, min(box[2][0],box[0][0]) + 10, max(box[2][1],box[0][1]) - 30)
# cv2.putText(newImage, name, (min(box[2][0],box[0][0]) + 10, max(box[2][1],box[0][1]) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (225,0,225), 1)
cv2_imshow(newImage)

结果如下