用特定值替换图像中的多个像素值 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 & ....)
。您所要做的就是更改代码开头行的输入列表,bsxfun
、permute
和 any
应该会为您完成这项工作。
这是一个 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
循环并使用初始全部 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
作为 A
和 x
作为 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
我有一张 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
.
因此,做这样的事情:
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
和 any
应该会为您完成这项工作。
这是一个 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
循环并使用初始全部 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
作为 A
和 x
作为 B
,所以 ~ismember(img,x)
会给你那些 [=26] =]
然后您可以映射到 img
以使用此最终解决方案将其中的所有内容设置为 10
-
img(~ismember(img,x)) = 10
方法 #2
类似于 bsxfun
,但将其保留在 2D
中,这可能更有效,因为它也避免了 permute
。实现看起来像这样 -
img(reshape(all(bsxfun(@ne,img(:),x(:).'),2),size(img))) = 10