一:概念:
滤波是信号处理机图像处理中的一个基本操作。滤波去除图像中的噪声,提取感兴趣的特征,允许图像重采样。
图像中的频域和空域: 空间域指用图像的灰度值来描述一幅图像 ;而 频域指用图像灰度值的变化来描述一幅图像 。而低通滤波器和高通滤波器的概念就是在频域中产生的。
低通滤波器指去除图像中的高频成分,而高通滤波器指去除图像中的低频成分。
后面将介绍低通滤波器—均值和高斯滤波器;中值滤波器—非线性滤波器;高通滤波器—sobel 算子(方向滤波器)和拉普拉斯变换(二阶导数)。其中利用方向滤波器和拉普拉斯变换可以对图像的边缘进行检测。
二:低通滤波器
<1>cv::blur函数: 每个像素替换为相邻矩形内像素的平均值
<2>cv::GaussianBlur函数: 通过高斯核来进行替换
Code:
Mat result; // 线性平滑 滤波 每个像素替换为相邻矩形内像素的平均值 blur(image, result,Size(5,5)); // filter2D可以自定义核进行线性滤波 Mat gauResult; GaussianBlur(image, gauResult, Size(5,5), 1.5); // 高斯平滑 模糊 线性滤波器
Result:
sourceImage:
BlurResult:
GaussianBlur:
低通滤波器的效果是对图像进行模糊和平滑,减弱了物体边缘可见的快速变化。它是一种线性滤波器,原理是与核进行卷积运算,此时的核内定,当我们需要指定核函数进行卷积时可以用filter2D函数,它的使用见blog: http://blog.csdn.net/lu597203933/article/details/16811851 。
三:中值滤波器
中值滤波器是非线性滤波器, 它的原理是仅仅计算这组数的中值,并用中值替换当前的像素值 。因此对于去除椒盐噪点非常有用。
Code:
Mat medianResult; medianBlur(image, medianResult,5); // 是一个非线性的滤波器,利用中值替换当前的像素值,对于去除椒盐噪点尤为有用
Result:
三:方向滤波器—sobel算子
Sobel算子就是通过卷积操作来计算图像的一阶导数,由于边缘处图像灰度变化率较大,因此可以用sobel算子来进行边缘检测。Sobel算子的核定义为:
y坐标轴:
x坐标轴:
Sobel函数:Sobel(InputArray src, OutputArray dst, int ddepth,
int dx, int dy, int ksize=3,
double scale=1, double delta=0,
int borderType=BORDER_DEFAULT );
其中ddepth为图像类型, (dx,dy) = (1,0)为x方向导数,(dx,dy) = (0,1)为y方向导数,scale和delta的作用是再保存前可以对图像进行缩放,公式为:dst =dst * scale + delta.
Code:
int main() { Mat image = imread("F:\\lena.png", 0); if(!image.data) { cout << "Fail to load image" << endl; return 0; } Mat sobel_x, sobel_y; //Sobel(image, sobel_x, CV_8U, 1, 0, 3, 0.4, 128); //Sobel(image, sobel_y, CV_8U, 0, 1, 3, 0.4, 128); Sobel(image, sobel_x, CV_16S, 1, 0); // 因为后面要相加 所以用16位有符号的整数来表示 另外导数肯定含有负数 Sobel(image, sobel_y, CV_16S, 0, 1); Mat sobel; sobel = abs(sobel_x) + abs(sobel_y); double sobmin, sobmax; minMaxLoc(sobel, &sobmin, &sobmax); Mat sobelImage; sobel.convertTo(sobelImage, CV_8U, -255.0/sobmax, 255); // 等价于 saturate_cast(a*sobel + b) Mat sobelThresholded; int thre = 200; threshold(sobelImage, sobelThresholded, thre, 255, THRESH_BINARY); namedWindow("sobelImage", 0); imshow("sobelImage", sobelImage); namedWindow("sobelThresholded", 0); imshow("sobelThresholded", sobelThresholded); waitKey(0); return 0; }
Result:
当然除了sobel算子,还有其它的算子,如Scharr算子,它更精确、快。它的核为:
Sobel(image, sobelX, CV_16S, 1, 0,CV_SCHARR);
或者:
Scharr(image, scharrX, CV_16S, 1, 0, 3);
四:拉普拉斯变换
拉普拉斯变化时基于图像导数的高通滤波器,计算二阶导数以衡量图像的弯曲度
Code:
int main() { Mat image = imread("F:\\lena.png", 0); if(!image.data) { cout << "Fail to load image" << endl; return 0; } Mat laplacian; Laplacian(image, laplacian, CV_16S, 3); // 二阶导数肯定含有负数。。 基于图像导数的高通滤波器,计算二阶导数以衡量图像的弯曲度 laplacian = abs(laplacian); Mat laplacianImage; laplacian.convertTo(laplacianImage, CV_8U); namedWindow("laplacianImage"); imshow("laplacianImage", laplacianImage); waitKey(0); return 0; }
Result:
作者:小村长 出处:
http://blog.csdn.net/lu597203933
欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)