接到个任务需要将几万张带表格的图片转换成结构化数据。
1. 大步骤
最终算是完成任务,但是识别率上还有一点问题,人工再过一下,还是蛮快的。先说一下大的步骤:分割单元格。将图片中的表格全部定位出来,然后按单元格裁剪成一个个小图片,以便后续分析及操作;
聚焦。其实就是将单元格中的文本区域裁剪出来,将多余的空白去掉;
大图片的识别。对于大图片用图像相似性的算法(phash+汉明距离)做识别;
小图片的识别。对于小图片,做字符分割,然后用NN做分类识别;
识别结果输出到txt;
txt输出到excel。将全部txt按照目标表格的格式,解析输出到excel。
1.1 分割单元格
既然只关心表格区域,所以第一步先将各个单元格拆分出来,截取成一个个小图片。尝试用图像的膨胀、腐蚀来定位表格区域,图像处理包skimage,最后算是定位出了表格区域,也分割出了各个单元格图片,其中部分中间过程的图片如下:
分割单元格这一块的基本流程是:读取图像;
二值化处理;
横向、纵向的膨胀、腐蚀操作,得到横线图img_row和竖线图img_col;
得到点图,img_row + img_col=img_dot;
得到线图,img_row × img_col=img_line(线图只是拿来看看的,后续没有用到);
浓缩点团到单个像素;
开始遍历各行的点,将各个单元格从二值图像上裁剪出来,保存到temp文件夹。
参考资料:
1.1.1 读取图像、二值化import skimage
# 读取图片,并转灰度图
img=io.imread(imgFilePath,True)
#二值化
bi_th=0.81
img[img<=bi_th]=0
img[img>bi_th]=1
1.1.2 膨胀、腐蚀操作# 膨胀腐蚀操作
def dil2ero(img,selem):
img=morphology.dilation(img,selem)
imgres=morphology.erosion(img,selem)
return imgres
# 求图像中的横线和竖线
rows,cols=img.shape
scale=80
col_selem=morphology.rectangle(cols//scale,1)
img_cols=dil2ero(img,col_selem)
row_selem=morphology.rectangle(1,rows//scale)
img_rows=dil2ero(img,row_selem)
1.1.3 得到点图、线图# 线图
img_line=img_cols*img_rows
# 点图
img_dot=img_cols+img_rows_temp
img_dot[img_dot>0]=1
img_dot=clearEdge(img_dot,3)
1.1.4 浓缩点为单个像素# 收缩点团为单像素点(3×3)
d