中值滤波


#include <stdio.h>
#include <float.h>
#include <cstdlib>
#include <string>

#include <opencv2/highgui.hpp>
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <fstream>

//using 5x5 window 
#define FILTER_WINDOW_Y 5
#define FILTER_WINDOW_X 5
#define FILTER_WINDOW_SIZE 25
#define FILTER_WINDOW_MEDIAN_SIZE (25/2)
#define PIXEL_RANGE_MAX 256

void median_filter( cv::Mat &src, size_t row, unsigned char *pdst)
{
    unsigned char *pcurdst = pdst+FILTER_WINDOW_X/2;
    unsigned char histogram[PIXEL_RANGE_MAX];
    memset(histogram, 0, sizeof(histogram));

    for(int i = row-FILTER_WINDOW_Y/2; i <= row+FILTER_WINDOW_Y/2; i++)
    {
        unsigned char *pRow = src.ptr<unsigned char>(i);
        for(int j = 0; j < FILTER_WINDOW_X; j++)
        {
            histogram[*(pRow+j)] +=1;
        }
    }
    int index = 0;
    int count = 0;
    for(index = 0, count = 0; index < PIXEL_RANGE_MAX;)
    {
        count+= histogram[index]; 
        ++index;
        if(count > FILTER_WINDOW_MEDIAN_SIZE)
        {
            break;
        }
    }
    *pcurdst = index;
    ++pcurdst; 
    //printf("\n %s:%d, index %d, count %d\n", __FILE__, __LINE__, index, count);

    for(int col = 1; col < src.cols-FILTER_WINDOW_Y+1; col++, pcurdst++)
    {
        for(int i = row-FILTER_WINDOW_Y/2; i <= row+FILTER_WINDOW_Y/2; i++)
        {
            unsigned char *pRow = src.ptr<unsigned char>(i);
            histogram[*(pRow+col-1)] -=1;
            histogram[*(pRow+col+4)] +=1;
            if(*(pRow+col-1) < index)
                --count;
            if(*(pRow+col+4) < index)
                ++count;
        }
        int tmp = 0;
        for(int i = 0; i < PIXEL_RANGE_MAX;++i)
        {
           tmp += histogram[i]; 
        } 
        //printf("\n index %d, count %d, %d\n", index, count, tmp);

        while(1)
        {
            if(count < FILTER_WINDOW_MEDIAN_SIZE)
            {
                count += histogram[index];
                if(index < (PIXEL_RANGE_MAX-1))
                    ++index;
                else
                    break;
                if(count > FILTER_WINDOW_MEDIAN_SIZE)
                    break;
            }
            if(count > FILTER_WINDOW_MEDIAN_SIZE)
            {
                count -= histogram[index-1];
                if(index > 0)
                    --index;
                else
                    break;
                if(count < FILTER_WINDOW_MEDIAN_SIZE)
                    break;
            }
            if(count == FILTER_WINDOW_MEDIAN_SIZE)
                break;
        }

        *pcurdst = index;  
    }

    return;
}

int main(int argc, char* argv[])
{
    int w = 0, h = 0;
    std::string fileName = argv[1];
    int iter = 1;
    if(argc > 2)
        iter = atoi(argv[2]);

    cv::Mat src = cv::imread(fileName, CV_LOAD_IMAGE_GRAYSCALE);
    cv::Mat dst ;
    dst = src.clone();

    printf("%d,%d,%d\n", src.rows, src.cols, src.channels());
    imwrite("src.bmp", src);
    
    for(int i = FILTER_WINDOW_Y/2; i < src.rows-FILTER_WINDOW_Y/2; i++)
    {
        unsigned char *pdst = dst.ptr<unsigned char>(i);
        median_filter( src, i, pdst);
    }

    imwrite("dst.bmp", dst);

   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值