如果重新塑造一次然后重新塑造回原始大小,Matlab矩阵会改变吗?

时间:2016-06-07 15:26:17

标签: matlab matrix reshape

基本上我有一个原始的128 x 128 x 3矩阵,它描述了一个RGB图像(128 * 128点,每个点分别是一个包含红色,绿色和蓝色强度的1x3矢量),我也有16个点从中选择它们(这是容易的部分),现在我想在128 x 128 x 3矩阵和16点之间进行成对距离计算。

但问题是Matlab的功能," pdist2"只需要2个大小为M1 x N和M2 x N的矩阵而不是其他任何东西,所以我打算将128 x 128 x 3矩阵转换为(128 * 128)x 3矩阵。稍后,在使用新变换的矩阵进行一些计算之后,我需要将其转换回原始大小以显示图像并检查结果。但我不确定这些元素是否会留在原位或是否会被拖曳?请帮助我,非常感谢你!

2 个答案:

答案 0 :(得分:6)

来自documentation

  

B中的数据类型和元素数量与A中的数据类型和元素数量相同。 B中的元素保留了从A开始的列式排序。

如果您需要的结果与原始结果大小相同,只需在初始转换之前存储大小,并在执行操作之后将其用作reshape的输入。数据

% Store the original size
originalSize = size(data);

% Reshape it to your new 2D array
data = reshape(data, [], 3);

% Do stuff

% Reshape it back to it's original size
data = reshape(data, originalSize);

在2D版本中,元素在技术上不会像在3D矩阵中那样处于同一位置,因为......好吧......不是3D而是3D。 但是,如果你将它重新塑造回3D(没有移动元素),元素排序将与原始3D矩阵相同。

<强>更新

您可以自己轻松查看。

R = rand([10, 20, 3]);
isequal(R, reshape(reshape(R, [], 3), size(R)))

为什么这是因为reshape实际上并没有改变基础数据,而是改变了它的访问方式。我们可以使用format debug轻松检查这一点,以查看数据的存储位置。

我们还可以使用a little anonymous function I wrote来查看存储器中存储给定变量的位置。

format debug;
memoryLocation = @(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')

好的,让我们创建一个矩阵并检查MATLAB将其存储在内存中的位置

A = rand(10);
memoryLocation(A)
%   7fa58f2ed9c0

现在让我们重塑它并再次检查内存位置以查看它是否在不同的位置(即订单或值被修改)

B = reshape(A, [], 10);
memoryLocation(B)
%   7fa58f2ed9c0

正如您所看到的,内存位置没有改变意味着元素的排序是相同的,否则MATLAB需要在内存中复制。

答案 1 :(得分:0)

基础数据表示以及为什么Suever的答案是正确的:

MATLAB中的底层数组数据本质上是一个双精度浮点数组。在c ++中它将是:

double *array_data;

MATLAB以列主格式存储数据。如果箭头有n_rows行,则元素A_{i,j}(即第i行,第j列(零索引)将由下式给出:

array_data[i + j * n_rows]

当您调用reshape函数时,变量n_rowsn_cols等等会发生什么变化。不会更改{{1 }}

示例(无需触摸数组数据来调整数组大小):

array_data

使用array_data = [1, 2, 3, 4, 5, 6]; 和列主格式,这将是:

n_rows = 2

使用n_rows = 3 和相同的底层array_data ,您将拥有:

A = [1, 3, 5
     2, 4, 6]


A11 = array_data[0 + 0 * 2] = array_data[0] = 1
A21 = array_data[1 + 0 * 2] = array_data[1] = 2
A12 = array_data[0 + 1 * 2] = array_data[2] = 3
A22 = array_data[1 + 1 * 2] = array_data[3] = 4
A13 = array_data[0 + 2 * 2] = array_data[4] = 5
A23 = array_data[1 + 2 * 2] = array_data[5] = 6

只需更改A = [1, 4 2, 5 3, 6] A11 = array_data[0 + 0 * 3] = array_data[0] = 1 A21 = array_data[1 + 0 * 3] = array_data[1] = 2 A31 = array_data[2 + 0 * 3] = array_data[2] = 3 A12 = array_data[0 + 1 * 3] = array_data[3] = 4 A22 = array_data[1 + 1 * 3] = array_data[4] = 5 A32 = array_data[2 + 1 * 3] = array_data[5] = 6 n_rows等等...