前言
由于计算机最擅长二进制处理,因此将图片导入到计算模块前需要进行颜色空间上的调整,将 RGB 空间调整为黑白二色的颜色空间,同时对图像形态进行简单优化,使得处理更加快捷,处理效果更优化。
颜色空间转换
颜色空间调节的目标是将其从 RGB 空间调节到黑白颜色空间。首先,输入的是一张彩色图片,要将他调整到灰度,以方便二值化。
在转换灰度是这里有一点和常识不同的地方,通常认为灰度即一个像素点的 (R,G,B) 值取平均。三基色红绿蓝,亮度不同(根据常用标准 CCIR 601
,红绿蓝的视觉亮度之比为 (2.99:5.87:1.14)),并且因为简单求和的值不整除 (3),会造成轻微的失真,因此不能简单使用 (frac{R+G+B}{3}) 来计算。
然后要进行二值化。因为不同的图片灰度后的结果不同,例如较暗的图片灰度值偏高,而较亮的图片灰度值偏低,因此需要用户手动调节阈值进行二值化。
OpenCV 自带了 threshold
函数,但使用时出现了一些小问题。使用时,第一次选定阈值,能够正确输出二值化图像,第二次选定阈值,图片转为全黑或全白。结合图像处理经验和测试图像本身,排除了未成功调用函数的情况后,发现是源图片被更新为二值化后的图片,第二次二值化即对第一次二值化的结果进行二值化,但检查代码发现无此类赋值语句。查询 OpenCV 文档对 Mat
类的定义发现,Mat
类中将矩阵通过 uchar *data
进行引用,因此赋值时共享了矩阵数据,在二值化时数个 Mat
所共享的矩阵数据被改变。结合 Mat
类的构造方法,设计在二值化函数中即时申请新的矩阵,可以保证原图数据安全和二值化顺利实施。
小结
通过实现二值化,加深了对 Mat
类的了解和对颜色和颜色转换的理解。不仅实现了功能,也了解了很多新东西。
灰度图
二值化结果1
抛弃了手机状态栏上的信息。
二值化结果2
保留了重要信息。
手动形态优化
对于表格框线等二值化等操作难以去掉的内容,提供给了用户一个手工操作的途径。使用 std::vector<std::vector<int> >imgdata
的嵌套,动态模拟二维数组,避免空间浪费。之前使用的是 bool 的数据类型,但一直出现乱码情况,即 push_back 后马上访问返回一串乱码,经了解其为 vector 对 bool 类型的特化。通过找联通块并用 (1 imes 1) 白色矩形抹除 + imgdata 对应标记为 0,用户在表格边上轻松双击右键,即可将整个表格去除!