所有栏目

中值滤波原理

已输入 0 字
优质回答
  • 中值滤波在图像处理中,在进行图像处理操作之前往往要对图像进行滤波操作。中值滤波为一种非线性的数字滤波器,它的原理基于用像素点邻域点集像素值的中值代替像素点的值,从而消除孤立的噪声点。中值滤波是非线性的、对斑点噪声和椒盐噪声的滤波处理效果比较好,只要选取合适的阈值阀,中值滤波能在保留较好的边缘下降噪。

    斑点噪声

    斑点噪声是SAR成像系统的一大特色,源自基本分辨单元内地物的随机散射,在图像上表现为信号相关(如在空间上相关)的小斑点,它既降低了图像的画面质量,又严重影响图像的自动分割、分类、目标检测以及其它定量专题信息的提取 。

    椒盐噪声

    椒盐噪声也称为脉冲噪声,是图像中经常见到的一种噪声,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。椒盐噪声的成因可能是影像讯号受到突如其来的强烈干扰而产生、模数转换器或位元传输错误等。例如失效的感应器导致像素值为最小值,饱和的感应器导致像素值为最大值。

    中值滤波算法步骤以及代码实现

    基于中值滤波的设计思想,算法步骤非常简单

    (1) 用一个滑动窗口去遍历图像,这个滑动窗口的范围就是像素点的邻域。

    (2) 获取滑动窗口的像素值集合,并且排序,得到中值替换原像素点。

    (3) 遍历图像重复步骤(2)至结束。

    // This main.cpp

    // median filtering sample

    // author:mango

    // copyright: https://mangoroom.cn

    #include<iostream>

    #include<vector>

    #include<opencv2/opencv.hpp>

    // median filtering

    void MedianFilter(const cv::Mat& input_image, cv::Mat& output_image, const int& kernel_size)

    {

    // 输入参数检查

    if (input_image.empty())

    {

    throw "Input image is empty!!!";

    }

    else if(input_image.channels() != 1)

    {

    throw "Input image not be gray!!!";

    }

    // 遍历图像

    output_image = input_image.clone();

    int rows = input_image.rows;

    int cols = input_image.cols;

    std::vector<int> filter_windows(kernel_size*kernel_size, 0);

    for (auto i= kernel_size / 2;i < rows - (kernel_size /2); i++)

    {

    for (auto j = kernel_size / 2; j < cols - (kernel_size / 2); j++)

    {

    // 滤波窗口元素排序

    int index = 0;

    for (auto m = 0; m < kernel_size; m++)

    {

    for (auto n = 0; n < kernel_size; n++)

    {

    filter_windows.at(index) = input_image.at<uchar>(i - kernel_size / 2 + m, j - kernel_size / 2 + n);

    index++;

    }

    }

    std::sort(filter_windows.begin(), filter_windows.end());

    // 更新图像像素

    output_image.at<uchar>(i, j) = filter_windows.at(kernel_size * kernel_size / 2);

    }

    }

    }

    int main()

    {

    cv::Mat img = cv::imread("Noise_salt_and_pepper.png", 0);

    cv::Mat dst;

    MedianFilter(img, dst, 3);

    cv::imshow("img", img);

    cv::imshow("dst", dst);

    cv::waitKey(0);

    return 0;

    }

    但是以上直白思路的算法效率是非常低的,每个滑动窗口中的像素点每一次都需要重新排序,假如窗口选取比较大和图像比较大,显然这开销是巨大的。我们发现窗口每一次移动的时候,窗口内容丢掉的只是最左侧的一列而新增的是最右侧的一例,对于窗口的其他像素点并没有发生变化,不需要重新排序。此优化的算法步骤如下:

    (1)置$t = frac{mn}{2}$

    如果m和n都为奇数,则对t取整,这样我们总是可以避免不必要的浮点数运算。

    (2)将窗口移至一个新行的开始,对其内容排序。建立窗口像素的直方图H,确定其中值m,记下亮度小于或者等于m的像素数目$n_m$。

    (3)对于最左列亮度是$p_g$的每个像素p,做

    $$H[p_g] = H[p_g] - 1$$

    进一步,如果$p_g leq m$, 置$n_m = n_m-1$。

    (4)将窗口右移一列,对于最右列亮度是$p_g$的每个像素$p$,做

    $$H[p_g] = H[p_g] + 1$$

    如果$p_g leq m$, 置$n_m = n_m + 1$。

    (5)如果$n_m = t$,则跳转至步骤8.

    (6)如果$n_m > t$ 则跳转至步骤7。

    重复

    $$m = m + 1$$

    $$n_m = n_m + H[m]$$

    直到$n_m geq t$则跳转至步骤8。

    (7)(此时有$n_m > t$。重复

    $$n_m = n_m - H[m]$$

    $$m = m - 1$$

    直到$n_m leq t$。

    (8) 如果有窗口的右侧列不是图像的有边界,

    2023-10-23 22:36:32
  • 中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.

    中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近真实值,从而消除孤立的噪声点。方法是用某种结构的二维滑动模板,将板内像素按照像素值的大小进行排序,生成单调上升(或下降)的为二维数据序列。二维中值滤波输出为g(x,y)=med{f(x-k,y-l),(k,l∈W)} ,其中,f(x,y),g(x,y)分别为原始图像和处理后图像。W为二维模板,通常为3*3,5*5区域,也可以是不同的形状,如线状,圆形,十字形,圆环形等。

    2023-10-23 22:36:32
最新问题 全部问题