抠字调研报告
1.需求分析
抠字的需求:把纸上的文字抠出来以透明背景的png的格式保存下来。这个png的图片有两个用处:1、保存到本地相册;2、作为水印添加到另一张图片上,这个水印png可以拉伸、拖动改变位置
需求分解
- 把纸上的文字保存为黑白图片
- 把该图片背景色改为透明
2.实现文字转墨迹图片
-
对
iOS
平台处理图片文字相关库OpenCV
和Tesseract
的了解 -
OpenCV
有一个imgproc
模块,是用来图像处理相关,包括线性和非线性图像滤波、几何图像转换、颜色空间转换、直方图等等。确认使用OpenCV
来处理该功能 -
利用
opencv
对图片进行处理,步骤大致如下1. 图像彩色转灰度 2. 灰度图像设置阈值后二值化即变成完全黑白 3. 去除多余的噪点
3.1 将
UIImage
对象转成转成cv::Mat
3.2 把图片放大
3.3 转化成灰度图CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
在opencv中,其默认的颜色制式排列是BGR而非RGB。所以对于24位颜色图像来说,前8-bit是蓝色,中间8-bit是绿色,最后8-bit是红色。 code=COLOR_BGR2GRAY
3.4 二值化转为完全黑白
OpenCV
提供了两个函数,第一个是普通的Threshold
函数:CV_EXPORTS_W double threshold( InputArray src, OutputArray dst, double thresh, double maxval, int type );
传入图像,传出图像,阈值,填充的最深颜色,填充方法(达到阈值就填充最深颜色或相反),就可以根据每个像素的灰度值与阈值进行比较来决定填充的值为0或是最深。
定阈值的方法虽然可以对一张图像通过调整达到最优的效果,但是对于不同光照条件下拍摄出来的照片,因为整体亮度的不同,定阈值显然无法适应所有的情况。
所以就有了第二种函数,
adaptiveThreshold
,除了传入上面的这些参数外,增加了三个重要的参数CV_EXPORTS_W void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C );
blockSize
:对某个像素周围进行采样的范围。
adaptiveMethod
:根据上面的范围求阈值的方法,有两种:mean平均,简单地取采样范围内的平均值作为阈值。 gaussian高斯,以高斯函数为基础,简单地说就是近的地方权重更高、远的地方权重低,来求阈值。
C
:求出来的阈值减去的常量。3.5 去噪点
去噪的目的是把图像中的独立的点去掉。去噪的方法是腐蚀,跟字面意思一样,就是缩小图案的范围,当图像的范围本身就很小时(噪点就是一个个这样的独立点),缩小后自然就不见了。
可以想到,在去噪后,部分笔画也随之缩小甚至细的地方会直接消失,所以腐蚀之后要再进行一步膨胀,即把图案的边缘扩大。
因为噪点已经消失,所以也不会因扩大而回来,但笔画依然存在,就会膨胀而得到弥补,也顺便可以补一下残缺的地方。
原理大概就是这样,但是由于
OpenCV
的这两个操作针对的是图像中的亮点(白色的地方被认为是亮点),而我们的表格又是白底黑字的,实际上黑色的部分是我们想要处理的部分,所以我将这两步交换了,相当于是对黑色的地方先腐蚀后膨胀。代码如下
//膨胀一次 cv::Mat dilateelement = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(8,8)); cv::Mat dilate1; dilate(binary, dilate1, dilateelement); //轻度腐蚀一次,去除噪点 cv::Mat element3 = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(8,8)); cv::Mat erode11; erode(dilate1, erode11, element3);
参考网站
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html#morphology-1
https://www.viseator.com/2016/11/15/OpenCV%E5%A4%84%E7%90%86%E6%8B%8D%E7%85%A7%E8%A1%A8%E6%A0%BC%EF%BC%88%E4%B8%80%EF%BC%89/
3.把图片修改为透明颜色
遍历图片的所有像素,把是白色或者接近白色的像素改成透明色。
将像素点转成子节数组来表示---第一个表示透明度即`ARGB`这种表示方式。
4.总结
抠字功能主要用到了OpenCV
Core Image
,我对这两个库都是基础了解,很多功能都在网上查找的。实现该功能最困难的地方就是在照片腐蚀膨胀那,参数配置做了大量的测试,有些图片处理后噪点还是很多,有些又处理过了,需要在这中间找到一些平衡。
网友评论