NB:这假设已安装图像处理工具箱。
中值滤波背后的基本前提是分析图像中的像素邻域,对它们的强度进行排序,然后选择中间强度作为结果。我可以提出的一个建议是使用im2col http://www.mathworks.com/help/images/ref/im2col.html将每个像素邻域转换为单个像素邻域column向量并采用所有这些列向量来创建单个矩阵。每列代表像素邻域内的像素强度。接下来,使用sort http://www.mathworks.com/help/images/ref/sort.html并沿着每列的行进行排序,然后抓取middle该排序矩阵的值表示每个像素邻域的中间值。这将是一个单行向量,表示每个像素邻域的中值。完成后,只需将该向量重新整形回与原始图像相同的大小即可获得中值滤波结果。您可以使用col2im http://www.mathworks.com/help/images/ref/col2im.html帮助促进最后一步。
然而,随着im2col
,它只抓取原始图像范围内的像素邻域。因为您想要沿图像边界对像素进行中值过滤,所以您需要pad处理前的图像边框im2col
. Use padarray http://www.mathworks.com/help/images/ref/padarray.html为你做这件事。我假设边框用零填充以使事情变得更简单。
因此,给定一个灰度 image im
,以及一个对称邻域来分析N x N
, where N
是您所在社区的宽度/高度,您的代码可能如下所示。我还将假设N
允许更容易地选择中位数是很奇怪的:
im_pad = padarray(im, [floor(N/2) floor(N/2)]);
im_col = im2col(im_pad, [N N], 'sliding');
sorted_cols = sort(im_col, 1, 'ascend');
med_vector = sorted_cols(floor(N*N/2) + 1, :);
out = col2im(med_vector, [N N], size(im_pad), 'sliding');
我们来举个例子。假设我们的过滤器尺寸是5 x 5
,我们将使用cameraman.tif
这是图像处理工具箱的一部分。如果我们执行下面的代码,然后运行上面看到的中值滤波器代码:
N = 5;
im = imread('cameraman.tif');
我们得到以下内容,包括原始图像和经过中值滤波的最终图像。
这是我们所期望的,因为中值滤波期望在进行图像平滑时(或多或少)保持边缘良好。中值滤波对于椒盐噪声特别有用,在对像素邻域进行排序时,这些噪声像素很可能出现在开头和结尾,因此选择中间值很可能会过滤掉这些噪声值。
Bonus
您的帖子还要求从进行高斯过滤的第一原理中查找代码。我前几天替别人回答过这个问题。
在这里查看这篇文章:如何在 MATLAB 中创建和应用高斯滤波器而不使用 fspecial、imfilter 或 conv2? https://stackoverflow.com/questions/27499057/how-to-create-and-apply-a-gaussian-filter-in-matlab-without-using-fspecial-or-im