目录
采用不同的滤波方式来对图像进行降噪、增强细节等处理。不通滤波方式核心是采取的滤波器不同。
线性滤波器有 方框滤波、均值滤波、高斯滤波等。
非线性滤波有 中值滤波、双边滤波等。
滤波操作也可以在图像的 频域 进行,利用 离散傅里叶变换。
几种常见的线性滤波器(频率即指灰度值的变化,频率高灰度值变化快):
低通滤波器:允许低频率通过。
高通滤波器:允许高频通过。
带通滤波器:允许一定范围内的频率通过。
带阻滤波器:阻止一定范围内的频率通过。
全通滤波器:允许所有频率通过,仅仅改变相位关系。
陷波滤波器:阻止一个狭窄频率范围通过,是一种特殊的带阻滤波器。
方框滤波
函数原型如下:
void boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1, -1), bool normalize = true, int borderType = BORDER_DEFAULT)
(1)第一个参数,InputArray 类型的 src,为源图像(Mat 类型的对象)。该函数对通道是独立处理的,且可以处理任意通道的图像,但其深度应为 CV_8U、CV_16U、CV_16S、CV_32F、CV_64F 之一。
(2)第二个参数,OutputArray 类型的 dst,为输出图像,需要和源图像有一样的尺寸和类型。
(3)第三个参数,int 类型的 ddpeth,输出图像的深度,-1 代表使用源图像的深度,即 src.depth()。
(4)第四个参数,Size 类型的 ksize,内核的大小。一般用 Size(w, h) 表示内核的大小,w 表示内核的宽度,h 表示内核的高度。
(5)第五个参数,Point 类型的anchor,表示锚点(即被平滑处理的那个店)。默认为(-1,-1)。若该点为负值,则表示内核的中心点为锚点。
(6)第六个参数,bool 类型的 normalize,默认值为 true。表示内核是否被归一化了。被归一化即为 均值滤波。
(7)第七个参数,int 类型的 borderType,用于推断图像外部像素的某种边界模式。一般使用默认值即可。
均值滤波
函数原型如下:
void blur(InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1, -1), int borderType = BORDER_DEFAULT);
(1)第一个参数,InputArray 类型的 src,参考方框滤波中的 src,注意图像深度的取值。
(2)第二个参数,OutputArray 类型的 dst,输出图像,同方框滤波中的 dst。
(3)第三个参数,Size 类型的 ksize。
(4)第四个参数,Point 类型的 anchor。
(5)第五个参数,int 类型的 borderType。
高斯滤波
函数原型如下:
void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);
(1)第一个参数,InputArray 类型的 src,源图像。
(2)第二个参数,OutPutArray 类型的 dst,输出图像。
(3)第三个参数,Size 类型的 ksize,内核大小。
(4)第四个参数,double 类型的 sigmaX,表示高斯函数在 X 轴方向上的标准偏差。
(5)第五个参数,double 类型的 sigmaY,表示高斯函数在 Y 轴方向上的标准偏差,默认值为 0 。若 sigmaY 为 0,将其设为 sigmaX,若 sigmaX 也为 0 ,则有 ksize.width 和 ksize.height 计算出来。
(6)第六个参数,int 类型的 borderType。
中值滤波
函数原型如下:
void medianBlur(InputArray src, OutputArray dst, int ksize);
(1)第一个参数,InputArray 类型的 src,源图像。
(2)第二个参数,OutputArray 类型的 dst,输出图像。填通道数为1、3、4 的 图像。若 ksize 为 3 或 5,则图像深度的取值为 CV_8U、CV_16U、CV_32F之一。对于较大孔径尺寸的图像,深度只能为 CV_8U。
(3)第三个参数,int 类型的 ksize,孔径的线性尺寸,(3,5,7....)。
双边滤波
函数原型如下:
void bilateraFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT);
(1)第一个参数,源图像。
(2)第二个参数,输出图像。
(3)第三个参数,int 类型的 d,表示在过滤过程中每个像素邻域的直径。若该参数为非正数,会通过 sigmaSpace 计算。
(4)第四个参数,double 类型的 sigmaColor ,颜色空间滤波器的 sigma 值 。该参数值越大,说明该像素邻域内越宽广的颜色会被混合到一起,产生较大半径的半相等颜色区域。
(5)第五个参数,double 类型的 sigmaSpace,坐标空间滤波器的 sigma 值。该参数值越大,说明越远的像素会相互影响。参数 d > 0 时,d 指定了 邻域大小且与 sigmaSpace 无关。否则,d 正比于 sigmaSpace。
(6)第六个参数,int 类型的 borderType。用于推断图像外部像素的某种边界模式。
先简单写个示例演示四种滤波器(均值滤波、高斯滤波、中值滤波、双边滤波),代码如下:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void on_Smoothing(int, void*);
int smoothType = 0;
int maxSmoothType = 3;
int kernelSize = 1;
int maxKernelSize = 31;
const char* smoothTypeStr = "滤波器类型 ";
const char* kernelSizeStr = "滤波器大小 ";
Mat srcSmoothImage, dstSmoothImage;
int main()
{
srcSmoothImage = imread("cat.jpg");
if (srcSmoothImage.empty())
{
cout << "原图读取发生错误!\n" << endl;
}
imshow("原图", srcSmoothImage);
namedWindow("效果图", WINDOW_AUTOSIZE);
createTrackbar(smoothTypeStr, "效果图", &smoothType, maxSmoothType, on_Smoothing);
createTrackbar(kernelSizeStr, "效果图", &kernelSize, maxKernelSize, on_Smoothing);
on_Smoothing(0, 0);
waitKey(0);
return 0;
}
void on_Smoothing(int, void*)
{
Size smoothSize = Size(2 * kernelSize + 1, 2 * kernelSize + 1);
int smoothsize = 2 * kernelSize + 1;
switch (smoothType)
{
/**
0: 均值滤波
1: 高斯滤波
2: 中值滤波
3: 双边滤波
*/
case 0:
blur(srcSmoothImage, dstSmoothImage, smoothSize, Point(-1, -1));
break;
case 1:
GaussianBlur(srcSmoothImage, dstSmoothImage, smoothSize, 0, 0);
break;
case 2:
medianBlur(srcSmoothImage, dstSmoothImage, smoothsize);
break;
case 3:
bilateralFilter(srcSmoothImage, dstSmoothImage, smoothsize, smoothsize * 2, smoothsize / 2);
break;
default:
break;
}
imshow("效果图", dstSmoothImage);
}
运行结果如下所示:
不知道为啥 trackbar 的名字显示不全....