【问题标题】:How to implement median filter with a kernel in MATLAB to smooth an image?如何在 MATLAB 中使用内核实现中值滤波器以平滑图像?
【发布时间】:2018-05-24 15:33:01
【问题描述】:

我不知道如何在 MATLAB 中实现带有滑动窗口(内核)的中值滤波器。我需要知道实现的样子,以便我可以尝试实现 BSE 算法(块智能擦除),它与中值滤波器非常相似。我需要它来擦除一些黑白像素。我知道有 medfilt2() 函数,但我需要知道它是如何实现的。

BSE 算法的工作原理如下:

BSE 算法基于中值技术,用周围像素的中值代替极值(黑色或白色)像素。

1) 对于以测试像素为中心的 NxN 窗口,通常为 N,建议使用更大的值。

2) 如果f(i,j) = 0或f(i,j) = 255,则f(i,j)是必须估计的绝对极值像素;转到步骤 3。否则, f(i,j) 的值不会改变;转到第 4 步。

3) 当检测到极值像素时,将其灰度值替换为窗口的中值。

4) 对下一个窗口重复该过程。

我的理解是,我需要使用条件来实现中值滤波器,以检查当前像素值是 0 还是 255。如果是,我将其更改为邻域像素的中值。

我不知道我是否足够清楚,但我需要一些帮助:)。

当前的 BSE 算法:

function [outimg] = medianfilt(img,sz)
green  = img(:,:,2);
[rows,cols] = size(green);    % get size of grayscale image
pad = sz-1; % padding to be added
nimg = zeros(rows+pad,cols+pad); % padded image
nimg(pad/2+1:rows+pad/2, pad/2+1:cols+pad/2) = green;
outimg = zeros(rows,cols);  % output / median filtered image
for x = pad/2 + 1 : cols + pad/2  % loop over columns
    for y = pad/2 + 1 : rows + pad/2   % loop over rows
        if nimg(y,x) == 0 || nimg(y,x) == 255
            win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
            outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
        else
            outimg(y-pad/2,x-pad/2) = nimg(y,x);
        end
        win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
        outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
    end
end
imshow(outimg);
end

【问题讨论】:

    标签: matlab image-processing median noise-reduction


    【解决方案1】:

    你可以如下实现中值过滤:

    function [outimg] = medianfilt(img,sz)
        [rows,cols] = size(img);    % get size of grayscale image
        pad = sz-1; % padding to be added
        nimg = zeros(rows+pad,cols+pad); % padded image
        nimg(pad/2+1:rows+pad/2, pad/2+1:cols+pad/2) = img;
        outimg = zeros(rows,cols);  % output / median filtered image
        for x = pad/2 + 1 : cols + pad/2  % loop over columns
            for y = pad/2 + 1 : rows + pad/2   % loop over rows 
                win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
                outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
            end
        end
    end
    

    您可以如下检查 BSE:

    if nimg(y,x) == 0 || nimg(y,x) == 255
        win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
        outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
    else
        outimg(y-pad/2,x-pad/2) = nimg(y,x);
    end
    

    【讨论】:

    • 如果将循环切换到yx,您将获得显着的速度提升。 MATLAB 按列存储数组,并且按存储顺序迭代数组总是最快的(与数据局部性和缓存未命中有关)。
    • 谢谢,@user8190419!如果我想从 BSE 算法中做那个条件,我需要做的就是在获得 mxm 窗口之后的一个 if 条件?或者会怎么样?
    • “sz”代表什么?
    • 它是窗口的大小,即 3x3 或 5x5 或 7x7 .... 您应该将其称为 medianfilt( imread(path), 3)
    • 显示错误:“下标分配维度不匹配。”显示错误在该行: nimg(pad/2+1:rows+pad/2, pad/2+1:cols+pad/2) = img;
    【解决方案2】:

    如您所述,MATLAB 有medfilt2。你可以使用这个函数来构建你的过滤器:

    img = imread(...);
    med = medfilt2(img);
    mask = img==0 | img==255;
    img(mask) = med(mask);
    

    上面的代码所做的是

    1. 计算中值滤波图像med
    2. 识别需要替换的像素(值为0或255的像素),生成可用于索引的逻辑数组mask,最后
    3. 用中值滤波图像中的对应像素替换输入图像中的给定像素。

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 2015-07-12
      • 2021-05-19
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多