http://blog.csdn.net/kezunhai
模糊滤镜主要用来修饰边缘过于清晰,或者对比度过于强烈的图像,或者图像中含有大量噪声,通过图像平滑可以使图像变得更加柔和。一般情况下,在空间域内可以用邻域平均来使图像灰度平滑过度,达到柔和效果;在频率域内,由于噪声多在高频段,因此可以采用低通滤波来达到目的。
模板操作是数字图像处理中经常用到的一种运算方法,图像平滑、锐化、细化及边缘检测等都要用到模板操作。模板操作实现了一种邻域运算,即某个像素点的结果不仅和本像素的灰度相关,而且和其邻域点的值有关。模板运算在数学中描述的是卷积运算。理解卷积的最好方法就是将它看做一个加权求和的过程。卷积时使用的权用一个小矩阵来表示,矩阵的大小一般是奇数,而且与使用的区域大小相同。这种权矩阵叫做卷积核,区域中的每个像素分别于卷积核中的每个元素对应相乘,所有乘积之和,就称为该区域中心像素的新值。
卷积核中的每个元素叫做卷积系数,卷积核中卷积系数的大小、方向及排列次序决定图像卷积后处理的最终效果。改变卷积核中的加权系数,会影响到综合的数值与符号,从而影响到所求像素的新值。常用卷积核有3×3、5×5、7×7等,所有卷积核的行、列都是奇数。均值滤波、高斯滤波以及各种自定义的滤波都可以通过模板操作来实现。
算法实现:
// 模板操作 // temp:卷积核的加权系数(一般都进行了归一化) // kSize:卷积核的大小3、5、7等(3×3、5×5、7×7) void PhotoShop::TemplateBlur(cv::Mat &img, cv::Mat &dst, double temp[], int kSize) { 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()); int i, j, k, p , q; float sum = 0; int index = 0; 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++) { sum = 0; index = 0; for ( p = -border; p<=border; p++) { for ( q = -border; q<=border; q++) { sum += getPixel(img, i+p, j+q, k)*temp[index]; index++; } } dstData[j*chns+k] = saturate_cast<uchar>(sum); } // for k } } }
以下是均值模板的测试效果:
从图上可以看到,原图中头发线条明显在处理后的图像中显得很柔和,其他区域也显得柔和多了,如美女手里的羽毛。
作者:kezunhai 出处:http://blog.csdn.net/kezunhai 欢迎转载或分享,但请务必声明文章出处。