PhotoShop算法实现进阶-模糊滤镜-中值滤波(二十二)
中值滤波是一种非线性滤波。中值滤波在一定条件下可以克服线性滤波器如最小均方滤波、均值滤波(BoxFilter)等带来的图像细节的模糊,而且对滤除椒盐灵三点的噪声最为有效。但对于一些细节多,特别是点、线、尖顶细节多的图像不宜采用中值滤波。
中值滤波一般采用一个含有奇数个点的滑动窗口,将窗口中各点灰度值的中值来替代指定点的灰度值。对于奇数个元素,中值是值排序后中间的数值;对于偶数则是排数后中间两个元素的平均值。常用的中值滤波窗口有线状、方形、原型、十字型等,本文算法只实现方形的中值滤波,其他形状的中值滤波实现方式相似。
算法实现:
// 中值滤波, kSize:尺寸 void PhotoShop::MedianBlur(cv::Mat &img, cv::Mat &dst, int kSize=3) { int height = img.rows; int width = img.cols; int chns = img.channels(); int border = (kSize-1)/2; // 边界像素不处理 int totalNum = kSize*kSize; // 模板大小 int iMid = (totalNum-1)/2; // 模板中间值索引号 if ( dst.empty()) dst.create(height, width, img.type()); vector<uchar> ucharVal; int i, j, k, p , q; for ( i =border; i<height-border; i++) { unsigned char* dstData = (unsigned char*)dst.data + dst.step*i; for ( j=border; j<width-border; j++) { for ( k=0; k<chns; k++) { ucharVal.clear(); for ( p = -border; p<=border; p++) { for ( q = -border; q<=border; q++) { ucharVal.push_back(getPixel(img, i+p, j+q, 0)); } } sort(ucharVal.begin(), ucharVal.end()); // 排序 dstData[j*chns+k] = ucharVal[iMid]; //setPixel(dst, i,j, 0, ucharVal[iMid]); } // for k } } }
测试效果(kSize=5):
从图中可以看到,图像的对比度有了明显的下降,而且模糊了。
作者:kezunhai 出处:http://blog.csdn.net/kezunhai 欢迎转载或分享,但请务必声明文章出处。