/* 实现思路很简单,就是以每一个像素点为中心框一个N*N的矩形,将矩形内的所有像素值排序,得到中位数,再重新把这个点的像素值设为中位数。 */ #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <algorithm> #include <vector> using namespace std; const int N = 3; int pixl2int(IplImage *img, int x, int y) { return ((uchar *)(img->imageData + x*img->widthStep))[y]; } void setPixl(IplImage *img, int x, int y, int val) { ((uchar *)(img->imageData + x*img->widthStep))[y] = val; } int median_compute(IplImage* img, int x, int y) { int t = (N - 1)/2; vector<int> tmp; for(int i = 0; i < N; ++i) { for(int j = 0; j < N; ++j) { int val = pixl2int(img, x - t + i, y - t + j); tmp.push_back(val); } } sort(tmp.begin(), tmp.end()); return tmp[(N*N + 1)/2]; } void medianfliter(IplImage* src, IplImage* dst) { int t = (N - 1)/2; for(int i = 0; i < src->width - t; ++i) { for(int j = 0; j < src->height - t; ++j) { int val = median_compute(src, i, j); setPixl(dst, i, j, val); //printf("%d %d %d ", i, j, val); } } } int main() { IplImage *src, *src1, *read, *dst; cvNamedWindow("MedianFliter"); read = cvLoadImage("test.jpg"); if(!read) { cout << "open image error" <<endl; return 0; } CvSize newsz, sz = cvGetSize(read); newsz.height = sz.height/2; newsz.width = sz.width/2; src = cvCreateImage(sz, IPL_DEPTH_8U, 1); src1 = cvCreateImage(newsz, IPL_DEPTH_8U, 1); dst = cvCreateImage(newsz, IPL_DEPTH_8U, 1); cvCvtColor(read, src, CV_BGR2GRAY); cvResize(src, src1, CV_INTER_LINEAR); cvCopy(src1, dst); medianfliter(src1, dst); cvShowImage("MedianFliter", dst); cvWaitKey(0); cvDestroyWindow("MedianFliter"); cvReleaseImage(&src); cvReleaseImage(&dst); return 0; }