二值图像的噪点去除算法
众所周知,二值图(前景黑色,背景白色) 由于低熵特性,能玩的花样很少, 很多图像处理算法难以实施在二值图上, 同时由于大部分二值图(传真,商业扫描文档),存在很多噪音, 噪音去除算法是大家比较感兴趣的, 尤其是涉及到OCR识别。
噪音样例
以下是两个样例, 一个噪音较多,一个噪音较少, 注意噪音并不是单点,也包括halftone算法造成的灰度转二值噪音。
--------------------------------------------------------------------
如何处理
大家第一感觉是通过形态学开闭运算解决, 但并没有什么卵用, 哦, 不,有用,但会将有效内容去掉,所以当然是不行的, 而且开闭运算需要两次filter,性能较差。
下面是解决方案, 直接上代码, 多快好省,效果好, 由于太简单, 直接看代码就好了, 算法逻辑就不多说了。
稍微说下, 此算法核心目的是去除噪点同时尽量不丢失有效信息,切记。
//去除二值图噪音, data:图像数据(单通道二值黑白,0黑,0xff白), byteLine:每行字节数, width:宽度,height:高度
int _removeNoise(unsigned char* data, int byteLine, int width, int height)
{
using namespace cv;
cv::Size sz(width, height);
Mat img(sz, CV_8UC1, data, byteLine);
Mat1b imgTmp = img.clone();
cv::morphologyEx(imgTmp, imgTmp, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
imgTmp = 0xff - imgTmp ;
Mat kernel = Mat::ones(5, 5, CV_32F) / (float)(25);
filter2D(imgTmp , imgTmp , -1, kernel);
imgTmp = 0xff - imgTmp ;
threshold(imgTmp , imgTmp , 220, 255, THRESH_BINARY);
img = img | imgTmp ;
return 0;
}
上述代码去除了噪音,同时很好的保留了有效文字信息。
处理结果
--------------------------------------------------------------------
其他说明
上述代码大家应该都能看懂,注意如果噪音过于密集, 请自行调整代码中参数。 最后一个图包含用于OCR的分块处理, 下次有时间另外开贴写。