/*
实现思路很简单,就是以每一个像素点为中心框一个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\n", 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;
}