平滑,也称为模糊,是一种简单而经常使用的图像处理操作。
要执行平滑操作,我们将对我们的图像应用过滤器。最常见的滤波器类型是线性的,其中输出像素的值(i.e. g(i,j)),被确定为输入像素值的加权和 (i.e. f(i+k,j+l)) :
被称为内核,它只不过是滤波器的系数。h(k,l)
它有助于将过滤器可视化为跨越图像滑动的系数窗口。
//平均滤波
void photoBlur(const cv::Mat src, cv::Mat &dst)
{
/**
* blur 平均滤波器
* src 原始图
* dst 目标图
* ksize 滤波器大小,如(5,5)
* anchor 内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值( -1, -1),表示锚位于内核中心。
* borderType 卷积填充方式,包括BORDER_CONSTANT:使用常量值(即黑色或0)来填充图像, BORDER_REPLICATE:原始边缘的行或列被复制到额外的边框,BORDER_REFLECT 等)
**/
CV_EXPORTS_W void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT );
cv::blur(src, dst, cv::Size(3, 3));
}
假设图像为1D,您可以注意到位于中间的像素将具有最大的权重。其邻居的权重随着它们与中心像素之间的空间距离的增加而减小。
注意
请记住,2D高斯可以表示为:
其中是平均值(峰值),\ sigma表示方差(每个变量x和y)μσXÿ
//高斯平滑滤波
void photoGaussianBlur(const cv::Mat src, cv::Mat& dst)
{
/**
* GaussianBlur 高斯平滑滤波器
* src 原始图
* dst 目标图
* ksize 滤波器大小,如(5,5)
* sigmaX:X方向上的高斯核标准偏差;
* sigmaY:Y方向上的高斯核标准偏差,如果sigmaY为0,则将其设置为与sigmaX相同的值,如果sigmaX和sigmaY都是0,则分别跟据ksize.width和ksize.height计算而来;
* borderType 卷积填充方式,包括BORDER_CONSTANT, BORDER_REPLICATE,BORDER_REFLECT 等)
**/
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT );
cv::GaussianBlur(src, dst, cv::Size(3, 3), 0);
}
中值滤波器遍历信号的每个元素(在这种情况下为图像),并用其相邻像素的中位数(位于估计像素周围的正方形邻域)中替换每个像素。
//中值滤波
void photoMedianBlur(const cv::Mat src, cv::Mat& dst)
{
/**
* medianBlur 中值滤波器
* src 原始图
* dst 目标图
* ksize 内核的大小(只有一个,因为我们使用一个方形窗口)
**/
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
cv::medianBlur(src, dst, 3);
}
//双边滤波
void photoBilateralFilter(const cv::Mat src, cv::Mat& dst)
{
/**
* bilateralFilter 双边滤波器
* src 原始图
* dst 目标图
* d 过滤期间使用的各像素邻域的直径
* sigmaColor 色彩空间的 到一起,从而造成更大范围的半相等颜色 sigma参数,该参数较大时,各像素邻域内相距较远的颜色会被混合
* sigmaSpace 坐标空间的sigma参数,该参数较大时,只要颜色相近,越远的像素会相互影响
* borderType 卷积填充方式,包括BORDER_CONSTANT, BORDER_REPLICATE,BORDER_REFLECT 等)
**/
CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT );
cv::bilateralFilter(src, dst, 5, 150, 150);
}
/**
* 几种滤波Demo
* 平均滤波、高斯平滑滤波、中值滤波、双边滤波
* 1、平滑滤波包括平均滤波、高斯滤波、中值滤波等方法,其中高斯滤波最为常用
* 2、平滑滤波具有去除噪声效果,不同滤波方法具有对不同噪声的适应性
* 3、中值滤波对椒盐噪声有效
**/
#include
#include
//平均滤波
void photoBlur(const cv::Mat src, cv::Mat &dst)
{
/**
* blur 平均滤波器
* src 原始图
* dst 目标图
* ksize 滤波器大小,如(5,5)
* anchor 内核的锚点,指示内核中过滤点的相对位置;锚应位于内核中;默认值( -1, -1),表示锚位于内核中心。
* borderType 卷积填充方式,包括BORDER_CONSTANT, BORDER_REPLICATE,BORDER_REFLECT 等)
**/
cv::blur(src, dst, cv::Size(3, 3));
}
//高斯平滑滤波
void photoGaussianBlur(const cv::Mat src, cv::Mat& dst)
{
/**
* GaussianBlur 高斯平滑滤波器
* src 原始图
* dst 目标图
* ksize 滤波器大小,如(5,5)
* sigmaX:X方向上的高斯核标准偏差;
* sigmaY:Y方向上的高斯核标准偏差,如果sigmaY为0,则将其设置为与sigmaX相同的值,如果sigmaX和sigmaY都是0,则分别跟据ksize.width和ksize.height计算而来;
* borderType 卷积填充方式,包括BORDER_CONSTANT, BORDER_REPLICATE,BORDER_REFLECT 等)
**/
cv::GaussianBlur(src, dst, cv::Size(3, 3), 0);
}
//中值滤波
void photoMedianBlur(const cv::Mat src, cv::Mat& dst)
{
/**
* GaussianBlur 中值滤波器
* src 原始图
* dst 目标图
* ksize 内核的大小(只有一个,因为我们使用一个方形窗口)
**/
cv::medianBlur(src, dst, 3);
}
//双边滤波
void photoBilateralFilter(const cv::Mat src, cv::Mat& dst)
{
/**
* bilateralFilter 双边滤波器
* src 原始图
* dst 目标图
* d 过滤期间使用的各像素邻域的直径
* sigmaColor 色彩空间的 到一起,从而造成更大范围的半相等颜色 sigma参数,该参数较大时,各像素邻域内相距较远的颜色会被混合
* sigmaSpace 坐标空间的sigma参数,该参数较大时,只要颜色相近,越远的像素会相互影响
* borderType 卷积填充方式,包括BORDER_CONSTANT, BORDER_REPLICATE,BORDER_REFLECT 等)
**/
cv::bilateralFilter(src, dst, 5, 150, 150);
}
int main()
{
// 读取图片
std::string imagename = "Standard_image/lena.jpg";
cv::Mat img = cv::imread(imagename);
// 判断载入图片是否成功
if (img.empty())
{
std::cout << "miss the image file : " + imagename << std::endl;
return -1;
}
cv::Mat BlurImg, GaussianBlurImg, MedianBlurImg, BilateralFilterImg;
photoBlur(img, BlurImg);
photoGaussianBlur(img, GaussianBlurImg);
photoMedianBlur(img, MedianBlurImg);
photoBilateralFilter(img, BilateralFilterImg);
cv::imshow("原图", img);
cv::imshow("平均滤波", BlurImg);
cv::imshow("高斯滤波", GaussianBlurImg);
cv::imshow("中值滤波", MedianBlurImg);
cv::imshow("双边滤波", BilateralFilterImg);
cv::waitKey();
return 0;
}