我正在尝试解决以下问题: 我是一个由0和1组成的内核, 例如十字形内核
kernel =
0 1 0
1 1 1
0 1 0
我需要将它应用于给定的矩阵,如
D =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
为了简洁,我们假设从元素D(2,2)开始,它是11,以避免填充(我可以用padarray做)。
我应该叠加内核并仅提取kernel == 1的元素,即
[2,5,11,10,7]然后在他们身上应用一个自定义过滤器,如中位数或平均值,并用结果替换中心元素。
然后我想通过所有其他元素(忽略边缘元素的简洁性)并做同样的事情。
现在我正在使用tempS= ordfilt2(Z,order,kernel,'symmetric');
用中值滤波器完全执行该操作。但我想使用不同的标准(即平均或一些奇怪的操作)
答案 0 :(得分:1)
这应该做你想要的:
D = rand(10,20);
kernel = [0,1,0;1,1,1;0,1,0];
[dy,dx] = find(kernel==1);
% should be calculated from kernel
dy = dy-2;
dx = dx-2;
% start and stop should calculated by using kernel size
result = zeros(size(D));
for y = 2:(size(D,1)-1)
for x = 2:(size(D,2)-1)
elements = D(sub2ind(size(D),y+dy,x+dx));
result(y,x) = weirdOperation(elements);
end
end
然而,就速度而言,这将表现得非常糟糕。你应该考虑使用内置函数。 conv2
或filter2
用于线性过滤操作。 ordfilt2
用于订单统计功能。
答案 1 :(得分:1)
使用blockproc
。这也会自动处理边框效果(请参阅documentation)。例如,要计算内核屏蔽的值的中位数:
mask = logical(kernel);
R = blockproc(D, [1 1], @(d) median(d.data(mask)), ...
'bordersize', [1 1], 'trimborder', 0);
第一个[1 1]
表示该步骤。第二个[1 1]
表示围绕中心元素采取的元素数量。
使用示例D
,结果为
R =
2 3 3 3
9 7 8 10
5 9 10 6
4 7 6 1