使用汉明/汉宁滤波器平滑二进制掩模

Sar*_*raG 0 matlab signal-processing image-processing

我使用MATLAB的内置"imfreehand"来定义二进制掩码.边界内的每个像素都设置为1,否则设置为零:

h = imfreehand(handles.fig);
wait(h);
mask = h.creatMask();
Run Code Online (Sandbox Code Playgroud)

然后,我想用4个像素扩大掩模,最后添加一段使边缘更平滑的代码,即掩模的边缘平滑地从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();
Run Code Online (Sandbox Code Playgroud)

然后,我们可以imdilate()通过创建一个更大的磁盘来扩展掩码strel()

%dilate radius of mask by 4
maskExpanded = imdilate(mask, strel('disk', 4));
Run Code Online (Sandbox Code Playgroud)

最后,我们可以从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');
Run Code Online (Sandbox Code Playgroud)

为了完整起见,您可以使用以下方法查看效果:

%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)'});
Run Code Online (Sandbox Code Playgroud)

对我来说,这会产生以下数字: 图输出.

我猜有很多方法可以做到这一点,但我希望我的解决方案有所帮助.