如何高效地遍历矩阵元素

3

我有一个针对8位图像分析的matlab脚本,我正在尝试通过减去没有物体存在的背景来增强图像中的物体。在像素级别上,我想做的是:

if B-I>50 then E=I
else E=255-B-I

在这里,B代表背景,I代表图像,E代表增强后的图像。我知道可以通过以下方式循环遍历图像矩阵的每个元素来实现这一点:

diff=imsubtract(B,I);
nrows=1024;
ncols=1360;
for r=1:nrows
     for c=1:ncols
         if diff(r,c)>50
             E=I(r,c);
         else
             E=255-diff(r,c);
         end
     end
 end

但是在处理多张图片时,这个方法可能会比较慢。我也尝试了以下方法:

 E=255-diff;
 E(diff>50)=I;

但是出现了以下错误:
在赋值“A(I) = B”中,B和I中的元素数量必须相同。
有什么优化的建议将不胜感激!

2
请勿使用 diff 作为变量名。在 Matlab 中,它是一个标准函数,这样会导致重载。这可能会令人困惑并导致意外问题的发生。 - Dennis Jaheruddin
3个回答

4

在赋值语句A(I)= B中,B和I的元素数量必须相同。

这个错误的原因是你试图将I的所有内容分配给E的一个子集(那些像素其中diff>50)。你必须明确告诉MATLAB你想要那些像素设置为I中匹配的像素。

E(diff>50)=I(diff>50);

顺便提一下,在这里使用imsubtract时需要小心。对于IB的像素,如果你的值是uint8,那么结果将为零。也许这没关系(不确定你是在寻找绝对差异还是真正只是B大于I的地方)。


这正好按照我的意愿运作。 E=255-D; E(D>50)=I(D>50);根据其他评论中有关使用diff的建议,将变量更改为D。谢谢! - C_Brown

1
如果你使用 find() 会怎样?
ind = find(B-I>50)
E(ind) = I(ind)

% And then the ones that are not `B-I>50`
E(~ind) = 255-B(~ind)-I(~ind)

1
实际上你可以省略 find 直接使用 ind = B-I>50,这会使得代码更加高效。 - Dennis Jaheruddin
你可能是正确的。只是问题在于提问者尝试使用逻辑索引却失败了。这就是我为什么用find的原因。 - kkuilla
测试过了,但结果是一个1x1392640的矩阵,而不是1024x1360。 - C_Brown
我假设您已经预先分配了 EE = zeros(size(I))。如果是这样的话,那么 E 应该和 I 具有相同的形状。 - kkuilla
虽然我认为@nkjt的答案更优雅,也可能是最有效和最快的。 - kkuilla

0
尝试使用逻辑索引的矢量化方法。但是,我无法在图像上测试它,所以如果能够解决这个问题就太好了。
代码:
diff1=double(imsubtract(B,I));
E = double(I).*(diff1>50) + (255-diff1).*(diff1<=50);

您可能需要将数据类型转换回用于图像的无符号整数格式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接