方框滤波的核表示如下:
h代表该点的像素值
hsize代表滤波核
这里的normalize默认为ture,normalize为ture时,方框滤波其实就是均值滤波了
假设滤波核大小为3*3的的,锚点坐标为(x,y),则在目标图像上对应(x,y)这点的像素值为:
h = (f(x-1,y-1) + f(x,y-1)+ f(x+1,y-1) + f(x-1,y) + f(x,y) + f(x+1,y) + f(x-1,y+1) + f(x,y+1) + f(x+1,y+1))/(3*3)
C++: void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
#include
using namespace cv;
int main()
{
cv::Mat srcimage = cv::imread("test.png");
cv::namedWindow("源图像");
cv::namedWindow("滤波后");
std::cout << std::endl;
std::cout << std::endl;
std::cout << std::endl;
//show the source image
cv::imshow("源图像", srcimage);
cv::Mat dstimage;
cv::boxFilter(srcimage, dstimage,-1, cv::Size(3,3));
cv::imshow("滤波后", dstimage);
cv::waitKey(0);
return 0;
}
可以使用这种方式查看图像对应的像素值:
for (int y = 0; y < srcimage.rows; y++)
{
for (int x = 0; x < srcimage.cols; x++)
{
std::cout << (int)(srcimage.at(y, x)[0]) << " " << (int)(srcimage.at(y, x)[1]) << " " << (int)(srcimage.at(y, x)[2]) << ",";
}
std::cout << std::endl;
}
但是这里涉及一个边界填充的问题,边上进行滤波的时候,会有边界填充的,如果使用的是BORDER_REFLECT_101,就需要使用对称法,也就是以最边缘像素为轴对称,不能简单地由源图像按公式推输出图像,
缺陷:不能很好得保存图像的细节,去噪的同时会破坏图像的细节从而使图像模糊,不能很好地去噪。
它的原理就是在求均值,对滤波核所对应的所有元素的像素值进行求和再求出均值,再将这个均值赋值给锚点所对应像素作为该像素的值。
C++: void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
#include<opencv2/opencv.hpp>
void main3()
{
cv::Mat srcimage = cv::imread("腐蚀_膨胀.png");
cv::namedWindow("源图像");
cv::imshow("源图像", srcimage);
cv::namedWindow("均值滤波");
cv::Mat dstimage;
cv::blur(srcimage, dstimage, cv::Size(15, 15));
cv::imshow("均值滤波", dstimage);
cv::waitKey(0);
}
高斯滤波是一种线性平滑滤波,可以消除高斯噪声,广泛应用于图像处理减噪过程。
高斯滤波就是每个像素点的值都是由其本身和邻域内的其他像素值经过加权平均后得到的。
高斯函数具有五个重要的性质,这些性质使得它在早期图像处理中特别有用.这些性质表明,高斯平滑滤波器无论在空间域还是在频率域都是十分有效的低通滤波器,且在实际图像处理中得到了工程人员的有效使用.高斯函数具有五个十分重要的性质,它们是:
(1)二维高斯函数具有旋转对称性,即滤波器在各个方向上的平滑程度是相同的.一般来说,一幅图像的边缘方向是事先不知道的,因此,在滤波前是无法确定一个方向上比另一方向上需要更多的平滑.旋转对称性意味着高斯平滑滤波器在后续边缘检测中不会偏向任一方向.
(2)高斯函数是单值函数.这表明,高斯滤波器用像素邻域的加权均值来代替该点的像素值,而每一邻域像素点权值是随该点与中心点的距离单调增减的.这一性质是很重要的,因为边缘是一种图像局部特征,如果平滑运算对离算子中心很远的像素点仍然有很大作用,则平滑运算会使图像失真.
(3)高斯函数的付立叶变换频谱是单瓣的.正如下面所示,这一性质是高斯函数付立叶变换等于高斯函数本身这一事实的直接推论.图像常被不希望的高频信号所污染(噪声和细纹理).而所希望的图像特征(如边缘),既含有低频分量,又含有高频分量.高斯函数付立叶变换的单瓣意味着平滑图像不会被不需要的高频信号所污染,同时保留了大部分所需信号.
(4)高斯滤波器宽度(决定着平滑程度)是由参数σ表征的,而且σ和平滑程度的关系是非常简单的.σ越大,高斯滤波器的频带就越宽,平滑程度就越好.通过调节平滑程度参数σ,可在图像特征过分模糊(过平滑)与平滑图像中由于噪声和细纹理所引起的过多的不希望突变量(欠平滑)之间取得折衷.
(5)由于高斯函数的可分离性,大高斯滤波器可以得以有效地实现.二维高斯函数卷积可以分两步来进行,首先将图像与一维高斯函数进行卷积,然后将卷积结果与方向垂直的相同一维高斯函数卷积.因此,二维高斯滤波的计算量随滤波模板宽度成线性增长而不是成平方增长.
#include<opencv2/opencv.hpp>
void mian()
{
cv::Mat srcimage = cv::imread("腐蚀_膨胀.png");
cv::namedWindow("srcimage");
cv::namedWindow("dstimage");
cv::imshow("srcimage", srcimage);
cv::Mat dstimage;
cv::GaussianBlur(srcimage, dstimage, cv::Size(5, 5), 0, 0);
cv::imshow("dstimage", dstimage);
cv::waitKey(0);
}
#include
cv::Mat g_srcImage, g_dstImage1, g_dstImage2, g_dstImage3;
int g_nBoxFilterValue = 3; //方框滤波的参数值
int g_nMeanBlurValue = 3; //均值滤波参数值
int g_nGaussianBlurValue = 3; //高斯滤波参数值
//轨迹调回调函数
static void on_BoxFilter(int, void *);
static void on_MeanBlur(int, void *);
static void on_GaussianBlur(int, void *);
void main4()
{
g_srcImage = cv::imread("腐蚀_膨胀.png");
if (!g_srcImage.data)
std::cout << "图片加载失败!" << std::endl;
g_dstImage1 = g_srcImage.clone();
g_dstImage2 = g_srcImage.clone();
g_dstImage3 = g_srcImage.clone();
cv::namedWindow("源图像");
cv::imshow("源图像", g_srcImage);
/******************** Boxfilter ***********************/
cv::namedWindow("BoxFilter");
//创建滑块条
cv::createTrackbar("内核值:", "BoxFilter", &g_nBoxFilterValue, 40, on_BoxFilter);
on_BoxFilter(g_nBoxFilterValue,0);
cv::imshow("BoxFilter", g_dstImage1);
/***********************MeanBlur************************/
cv::namedWindow("MeanBlur");
cv::createTrackbar("内核值:", "MeanBlur", &g_nMeanBlurValue, 40, on_MeanBlur);
on_BoxFilter(g_nMeanBlurValue, 0);
cv::imshow("MeanBlur", g_dstImage2);
/*********************GaussianBlur***********************/
cv::namedWindow("GaussianBlur");
cv::createTrackbar("内核值:", "GaussianBlur", &g_nGaussianBlurValue, 40, on_GaussianBlur);
on_GaussianBlur(g_nGaussianBlurValue, 0);
cv::imshow("GaussianBlur", g_dstImage3);
while (char(cv::waitKey(1)) != 'q') {};
}
static void on_BoxFilter(int, void *)
{
cv::boxFilter(g_srcImage, g_dstImage1, -1, cv::Size(g_nBoxFilterValue + 1, g_nBoxFilterValue + 1));
cv::imshow("BoxFilter", g_dstImage1);
}
static void on_MeanBlur(int, void*)
{
cv::blur(g_srcImage, g_dstImage2, cv::Size(g_nMeanBlurValue + 1, g_nMeanBlurValue + 1),cv::Point(-1,-1));
cv::imshow("MeanBlur", g_dstImage2);
}
static void on_GaussianBlur(int, void *)
{
cv::GaussianBlur(g_srcImage, g_dstImage3, cv::Size(g_nGaussianBlurValue*2 + 1, g_nGaussianBlurValue*2 + 1), 0, 0);
cv::imshow("GaussianBlur", g_dstImage3);
}