概述
上一篇博客中,我们把图片中的水印去除掉,并且加深了字体的颜色,之后我对图片的大小进行了统一,甚至我还专门给他们都加上了参照字段,分别尝试了百度AIP的表格识别服务和Face++的自定义模板文字识别服务,可能是因为图片的分辨率较低,而且文字较密集的缘故,最终得到的结果都不尽如人意,错误率非常高,所以准备尝试下先将图片按照行列进行分割,之后再逐个去识别的方法,结果却出乎我的意料。
识别表格
要想对图片中的表格进行精准切分,就必须要先对表格进行识别,然后再根据行列相交点的位置进行切分。
读取中文路径的图片
1 | def cv_imread(filepath): |
将图片转为黑底白字
因为后续的
膨胀
是对高亮部分(白色)进行处理,所以就需要把我们感兴趣的部分——表格线转为白色
1 | #转为二值图,矩阵中只有0和255 |
查看效果
1 | cv2.imshow("Image",img_thresh) |
识别
1 | rows,cols=img_thresh.shape |
识别的关键就在于腐蚀
与膨胀
函数。腐蚀即为让卷积核在二值化的图片上滑动并进行卷积计算,只有在卷积核范围内图片中的所有值均为255时才会得到255的结果,其余情况均得到0;而膨胀刚好相反,在卷积核范围内只要有一个值为255,那么就会得到255的结果。
所以,在我们进行表格中的行识别时,就需要选择尽可能长(很多列)和矮(一行)这种形状的卷积核,才能契合长长的横线,然后把比较短的文字腐蚀掉。看下面的示例:
示例图片的shape为(369,1000)
precision=20
时,卷积核的shape为(50,1),识别得到的结果:
这时候已经把所有行都识别出来了,因为不会有任何一个字的长度可以超过50个像素,那么现在我们把卷积核的shape调整到(5,1)再来看下效果。
precision=200
时,识别得到的结果:
可以发现,很多字中的横
都没有被腐蚀掉。
筛选交点位置坐标
我们筛选出那些在行和列都等于255的点,就可以得到所有交点了。
1 | intersections = cv2.bitwise_and(row_lines,col_lines) |
1 | #筛选出白点的索引(坐标) |
这样我们就把所有交点的坐标都筛选出来了。
截取图片并识别
按照交点坐标截取单元格后,再转换为jpg或者是png格式的二进制编码,利用百度aip的通用文字识别API进行识别,获取结果。
1 | #按照交点坐标截取单元格 |
最后再利用Pandas将得到的结果以此储存到DataFrame中,导出Excel,收工!
总结
- 识别方法很笨,虽然正确率较高,但是识别速度较慢;
- 依赖百度文字识别服务。
下一步尝试:
- Google开源OCRtesseract-ocr
- 基于yolo3 与crnn 实现中文自然场景文字检测及识别的chineseocr
- 基于tensorflow、keras/pytorch的OCR中文文字识别CHINESE-OCR
参考
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。