用特定值Matlab替换图像中的多个像素值

时间:2015-03-17 01:22:16

标签: image matlab image-processing

我的图片为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。所以,如果有人可以请提供建议。

2 个答案:

答案 0 :(得分:4)

通过permutebsxfun的组合,您可以轻松实现这一目标。我们可以创建一个由[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 & ....)bsxfunpermute应该为您完成工作。

这是一个示例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)案例的官方文档,将输出与A1的大小相同的逻辑数组 B中的任何元素都存在于A0中。由于您希望检测"not in the list or array",因此您需要在之后将其反转,即~ismember()

在您的情况下,imgAxB,因此~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