Matlab 中具有 3x3 掩码的中值滤波器二值图像

Median filter binary image with 3x3 mask in Matlab

我正在尝试在具有给定 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];

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

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

一般来说,如果您的蒙版中有 n 个有效像素,我们可以通过将卷积矩阵除以 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);

简短的回答是您可以使用 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 速度很慢。我建议您在此处查看我的 post:Matlab Median Filter Code .

这根据第一原理非常快速地计算 median 过滤器。我将留给您通读 post 并理解我所做的事情。但是,为了您的目的,您需要做的是在 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给你的回答应该很快,比我写的快多了。但是,如果将其应用于灰度图像,那么我所写的内容将起作用。这适用于二进制和灰度图像。