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

Replace multiple pixels value in an image with a certain value Matlab

我有一张 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 时,它给出了一个错误提示 Matrix dimensions must agree。所以如果有人可以请指教。

您可以通过 permute and bsxfun 的组合轻松实现此目的。我们可以创建一个由 [1,2,3,4,5] 的元素组成的 3D 列向量,然后在您的图像(假设灰度)上使用 bsxfun 和不等于方法 (@ne),这样我们就可以创建5 个切片的 3D 矩阵。每个切片都会告诉您图像中的位置 是否与 中的元素不匹配 x。第一个切片会给你匹配x = 1的位置,第二个切片会给你的位置]匹配x = 2,依此类推。

完成此操作后,我们可以使用在三维上运行的 all 调用来合并不等于所有 1、2、3、4 或 5 的像素位置。 最后一步将采用此 logical 地图,它告诉您 none 的位置 1、2、3、4 或 5,我们将这些位置设置为 10。

我们需要考虑的一件事是图像类型和矢量 x 必须是同一类型。我们可以通过将向量转换为与 img.

相同的 class 来确保这一点

因此,做这样的事情:

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 & ....)。您所要做的就是更改代码开头行的输入列表,bsxfunpermuteany 应该会为您完成这项工作。

这是一个 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。

放在一边

如果您不喜欢 permutebsxfun 方法,一种方法是使用 for 循环并使用初始全部 true 数组,使用 logical 映射保持逻辑与最终结果,该映射由不等于 x 中每个值的那些位置组成。最后,我们将有一个逻辑映射,其中 true 是那些既不等于 1、2、3、4 或 5 的位置。

因此,做这样的事情:

ind = true(size(img));
for idx = 1 : 5
    ind = ind & img ~= idx;
end
img(ind) = 10;

如果您改为这样做,您会发现我们得到了相同的答案。

方法 #1

您可以使用 ismember, 根据其关于 ismember(A,B) 案例的官方文档,它会输出与 A 大小相同且具有 1 的逻辑数组 B 中的任何元素都存在于 A 中,否则 0 中存在。因为,您要检测 "not in the list or array",之后需要将其反转,即 ~ismember().

在你的例子中,你有 img 作为 Ax 作为 B,所以 ~ismember(img,x) 会给你那些 [=26] =] 然后您可以映射到 img 以使用此最终解决方案将其中的所有内容设置为 10 -

img(~ismember(img,x)) = 10

方法 #2

类似于 , you can use bsxfun,但将其保留在 2D 中,这可能更有效,因为它也避免了 permute。实现看起来像这样 -

img(reshape(all(bsxfun(@ne,img(:),x(:).'),2),size(img))) = 10