平滑滤波是一种简单又常见的图像处理操作。平滑图像的目的有很多,但通常都是为了减少噪声和伪影。
在OpenCV中共有5种平滑滤波操作,分别是以下几种:
实验测试代码如下:
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = cv::imread("F:/图像处理/图片一/outThee2.jpg", 0);
if (srcImage.empty())
{
printf("图片读取失败!\n");
return -1;
}
Mat outputImage;
//简单模糊滤波器
//blur(srcImage, outputImage, Size(3, 3));
//方框型滤波器
//boxFilter(srcImage, outputImage, -1, Size(3, 3));
//中值滤波器
medianBlur(srcImage, outputImage, 3);
//高斯滤波器
//GaussianBlur(srcImage, outputImage, Size(3, 3), 0.0, 0.0);
//双边滤波器
//bilateralFilter(srcImage, outputImage, 9, 10.0, 50.0);
imshow("原图", srcImage);
imshow("滤波处理后的图像", outputImage);
waitKey(0);
return 0;
}
输入的源图像
(1) 简单模糊滤波器
void cv::blur(
cv::InputArray src, //输入图像
cv::OutputArray dst, //滤波后得到的图像
cv::Size ksize, //窗口(核)的尺寸大小
cv::Point anchor = cv::Point(-1, -1), //核与源图像的对齐方式。默认值为Point(-1,-1),表示核相等滤波器居中
int borderType = cv::BORDER_DEFAULT //边界类型
);
//5种边界类型
cv::BORDER_CONSTANT //复制指定的常量扩展边界
cv::BORDER_WRAP //复制对边的像素扩展边界
cv::BORDER_REPLICATE //复制边缘的像素扩展边界
cv::BORDER_REFLECT //通过镜像复制扩展边界
cv::BORDER_REFLECT_101 //通过镜像复制扩展边界,边界像素除外
cv::BORDER_DEFAULT //cv::BORDER_REFLECT_101的别名
滤波结果:
从结果来看,简单模糊滤波对于点状噪声的处理有一定效果,但不理想。
(2) 方框型滤波器
void cv::boxFilter(
cv::InputArray src, //输入图像
cv::OutputArray dst, //滤波得到的图像
int ddepth, //输出图像的深度,取-1表示与源图像一致
cv::Size ksize, //核的大小
cv::Point anchor = cv::Point(-1, -1), //核与源图像的对齐方式
bool normalize = true,
int borderType = cv::BORDER_DEFAULT //边界类型
);
滤波结果:
简单模糊是方框型滤波器的一种特殊形式,从测试结果来看,它们两个的滤波效果基本是一样的。
(3) 中值滤波器
void cv::medianBlur(
cv::InputArray src, //输入图像
cv::OutputArray dst, //滤波后得到的图像
int ksize //核大小
);
滤波结果:
由于中值滤波是将每个像素替换为围绕这个像素的矩形领域内的中值像素,因此对图像中较大的异常孤立值非常敏感,所以中值滤波对于这种点状噪声的处理效果是最好的。
(4) 高斯滤波器
void cv::GaussianBlur(
cv::InputArray src, //输入图像
cv::OutputArray dst, //滤波后得到的图像
cv::Size ksize, //核尺寸的大小
double sigmaX,
double sigmaY,
int borderType = cv::BORDER_DEFAULT
);
滤波结果:
高斯滤波虽然非常常用,但是对于这种点状噪声的处理,还是不太适用的。
(5) 双边滤波器
void cv::bilateralFilter(
cv::InputArray src, //输入图像
cv::OutputArray dst, //滤波后得到的图像
int d,
double sigmaColor,
double sigmaSpace,
int borderType = cv::BORDER_DEFAULT
);
滤波结果: