图形图像——中值滤波去除椒盐噪声

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

 

posted @ 2013-06-26 16:30  AC_Von  阅读(4562)  评论(0编辑  收藏  举报