基于笔画宽度转换(SWT)和连通域的汉字检测方法
在upwork上看到一个有意思的项目,该项目要求处理一组图片,该组图片分为两部分,A区有一部分区域包含3~5个汉字,白底黑字,其他没有字的部分为黑色背景;B区背景色彩斑斓,前景随机分布着A区的汉字。处理要求是依据A区汉字的顺序分别找到其在B区的位置,并识别A区的汉字。
该项目附件中包含了大量类似的待处理图片,我下载了附件并将项目要求作为我学习opencv的新目标。我认为该项目的处理思路大致如下:找到B区中汉字的位置,对B区汉字区域进行局部去噪和二值化处理,然后根据汉字特征对B区和A区的文字进行匹配,最后用Tesseract对A区汉字进行识别;或者直接用Tesseract对A区和处理后的B区汉字进行识别,再根据识别结果进行匹配,虽然尚未尝试用Tesseract对B区汉字进行识别,不过我猜用通用的识别模板识别效果应该不好,要想Tesseract可以识别B区的汉字,B区的汉字需要准确被检出,要进行倾斜校正,并且要单独针对B区汉字的字体进行模板训练,工作量也是相当的巨大。
但不论是哪一种方案,首先要对B区的文字进行检出,这也是本文后续要记录的主要内容。
基于笔画宽度转换(SWT)和连通域的汉字检测
在此类图片中检出汉字,我能想到的方案有两种:一,手动从原图中截取大量的正样本(包含汉字)和负样本(不包含汉字),用HOG特征和SVM来训练识别汉字的模型,由训练模型来预测汉字所在区域;二,根据汉字特征对图像进行处理后识别出汉字所在区域,即基于笔画宽度转换(SWT)和连通域的汉字检测。
我尝试了基于笔画宽度转换(SWT)和连通域的汉字检测,大致思路如下:
1. 根据《基于笔画宽度转换的文字检测(SWT)方法》一文中提到的SWT求取图像笔画宽度图。观察图片库中不同图片的字体大小和笔画宽度比较接近,根据笔画宽度的分布对不合理的笔画进行过滤;
2. 对过滤后的笔画宽度图进行开操作和连通域处理connectedComponentsWithStats;
4. 对connectedComponentsWithStats得到的连通域进行过滤:根据汉字特征和此类图像笔画宽度特征,根据连通域面积,长,宽进行过滤,仅保留符合汉字特征的连通域。
6. 对过滤得到的连通域求取直方图,根据有字体的主要笔画宽度比例进行过滤;
7. 对最后留下的连通域进行如下规则的合并:连通域质心的宽度和高度均在一定像素值以内;
8. 在原图中用矩形找出最后保留下来的连通域并标注。
上述尝试方案的代码已上传至Github:ExtractChar,其效果示意图如下图所示:
基于笔画宽度转换(SWT)和连通域的汉字方法测试
我在图库中挑选了6张有代表性的图进行验证,检测结果参差不齐,汉字颜色与背景色对比明显的基本都会被检测出来;相反,汉字颜色与背景色对比度小的比较难被检测。
本课题的后续学习方向
目前通过SWT和连通域定位汉字的效果并不理想,针对此项目的其他要求,我也尝试过以下方案:
1.用Tesseract对A区汉字进行识别,识别正确率约60%,并不理想。
2.通过surfMatch或MatchTemplate对A区和B区的汉字进行匹配。在理想状态下,两张图中待匹配的汉字无倾斜,无变形,无噪声,非常清晰,shsurfMatch无法完成匹配工作;MatchTemplate则可以准确的匹配到汉字,但是待匹配文字旋转角度超过45度时,其匹配精确度大大降低,超过90度或字体有变形时,MatchTemplate也无能为力。
目前学习目标暂未达成,但在学习过程中发现了opencv多个好用的功能,其中连通域和将Mat数据写入Excel表格是最值得推荐的,请参阅:
connectedComponentsWithStats在汉字定位中的应用
若有同学对该学习课题有兴趣,欢迎随时留言讨论。
汉字的定位可以用faster RCNN来做,我自己标了1000张类似的数据用来训练,最后定位的准确率在95%+。
苦恼的是汉字的识别部分,不知道如何下手。
用Tesseract中文库试过吗?不过这个中文库只能识别比较标准的字体。