均值濾波的基本原理很簡單,就是用滑動窗口內所有像素的平均值代替窗口中心像素的灰度值
高效均值濾波的原理如下:
代碼:
//高效均值濾波 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);//如果重新分配,之前的空間會扔掉 image_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=image_Src.data+startY*width_Dst+startX; uchar *row_Dst=image_Dst.data+startY*width_Dst+startX; uchar *row_Aperture_Src=image_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沒有太大關聯。
注意:算法沒有處理邊界的情況,還不太清楚怎麼處理邊界,有會的朋友,希望能夠一起分享一下邊界處理的一些技巧
代碼寫的不是特別規範,大家有什麼看不懂的地方,可以提出來