简单中值滤波器的实现

  有许多实现中值滤波的方法,本文用的是非常暴力的方法:这里以一个彩色图像为例,遍历所有非边界上的像素,每找到一个像素(r,g,b三个元素的数组),就将它(0)及周围 3x3 邻域的所有像素(1-8)的r,g,b(9个r,9个g,9个b)三种值分别做插入排序取中值(你也可以用直方图估算中值的方法做)返回给输出图像。因此此方法仅供了解中值滤波基本原理,生产环境请直接使用OpenCV自带的函数medianBlur。如图:


无标题.png

代码:

#include 
#include 
#include 

using namespace std;
using namespace cv;

int insertSortAndReturnMedian(int arr[], int n){
    for(int i = 1; i < n; i++) {
        int e = arr[i];
        int j;
        for(j = i; j >= 1 && e < arr[j-1]; j--){
            arr[j] = arr[j - 1];
        }
        arr[j] = e;
    }
    if (n % 2 == 1) {
        return arr[n / 2];
    } else {
        return  (arr[n / 2 - 1] + arr[n / 2]) / 2;
    }
}

int main() {
    string imagePath = "../cup.jpg";
    Mat image = imread(imagePath);
    resize(image, image, Size(600, 900));
    Mat dstImg(image.rows, image.cols, CV_8UC3);
    for (int i = 0; i < image.rows; ++i) {
        for (int j = 0; j < image.cols; ++j) {
            // 边界像素3x3的邻域不足9个,就不取中值了
            if(i == 0 || j == 0) {
                dstImg.at(i,j)[0] = image.at(i,j)[0];
                dstImg.at(i,j)[1] = image.at(i,j)[1];
                dstImg.at(i,j)[2] = image.at(i,j)[2];
            } else {
                // 3x3邻域中值滤波
                int pb[9];
                pb[0] = image.at(i,j)[0];
                pb[1] = image.at(i,j + 1)[0];
                pb[2] = image.at(i - 1,j + 1)[0];
                pb[3] = image.at(i - 1,j)[0];
                pb[4] = image.at(i - 1,j - 1)[0];
                pb[5] = image.at(i,j - 1)[0];
                pb[6] = image.at(i + 1,j - 1)[0];
                pb[7] = image.at(i + 1,j)[0];
                pb[8] = image.at(i + 1,j + 1)[0];

                int pg[9];
                pg[0] = image.at(i,j)[1];
                pg[1] = image.at(i,j + 1)[1];
                pg[2] = image.at(i - 1,j + 1)[1];
                pg[3] = image.at(i - 1,j)[1];
                pg[4] = image.at(i - 1,j - 1)[1];
                pg[5] = image.at(i,j - 1)[1];
                pg[6] = image.at(i + 1,j - 1)[1];
                pg[7] = image.at(i + 1,j)[1];
                pg[8] = image.at(i + 1,j + 1)[1];

                int pr[9];
                pr[0] = image.at(i,j)[2];
                pr[1] = image.at(i,j + 1)[2];
                pr[2] = image.at(i - 1,j + 1)[2];
                pr[3] = image.at(i - 1,j)[2];
                pr[4] = image.at(i - 1,j - 1)[2];
                pr[5] = image.at(i,j - 1)[2];
                pr[6] = image.at(i + 1,j - 1)[2];
                pr[7] = image.at(i + 1,j)[2];
                pr[8] = image.at(i + 1,j + 1)[2];

                dstImg.at(i,j)[0] = insertSortAndReturnMedian(pb, 9);
                dstImg.at(i,j)[1] = insertSortAndReturnMedian(pg, 9);
                dstImg.at(i,j)[2] = insertSortAndReturnMedian(pr, 9);
            }
        }
    }

    namedWindow("MedianBlur",WINDOW_AUTOSIZE);
    imshow("MedianBlur",dstImg);
    waitKey(0);
    destroyAllWindows();
    return 0;
}

原图:


srcImg.png

中值滤波后的目标图:


dstImg.png

终于打完了,以上还有更好的优化方式,
取中值方式:https://www.sciencedirect.com/science/article/pii/S0022000073800339

最后我只有一句话想说:


v2-8c554f8942403fe0326c40059596488e_b.jpg

你可能感兴趣的:(简单中值滤波器的实现)