均值滤波的基本原理很简单,就是用滑动窗口内所有像素的平均值代替窗口中心像素的灰度值
高效均值滤波的原理如下:
代码:
//高效均值滤波
void Blur(const Mat &p_w_picpath_Src, Mat &p_w_picpath_Dst, Size size_Aperture)
{
//step 1.重新分配图像(如果需要)/
//新图像的大小
int width_Dst=p_w_picpath_Src.cols;
int height_Dst=p_w_picpath_Src.rows;
p_w_picpath_Dst.create(Size(width_Dst,height_Dst),CV_8UC1);//如果重新分配,之前的空间会扔掉
p_w_picpath_Dst.setTo(Scalar(0));
//滑动窗口
int width_Aperture=size_Aperture.width;
int height_Aperture=size_Aperture.height;
int pixelCount=width_Aperture*height_Aperture;
int *sum_PerCol=new int[width_Dst];//每列的灰度值
//计算起点坐标
int startX=width_Aperture>>1;
int startY=height_Aperture>>1;
//第一行
//三个关键的指针,这三个指针绑定在一起,一起滑动
//1.2:需要被处理的像素
//3:滑动窗口第一个元素,用来操作滑动窗口
uchar *row_Src=p_w_picpath_Src.data+startY*width_Dst+startX;
uchar *row_Dst=p_w_picpath_Dst.data+startY*width_Dst+startX;
uchar *row_Aperture_Src=p_w_picpath_Src.data;
for (int y=startY;y<=height_Dst-startY-1;++y)
{
//列
uchar *col_Src=row_Src;
uchar *col_Dst=row_Dst;
uchar *col_Aperture_Src=row_Aperture_Src;
//计算每列height_Aperture个像素的灰度值和
//第一行,计算所有列的和
if (y==startY)
{
for (int k=0;k<=width_Dst-1;++k)
{
sum_PerCol[k]=0;
//每列第一个指针
uchar *col_PerLine=col_Aperture_Src+k;
for (int t=0;t<=height_Aperture-1;++t)
{
sum_PerCol[k]+=col_PerLine[0];
col_PerLine+=width_Dst;//下一行
}
}
}
else//非第一行
{
for (int k=0;k<=width_Dst-1;++k)
{
//每列第一个指针
uchar *col_=col_Aperture_Src+k;
sum_PerCol[k]-=col_[0-width_Dst];//减上面
sum_PerCol[k]+=col_[0+(height_Aperture-1)*width_Dst];//加下面
}
}
//计算width_Aperture行的列总和
int sum_Aperture=0;
for (int x=startX;x<=width_Dst-startX-1;++x)
{
//每行第一个元素,求width_Aperture个列和
if (x==startX)
{
for (int k=x-startX;k<=x+startX;++k)
{
sum_Aperture+=sum_PerCol[k];
}
}
else//非第一个元素
{
//减去左边
sum_Aperture-=sum_PerCol[x-1-startX];
//加上右边
sum_Aperture+=sum_PerCol[x+startX];
}
//求均值
uchar meanValue=sum_Aperture/pixelCount;
col_Dst[0]=meanValue;
//滑动一个像素
col_Dst++;
col_Src++;
}
//下一行
row_Dst+=width_Dst;
row_Src+=width_Dst;
row_Aperture_Src+=width_Dst;
}
}
使用大小为3行5列的窗口,运行效果图:
运行这段代码之前,需要配置一下OpenCV,算法核心和OpenCV没有太大关联。
注意:算法没有处理边界的情况,还不太清楚怎么处理边界,有会的朋友,希望能够一起分享一下边界处理的一些技巧
代码写的不是特别规范,大家有什么看不懂的地方,可以提出来
转载于:https://blog.51cto.com/qianqing13579/1590213