Matlab分配3D数组的1D切片

Posted

技术标签:

【中文标题】Matlab分配3D数组的1D切片【英文标题】:Matlab Assigning 1D slice of 3D array 【发布时间】:2017-04-10 04:32:13 【问题描述】:

如何在 MATLAB 的 3d 数组中分配一维切片?

我有一个名为“CD”的逻辑 2d 数组,它对应于我要设置的 3-D 图像矩阵(RGB 格式)的像素。

CD = any(d, 3);
CDM(CD) = 255;

因此,在本例中,“CDM”是一个 3d 矩阵,其中包含每个像素的 R、G、B 值(例如,它是一个 771x457x3 矩阵)。

上面的代码有效。它会生成我想要的红色像素图像。

但是现在假设我想生成绿色或青色像素?如何访问“CDM”的第二和第三“层”(绿色和蓝色值)?我尝试分配

CDM(CD) = [0 255 255];

但这会返回错误

In an assignment  A(:) = B, the number of elements in A and B must be the same.

【问题讨论】:

【参考方案1】:

为了使用 2D 数组修改每个通道,您需要获取每个通道(作为 2D 数组),然后使用 2D 逻辑数组将您想要的像素替换为所需的值,然后将其分配回去进入数组。

green = CDM(:,:,2);
green(CD) = 255;
CDM(:,:,2) = green;

或者,您可以执行以下操作来矢量化问题。

replace_color = [0 255 255];
CDM = bsxfun(@times, ~CD, CDM) + bsxfun(@times, CD, reshape(replace_color, [1 1 3]))

说明

首先,我们使用bsxfun 执行维度广播并将CDM 内的每个RGB 像素与逻辑矩阵的逆矩阵(~) 相乘。这会将CD 中的所有1 像素设置为0,并将所有其他像素保留为其原始值(因为它们乘以1)。

bsxfun(@times, ~CD, CDM)

然后,我们将CD 乘以新颜色(重新整形为 1 x 1 x 3 数组)以生成 M x N x 3 数组,其中CD1 的每个 RGB 向量是所需的 RGB值和所有其他值都是0

bsxfun(@times, CD, reshape(replace_color, [1 1 3]))

然后,我们将这两者相加,以在 CD0 时保持 RGB 值,并在 CD1 时将 RGB 值替换为新值。

如果您使用的是 R2016b 或更高版本,则可以删除 bsxfun,解决方案简化为:

CDM = (~CD .* CDM) + (CD .* reshape(replace_color, [1 1 3]));

【讨论】:

三种解决方案都有效!非常好的答案,谢谢。 R2016 有什么不同,所以您可以“删除 bsxfun”? 2016 会自动扩展数组操作的单例维度 (?),这正是 bsxfun 所做的。 @Floris 有很多改进,但最突出的改进之一是单例维度的自动广播......所以是的,您可以删除 bsxfun,MathWorks 建议您这样做,因为它会更快、更容易阅读、更高效。

以上是关于Matlab分配3D数组的1D切片的主要内容,如果未能解决你的问题,请参考以下文章

为啥扩展切片分配不如常规切片分配灵活?

创建数组的随机切片以分配给另一个对象数组

结构的Matlab数组:快速分配

如何对 Rust 数组的 2 个可变切片进行操作?

如何在 C 中将动态分配的 3D 数组写入 hdf5 文件?

Matlab:为结构数组相同位置的(不同)字段分配相同的值