我试图在具有给定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 回答
简短的回答是您可以使用nlfilter,您可以在其中指定图像中像素邻域的操作 . 具体来说,你会像这样调用
nlfilter
:A
将是一个图像,[m n]
将指定您正在考虑的像素邻域的大小(m x n
),fun
是应用于每个邻域的函数 . 输入是m x n
补丁,输出应该是单个值 . 假设mask
是logical
,并且您的图像存储在im
中,您所要做的就是:x(mask)
访问在邻域内有效的那些位置,然后您将median
应用于这些值以检索有效位置上每个邻域的中值 .但是,
nlfilter
已知很慢 . 我建议你看看我的帖子:Matlab Median Filter Code .这可以非常快速地从第一原理计算
median
过滤器 . 我会留给你阅读帖子,了解我做了什么 . 但是,为了您的目的而修改它的方法是删除im2col
输出中与掩码中的无效值相对应的那些行 . 因此,做这样的事情:invalid_rows
将掩码展开为单个列,就像im2col
为每个像素邻域所做的那样,然后我们反转掩码以确定那些不应计入最终中位数的位置 . 此外,val
确定从我们开始删除未分析的邻域中的像素时我们需要获得中值的 new 索引 .如果输入是二进制图像,那么eigenchris对你的回答应该非常快,并且比我写的要快得多 . 但是,如果将其应用于灰度图像,那么我所写的内容将起作用 . 这适用于二进制和灰度图像 .
如果您只处理二进制图像,则可以通过使用
conv2()
函数执行卷积来解决此问题 .逻辑是,由于掩码中有7个有效像素,如果卷积结果中的像素值大于或等于4,我们知道中位数是
1
. 否则中位数必须为0
.通常,如果掩码中有有效像素,我们可以通过舍入卷积矩阵的结果除以
n
来获得掩码中值 .