使用汉明/汉宁滤镜平滑二元蒙版

时间:2018-07-23 17:24:24

标签: matlab image-processing signal-processing

我已经使用了MATLAB的内置“ imfreehand”来定义二进制掩码。边界内的每个像素均设置为1,否则设置为零:

h = imfreehand(handles.fig);
wait(h);
mask = h.creatMask();

然后,我想将蒙版扩大4个像素,最后添加一段使边缘更平滑的代码,即蒙版的边缘从1平滑变为0;像汉明窗或汉宁窗。我该怎么办?

1 个答案:

答案 0 :(得分:6)

因此,如果我正确理解了您的问题,则您有一个二进制遮罩,从h.createMask();输出,并且您想扩展边界,然后实质上是“遮盖”遮罩边界。

我完成此操作的一种方法是,或多或少像您建议的那样,使用imdilate()通过具有一定半径(例如4)的磁盘来扩展蒙版。尽管我不确定它会产生4像素的膨胀。然后,我将使用一个小的内核执行一个conv2()。您可以从Hann窗口构建它。在代码中:

首先,让我们制作您要问的面具:

% test image
I = imread('cameraman.tif');  % Read a sample grayscale image

% From the OP's Question (suggested edit anyway)
fig = figure;
hAx = axes(fig);
hImg = imshow(I, 'Parent', hAx);
h = imfreehand(hAx);
wait(h);
mask = h.createMask();

然后,通过使用imdilate()创建更大的磁盘,我们可以使用strel()扩展遮罩

%dilate radius of mask by 4
maskExpanded = imdilate(mask, strel('disk', 4));

最后,我们可以从hann()窗口中创建2D内核,并对卷积的蒙版进行卷积。 hann()窗口中使用的点数控制着羽化的数量。也就是说,您可以使用20而不是10来增加羽化。

%hann kernal
hannWindow = hann(10); %10px
% Convert window into 2 dimensions by outer product.
hannKernel = hannWindow * hannWindow';
% Make the kernel sum to 1
hannKernel = hannKernel ./ sum(hannKernel(:));

% Now Apply Smoothing to the enlarged mask
maskSmoothed = conv2(maskExpanded,hannKernel,'same');

为完整起见,您可以使用以下内容查看效果:

%View
f2 = figure; 
f2.Position(3) = 2*f2.Position(3); %twice as wide
f2.Position(1) = f2.Position(1) - f2.Position(3)/2;
f2.Position(4) = 2.1*f2.Position(4); %twice as wide
f2.Position(2) = f2.Position(2) - f2.Position(4)/2;

%axes
ax1 = subplot(2,2,1);
ax2 = subplot(2,2,2);
ax3 = subplot(2,2,3);
ax4 = subplot(2,2,4);
%plots
surf(hannKernel, 'parent', ax1);
imshow(maskExpanded,'parent', ax2);
imshow(maskSmoothed,'parent', ax3);
imshow(maskSmoothed-mask,'parent', ax4);
%titles
title(ax1,'Hann kernel 3d representation');
title(ax2,'Expanded Mask');
title(ax3,'Expanded Mask with convolution');
title(ax4,{'Effect of expansion & convolution';'(difference from original)'});

对我来说,这产生了以下数字: Figure outputs.

我想有很多方法可以做到这一点,但是我希望我的解决方案能帮上忙。