写了一段小程序,分享给大家!
//==================================================================== // 作者 : quarryman // 邮箱 : quarrying{at}qq.com // 主页 : http://blog.csdn.net/quarryman // 日期 : 2013年08月03日 // 描述 : 实现最值滤波,非最值抑制 //==================================================================== #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 kcvGetRectFromCenterAndSize(int cx, int cy, int w, int h=0) { CvRect rect; rect.x=cx-(w>>1); rect.y=cy-(h>>1); rect.width=w; rect.height=(h==0?w:h); return rect; } int minValue(IplImage* img,CvRect rect) { uchar minval=255; for(int i=rect.y;i<rect.y+rect.height;++i) { for(int j=rect.x;j<rect.x+rect.width;++j) { if(CV_IMAGE_ELEM(img,uchar,i,j)<minval) { minval=CV_IMAGE_ELEM(img,uchar,i,j); } } } return minval; } int maxValue(IplImage* img,CvRect rect) { uchar maxval=0; for(int i=rect.y;i<rect.y+rect.height;++i) { for(int j=rect.x;j<rect.x+rect.width;++j) { if(CV_IMAGE_ELEM(img,uchar,i,j)>maxval) { maxval=CV_IMAGE_ELEM(img,uchar,i,j); } } } return maxval; } enum { KCV_MAX, // 最大值滤波器,类似于形态学膨胀 KCV_MIN, // 最小值滤波器,类似于形态学腐蚀 KCV_NMS_MAX, // 非最大值抑制 KCV_NMS_MIN // 非最小值抑制 }; void maxminFilter(IplImage* src,IplImage* dst,int width,int height=0,int mode=KCV_MAX) { for(int j=0;j<src->width;++j) { for(int i=0;i<src->height;++i) { CvRect rect1=cvRect(0,0,src->width,src->height); CvRect rect2=kcvGetRectFromCenterAndSize(j,i,width,height); CvRect rect=kcvRectIntersection(rect1,rect2); switch(mode) { case KCV_MAX: CV_IMAGE_ELEM(dst,uchar,i,j)=maxValue(src,rect); break; case KCV_MIN: CV_IMAGE_ELEM(dst,uchar,i,j)=minValue(src,rect); break; case KCV_NMS_MAX: if(CV_IMAGE_ELEM(src,uchar,i,j)!=maxValue(src,rect)) { CV_IMAGE_ELEM(dst,uchar,i,j)=0; } else { CV_IMAGE_ELEM(dst,uchar,i,j)=CV_IMAGE_ELEM(src,uchar,i,j); } break; case KCV_NMS_MIN: if(CV_IMAGE_ELEM(src,uchar,i,j)!=minValue(src,rect)) { CV_IMAGE_ELEM(dst,uchar,i,j)=255; } else { CV_IMAGE_ELEM(dst,uchar,i,j)=CV_IMAGE_ELEM(src,uchar,i,j); } break; } } } } int main() { IplImage* src=cvLoadImage("lena.jpg",0); IplImage* dst=cvCreateImage(cvGetSize(src),8,1); cvNamedWindow("original image"); cvShowImage("original image",src); maxminFilter(src,dst,5,5,KCV_MAX); cvNamedWindow("maximum filter"); cvShowImage("maximum filter",dst); cvSaveImage("maximum filter.jpg",dst); maxminFilter(src,dst,5,5,KCV_MIN); cvNamedWindow("minimum filter"); cvShowImage("minimum filter",dst); cvSaveImage("minimum filter.jpg",dst); maxminFilter(src,dst,5,5,KCV_NMS_MAX); cvNamedWindow("non-maximum suppression"); cvShowImage("non-maximum suppression",dst); cvSaveImage("non-maximum suppression.jpg",dst); maxminFilter(src,dst,5,5,KCV_NMS_MIN); cvNamedWindow("non-minimum suppression"); cvShowImage("non-minimum suppression",dst); cvSaveImage("non-minimum suppression.jpg",dst); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&dst); return 0; }
最大值滤波结果:
最小值滤波结果:
非最大值抑制结果:
非最小值抑制结果: