我的图片为640x480 img
,我想将具有不在此列表或数组x=[1, 2, 3, 4, 5]
中的值的像素替换为特定值10
,以便{{1}中的任何像素1}}没有img
中的任何值,将替换为x
。我已经知道如何使用10
使用img(img~=1)=10
替换一个值或使用此img(img~=1 & img~=2 & img~=3 & img~=4 & img~=5)=10
替换多个值,但是当我尝试此img(img~=x)=10
时,我发出错误说Matrix dimensions must agree
。所以,如果有人可以请提供建议。
答案 0 :(得分:4)
通过permute
和bsxfun
的组合,您可以轻松实现这一目标。我们可以创建一个由[1,2,3,4,5]
元素组成的3D列向量,然后在图像上使用bsxfun
和非等于方法(@ne
)(假设是灰度),这样我们就可以创建5个切片的3D矩阵。每个切片都会告诉您图像中的位置是否与x
中的元素匹配。第一个切片会为您提供不匹配x = 1
的位置,第二个切片会为您提供不匹配的位置{{1} }, 等等。
完成此操作后,我们可以在第三维上使用all
调用来合并不等于1,2,3,4或5的像素位置。最后一步是获取此x = 2
地图,该地图会告诉您不是1,2,3,4或5的位置,我们会将这些位置设置为10。
我们需要考虑的一件事是图像类型和向量logical
必须是相同的类型。我们可以通过将向量转换为与x
相同的类来确保这一点。
因此,做这样的事情:
img
上述方法的优点是您要用于检查元素的列表可以是您想要的任何内容。它可以防止出现凌乱的逻辑索引语法,例如x = permute([1 2 3 4 5], [3 1 2]);
vals = bsxfun(@ne, img, cast(x, class(img)));
ind = all(vals, 3);
img(ind) = 10;
。您所要做的就是更改代码开头行的输入列表,img(img ~= 1 & img ~= 2 & ....)
,bsxfun
和permute
应该为您完成工作。
这是一个示例5 x 5图像:
any
通过使用上面的代码,我们获得的输出是:
>> rng(123123);
>> img = randi(7, 5, 5)
img =
3 4 3 6 5
7 2 6 5 1
3 1 6 1 7
6 4 4 3 3
6 2 4 1 3
您肯定可以看到那些既不是1,2,3,4或5的元素都设置为10。
如果您不喜欢img =
3 4 3 10 5
10 2 10 5 1
3 1 10 1 10
10 4 4 3 3
10 2 4 1 3
和permute
方法,一种方法是使用bsxfun
循环并使用最初的所有for
数组,保持逻辑使用true
地图对最终结果进行AND运算,该地图由那些与logical
中的每个值不相等的位置组成。最后,我们将得到一个逻辑映射,其中x
是那些既不等于1,2,3,4或5的位置。
因此,做这样的事情:
true
如果您这样做,您会看到我们得到相同的答案。
答案 1 :(得分:3)
方法#1
您可以使用ismember
,
根据其ismember(A,B)
案例的官方文档,将输出与A
和1
的大小相同的逻辑数组
B
中的任何元素都存在于A
,0
中。由于您希望检测"not in the list or array"
,因此您需要在之后将其反转,即~ismember()
。
在您的情况下,img
为A
而x
为B
,因此~ismember(img,x)
会为您提供img~=any element in x
的地方
然后,您可以使用此最终解决方案映射到img
以将其中的所有内容设置为10
-
img(~ismember(img,x)) = 10
方法#2
与rayryeng's solution
类似,您可以使用bsxfun
,但请将其保留在2D
中,这可能会更有效,因为它也会避免permute
。实现看起来像这样 -
img(reshape(all(bsxfun(@ne,img(:),x(:).'),2),size(img))) = 10