Image 将图像中的多个像素值替换为某个值
我有一张640x480的图像Image 将图像中的多个像素值替换为某个值,image,matlab,image-processing,Image,Matlab,Image Processing,我有一张640x480的图像img,我想用一个特定的值10,来替换不在这个列表或数组中的像素x=[1,2,3,4,5],这样img中没有x中任何值的任何像素都将被替换为10。我已经知道如何使用img(img~=1)=10替换一个值,或者使用这个img(img~=1&img~=2&img~=3&img~=4&img~=5)=10替换多个值,但是当我尝试这个img(img~=x)=10时,它给出了一个错误,说矩阵维度必须一致。因此,如果有人可以提供建议。您可以通过和的组合轻松实现这一点。我们可以创建
img
,我想用一个特定的值10
,来替换不在这个列表或数组中的像素x=[1,2,3,4,5]
,这样img
中没有x
中任何值的任何像素都将被替换为10
。我已经知道如何使用img(img~=1)=10替换一个值,或者使用这个img(img~=1&img~=2&img~=3&img~=4&img~=5)=10替换多个值,但是当我尝试这个img(img~=x)=10
时,它给出了一个错误,说矩阵维度必须一致
。因此,如果有人可以提供建议。您可以通过和的组合轻松实现这一点。我们可以创建一个由[1,2,3,4,5]
元素组成的3D列向量,然后在图像(假设灰度)上使用bsxfun
和不等于方法(@ne
),从而创建一个包含5个切片的3D矩阵。每个切片将告诉您图像中的位置是否与x
中的元素不匹配。第一个片段将为您提供与x=1
不匹配的位置,第二个片段将为您提供与x=2
不匹配的位置,依此类推
完成此操作后,我们可以使用对第三维操作的调用来合并不等于所有1、2、3、4或5的像素位置。最后一步是采用这个逻辑映射,它告诉您不是1、2、3、4或5的位置,我们将这些位置设置为10
我们需要考虑的是图像类型和向量<代码> 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;
ind = true(size(img));
for idx = 1 : 5
ind = ind & img ~= idx;
end
img(ind) = 10;
上述方法的优点是,用于检查元素的列表可以是您想要的任何列表。它可以防止出现混乱的逻辑索引语法,如img(img~=1&img~=2&..)
。您所要做的就是更改代码开始行的输入列表,bsxfun
、permute
和任何
都应该为您完成这项工作
下面是一个示例5 x 5图像:
>> 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
通过使用上述代码,我们得到的输出是:
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
您可以非常肯定地看到,那些既不是1、2、3、4或5的元素被设置为10
在一边
如果您不喜欢permute
和bsxfun
方法,一种方法是使用for
循环,并使用最初的alltrue
数组,使用一个logical
映射保持逻辑与最终结果的and,该映射由不等于x
中每个值的位置组成。最后,我们将有一个逻辑映射,其中true
是那些既不等于1、2、3、4或5的位置
因此,请这样做:
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;
ind = true(size(img));
for idx = 1 : 5
ind = ind & img ~= idx;
end
img(ind) = 10;
如果你这样做,你会发现我们得到了相同的答案。方法#1
你可以用,
根据ismember(a,B)
案例的官方文档,它将输出一个与a
大小相同的逻辑数组,其中1
B
中的任何元素都存在于A
,0
,否则。由于您希望检测到“不在列表或数组中”
,因此需要在之后将其反转,即~ismember()
在您的例子中,您有img
作为A
和x
作为B
,因此~ismember(img,x)
将为您提供img~=x中任何元素的位置
然后,您可以映射到img
,使用此最终解决方案将其中的所有值设置为10
-
img(~ismember(img,x)) = 10
方法#2
与类似,您可以使用,但将其保留在2D
中,这样会更有效,因为它还可以避免permute
。实现看起来像这样-
img(reshape(all(bsxfun(@ne,img(:),x(:).'),2),size(img))) = 10
非常有趣的问题!一个我已经想了很多次并解决了的问题。谢谢你的提问:)@shepherd:IMHO,ismember
方法是兼顾内存和可读性的方法。@Jonas同意这两种观点!