美文网首页
简单中值滤波器的实现

简单中值滤波器的实现

作者: 一点东风 | 来源:发表于2021-03-30 22:50 被阅读0次

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


无标题.png

代码:

#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>

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<Vec3b>(i,j)[0] = image.at<Vec3b>(i,j)[0];
                dstImg.at<Vec3b>(i,j)[1] = image.at<Vec3b>(i,j)[1];
                dstImg.at<Vec3b>(i,j)[2] = image.at<Vec3b>(i,j)[2];
            } else {
                // 3x3邻域中值滤波
                int pb[9];
                pb[0] = image.at<Vec3b>(i,j)[0];
                pb[1] = image.at<Vec3b>(i,j + 1)[0];
                pb[2] = image.at<Vec3b>(i - 1,j + 1)[0];
                pb[3] = image.at<Vec3b>(i - 1,j)[0];
                pb[4] = image.at<Vec3b>(i - 1,j - 1)[0];
                pb[5] = image.at<Vec3b>(i,j - 1)[0];
                pb[6] = image.at<Vec3b>(i + 1,j - 1)[0];
                pb[7] = image.at<Vec3b>(i + 1,j)[0];
                pb[8] = image.at<Vec3b>(i + 1,j + 1)[0];

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

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

                dstImg.at<Vec3b>(i,j)[0] = insertSortAndReturnMedian(pb, 9);
                dstImg.at<Vec3b>(i,j)[1] = insertSortAndReturnMedian(pg, 9);
                dstImg.at<Vec3b>(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

相关文章

  • 简单中值滤波器的实现

      有许多实现中值滤波的方法,本文用的是非常暴力的方法:这里以一个彩色图像为例,遍历所有非边界上的像素,每找到一个...

  • 第 6 章 图像滤波

    本章包括以下内容: 用低通滤波器进行图像滤波; 用滤波器进行缩减像素采样; 用中值滤波器进行图像滤波; 用定向滤波...

  • 【原创】C++实现IIR数字滤波器(二)

    在上一篇文章中,我们讲到了C++实现IIR数字滤波器的理论模型及计算公式,以及实现了一个简单的带通滤波器提取交流信...

  • 2018-06-03滤波器设计(1)

    常用的滤波器1、ma和ema 优点:简单易懂,好实现 缺点:延迟性和平滑性矛盾 Python实现:导入talib,...

  • 直接生成频域滤波

    接上文:傅立叶变换滤波 频域滤波器 理想低通滤波器 巴特沃兹低通滤波器 高斯低通滤波器 dftuv的实现 dftu...

  • 计算摄影学Lab2:图像滤波和傅里叶变换

    任务清单 实现盒装均值滤波 实现高斯滤波 实现中值滤波 实现简单的双边滤波 利用傅里叶变换完成图像的频域变换 空域...

  • 非线性滤波:中值滤波 双边滤波

    【OpenCV入门教程之九】 非线性滤波专场:中值滤波、双边滤波 一、非线性滤波概述 线性滤波器:两个信号之和的响...

  • 微信小程序 | 切换按钮或者view的选中状态

    实现非常简单,通过一个简单的判断当前data中的选中值,点击按钮时更新data值,重新渲染页面。 index.wx...

  • IIR滤波器的FPGA实现

    IIR滤波器的FPGA实现 生产实习著此篇实现的是直接1型7阶切比雪夫1型低通滤波器 [TOC] IIR原理 II...

  • opencv各种卷积核滤波器

    高斯滤波 使图像平滑,可以用来去除噪声。高斯滤波器将中心像素周围的像素按照高斯分布加权平均进行平滑化。 中值滤波 ...

网友评论

      本文标题:简单中值滤波器的实现

      本文链接:https://www.haomeiwen.com/subject/oqknhltx.html