首页 文章

在Matlab中使用3x3掩码的中值滤波器二进制图像

提问于
浏览
0

我试图在具有给定3x3掩码的2D二进制图像上使用medfilt2 function .

不幸的是,medfilt2没有将掩码作为参数 .

怎么可能median filter一个3x3掩码的图像?

例如 :

binary_image = [0 0 0 0 0 0 0 0;
                0 1 0 1 0 1 1 0;
                0 1 1 1 1 1 1 0;
                0 1 0 1 1 1 0 0;
                0 0 0 1 1 0 1 0;
                0 1 1 1 0 1 1 0;
                0 1 0 1 1 1 1 0;
                0 0 0 0 0 0 0 0];

mask = [1 0 1;
        0 1 1 ;
        1 1 1];

2 回答

  • 2

    简短的回答是您可以使用nlfilter,您可以在其中指定图像中像素邻域的操作 . 具体来说,你会像这样调用 nlfilter

    B = nlfilter(A, [m n], fun);
    

    A 将是一个图像, [m n] 将指定您正在考虑的像素邻域的大小( m x n ), fun 是应用于每个邻域的函数 . 输入是 m x n 补丁,输出应该是单个值 . 假设 masklogical ,并且您的图像存储在 im 中,您所要做的就是:

    out = nlfilter(im, size(mask), @(x) median(x(mask)));
    

    x(mask) 访问在邻域内有效的那些位置,然后您将 median 应用于这些值以检索有效位置上每个邻域的中值 .

    但是, nlfilter 已知很慢 . 我建议你看看我的帖子:Matlab Median Filter Code .

    这可以非常快速地从第一原理计算 median 过滤器 . 我会留给你阅读帖子,了解我做了什么 . 但是,为了您的目的而修改它的方法是删除 im2col 输出中与掩码中的无效值相对应的那些行 . 因此,做这样的事情:

    N = size(mask,1); %// Size of mask - Assume that # of rows = # of columns
    im_pad = padarray(im, [floor(N/2) floor(N/2)]);
    im_col = im2col(im_pad, [N N], 'sliding');
    
    %// Get locations in mask that don't count towards getting median
    invalid_rows = ~(mask(:));
    
    %// Remove from column neighbourhood matrix
    im_col(invalid_rows,:) = [];
    
    %// Determine new median index
    val = floor((N*N - sum(invalid_rows))/2) + 1;
    
    %// apply algorithm as normal
    sorted_cols = sort(im_col, 1, 'ascend');
    med_vector = sorted_cols(val, :);
    out = col2im(med_vector, [N N], size(im_pad), 'sliding');
    

    invalid_rows 将掩码展开为单个列,就像 im2col 为每个像素邻域所做的那样,然后我们反转掩码以确定那些不应计入最终中位数的位置 . 此外, val 确定从我们开始删除未分析的邻域中的像素时我们需要获得中值的 new 索引 .


    如果输入是二进制图像,那么eigenchris对你的回答应该非常快,并且比我写的要快得多 . 但是,如果将其应用于灰度图像,那么我所写的内容将起作用 . 这适用于二进制和灰度图像 .

  • 1

    如果您只处理二进制图像,则可以通过使用 conv2() 函数执行卷积来解决此问题 .

    逻辑是,由于掩码中有7个有效像素,如果卷积结果中的像素值大于或等于4,我们知道中位数是 1 . 否则中位数必须为 0 .

    通常,如果掩码中有有效像素,我们可以通过舍入卷积矩阵的结果除以 n 来获得掩码中值 .

    n = sum(sum(mask));                 % number of valid pixels in the mask
    maskFlipped = fliplr(flipud(mask)); % flip mask so it faces the right way
    convResult = conv2(binary_image,maskFlipped,'same');
    maskedMedianFilterResult = round(convResult/n);
    

相关问题