修改了之前的滤波算法,采用了copyMakeBorder扩充边界像素,给处理边界像素带来了很大的方便
<span style="font-size:14px;">void Blur(const Mat &image_Src, Mat &image_Dst, Size size_Aperture)
{
/////////////////////////////step 1.重新分配图像(如果需要)/////////////////////////////////////////////
//新图像的大小
int width_Dst=image_Src.cols;
int height_Dst=image_Src.rows;
image_Dst.create(Size(width_Dst,height_Dst),CV_8UC1);//如果重新分配,之前的空间会扔掉
//////////////////////////////step 2.创建一副新图像(对源图像加以扩充)////////////////////////////////////////////
//扩充的大小
int width_Extend=size_Aperture.width>>1;
int height_Extend=size_Aperture.height>>1;
//创建新图像</span><span style="font-size:14px;"><span style="white-space:pre"> </span>//这里采用了与OpenCV相同的方式BORDER_DEFAULT
Mat image_New;
copyMakeBorder(image_Src,image_New,height_Extend,height_Extend,width_Extend,width_Extend,BORDER_DEFAULT);
////////////////////////////step 3.滤波//////////////////////////////////////////////
//新图像参数
int width_New=image_New.cols;
int height_New=image_New.rows;
int widthStep_New=width_New;
//滑动窗口
int width_Aperture=size_Aperture.width;
int height_Aperture=size_Aperture.height;
int pixelCount=width_Aperture*height_Aperture;
//计算需要滤波像素的起点坐标
int startX=width_Aperture>>1;
int startY=height_Aperture>>1;
//每列的灰度值和
int *sum_PerCol=new int[width_New];
//对新图像做滤波处理
uchar *row_New=image_New.data+startY*widthStep_New+startX;
uchar *row_Dst=image_Dst.data;//第一行
uchar *row_Aperture_New=image_New.data;
for (int y=startY;y<=height_New-startY-1;++y)
{
//列
uchar *col_Dst=row_Dst;
uchar *col_Aperture_New=row_Aperture_New;
//计算每列height_Aperture个像素的灰度值和
//第一行,计算所有列的和
if (y==startY)
{
for (int k=0;k<=width_New-1;++k)
{
sum_PerCol[k]=0;
//每列第一个指针
uchar *col_PerLine=col_Aperture_New+k;
for (int t=0;t<=height_Aperture-1;++t)
{
sum_PerCol[k]+=col_PerLine[0];
col_PerLine+=widthStep_New;//下一行
}
}
}
else//非第一行
{
for (int k=0;k<=width_New-1;++k)
{
//每列第一个指针
uchar *col_=col_Aperture_New+k;
sum_PerCol[k]-=col_[0-widthStep_New];//减上面
sum_PerCol[k]+=col_[0+(height_Aperture-1)*widthStep_New];//加下面
}
}
//计算width_Aperture行的列总和
int sum_Aperture=0;
for (int x=startX;x<=width_New-startX-1;++x)
{
//每行第一个元素,求width_Aperture个列和
if (x==startX)
{
for (int k=0;k<=width_Aperture-1;++k)
{
sum_Aperture+=sum_PerCol[k];
}
}
else//非第一个元素
{
//减去左边
sum_Aperture-=sum_PerCol[x-startX-1];
//加上右边
sum_Aperture+=sum_PerCol[x+startX];
}
//求均值
uchar meanValue=sum_Aperture/pixelCount;
col_Dst[0]=meanValue;
//滑动一个像素
col_Dst++;
//col_New++;//这里不需要对源图像指针进行滑动
}
//下一行
row_Dst+=width_Dst;
row_Aperture_New+=width_New;
}
}</span>测试结果:
原图
结果
高效均值滤波(采用copyMakeBorder处理边界像素)
原文地址:http://blog.csdn.net/qianqing13579/article/details/42324645