在博文中《OpenCV之最值濾波和非最值抑制》中實現了最值濾波和非最值抑制,在本博文中將實現序統計濾波,最值濾波和中值濾波都是其特例。序統計濾波器的敘述和應用,在岡薩雷斯的《數位影像處理》中有述。代碼如下,希望有用。注意代碼未經最佳化。
//==================================================================== // 作者 : quarryman // 郵箱 : quarrying{at}qq.com // 首頁 : http://blog.csdn.net/quarryman // 日期 : 2014年01月05日 // 描述 : 序統計濾波 //==================================================================== #include <cv.h>#include <highgui.h>#define max(a,b)(((a) > (b)) ? (a) : (b))#define min(a,b)(((a) < (b)) ? (a) : (b))CvRect kcvRectIntersection(CvRect rect1,CvRect rect2){CvRect rect;rect.x=max(rect1.x, rect2.x);rect.y=max(rect1.y, rect2.y);rect.width=min(rect1.x+rect1.width, rect2.x+rect2.width);rect.width=rect.width-rect.x;rect.height=min(rect1.y+rect1.height, rect2.y+rect2.height);rect.height=rect.height-rect.y;return rect;}CvRect kcvRectFromCenterAndSize(int cx,int cy,int w,int h=0){CvRect rect;h=(h==0?w:h);rect.x=cx-(w>>1);rect.y=cy-(h>>1);rect.width=w;rect.height=h;return rect;}// 冒泡排序void sort(uchar a[],int n){uchar t=0;for(int i=0;i<n-1;++i){for(int j=0;j<n-1-i;++j){if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}}}}// 將p限定在[min(a,b),max(a,b)]double clip(double p,double a,double b){return min(max(p,min(a,b)),max(a,b));}int index(double p,int n){return int(p*(n-1));}uchar percentileValue(IplImage* img,CvRect rect,double p){int n=rect.width*rect.height;uchar* data=new uchar[n];for(int j=0;j<rect.width;++j){for(int i=0;i<rect.height;++i){data[j+i*rect.width]=CV_IMAGE_ELEM(img,uchar,rect.y+i,rect.x+j);}}sort(data,n);clip(p,0,1);return data[index(p,n)];}// p取值範圍為[0,1]。0表示最小值濾波,1表示最大值濾波,0.5表示中值濾波void percentileFilter(IplImage* src,IplImage* dst,double p,int kwidth,int kheight=0){CvRect rect1=cvRect(0,0,src->width,src->height);for(int j=0;j<src->width;++j){for(int i=0;i<src->height;++i){CvRect rect2=kcvRectFromCenterAndSize(j,i,kwidth,kheight);CvRect rect=kcvRectIntersection(rect1,rect2);CV_IMAGE_ELEM(dst,uchar,i,j)=percentileValue(src,rect,p);}}}int main(){IplImage* src=cvLoadImage("lena.jpg",0); IplImage* dst=cvCreateImage(cvGetSize(src),8,1); cvNamedWindow("original image"); cvShowImage("original image",src); percentileFilter(src,dst,1,5,5); cvNamedWindow("maximum filter"); cvShowImage("maximum filter",dst); cvSaveImage("maximum filter.jpg",dst);percentileFilter(src,dst,0,5,5); cvNamedWindow("minimum filter"); cvShowImage("minimum filter",dst); cvSaveImage("minimum filter.jpg",dst);percentileFilter(src,dst,0.5,5,5); cvNamedWindow("median filter"); cvShowImage("median filter",dst);cvSaveImage("median filter.jpg",dst);cvWaitKey(0);cvDestroyAllWindows();cvReleaseImage(&src);cvReleaseImage(&dst);return 0;}
最大值濾波的結果:
最小值濾波的結果:
中值濾波的結果: