使用Matlab将3D矩阵转换为字符串,再将其转换回3D矩阵

3
我目前正在进行一项关于如何使用Wang算法将秘密图像嵌入到封面图像中的速记任务。基本上,我只想更改例如:3D矩阵
A(:,:,1) = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7];
A(:,:,3) = [7 9 3; 4 5 9; 1 9 9];

To

Str = '578019436104356987793459199' 

如果有人能提供帮助,也可以反过来。


我假设A始终包含整数。 - Ander Biguri
输入 doc num2strdoc str2doubledoc reshape 应该是一个不错的起点。 - Zep
1
只有当您的矩阵中的所有元素都是0-9整数时,才能进行相反操作。 - Sardar Usama
1
你是以行还是列的方式重塑数据,这有关系吗? - gnovice
@gnovice 如果变换是可逆的话,那肯定会更容易。 - rayryeng
2个回答

4

由于MATLAB矩阵展开的顺序,您的问题可能比看起来更加复杂。您需要使用reshapepermute才能使其正常工作。

str=arrayfun(@num2str,reshape(permute(A,[2 1 3]),[],1,1)).';
A2=permute(reshape(arrayfun(@str2double,str),[size(A)]),[2 1 3]);
isequal(A2,A)

当然,这假设@Sardar在你的问题中所评论的:所有数字都是单个数字(即整数范围为0-9)。

2
可能更快的方法:str=char(reshape(permute(A,[2 1 3]),[],1,1)+'0')A2=permute(reshape(str-'0',size(A)),[2 1 3]) - Luis Mendo
@LuisMendo 嗯,想要在单独的答案中添加吗? - Ander Biguri
1
不,这是相同的想法。只是为了避免使用arrayfun而进行了一些小的注释(但代码变得稍微不那么易读)。 - Luis Mendo
1
@LuisMendo 可能更快的方法是使用sprintf。请参考我的回答。 - rayryeng
1
@rayryeng 好主意! - Luis Mendo

4
另一种方法是只使用sprintf。首先需要独立地转置每个切片,因此按照Ander的答案调用permute即可达到这一点。之后,您只需提供一个单一的格式字符串%d(整数)和实际的排列矩阵,它将按列展开所有元素并将所有数字连接在一起。额外的好处是您不再需要假设每个矩阵元素仅占据一个数字位。
str = sprintf('%d', permute(A, [2 1 3]));

例子

>> str = sprintf('%d', permute(A, [2 1 3]))

str =

578019436104356987793459199

>> class(str)

ans =

char

不过,要重建这个矩阵,你需要假设每个矩阵中只有一个元素。在这种情况下,你可以使用未记录的 sprintfc 函数,它可以输出一个字符对应一个单元格,然后使用 str2double 将字符转换为数字。最后,重新整形你的矩阵并撤销转置操作:

A2 = permute(reshape(str2double(sprintfc('%c', str)), size(A)), [2 1 3]);

示例

>> A2 = permute(reshape(str2double(sprintfc('%c', str)), size(A)), [2 1 3])

A2(:,:,1) =

     5     7     8
     0     1     9
     4     3     6


A2(:,:,2) =

     1     0     4
     3     5     6
     9     8     7


A2(:,:,3) =

     7     9     3
     4     5     9
     1     9     9

1
@AnderBiguri 哈哈,这只是偶然。我几天前也在做类似的事情。 - rayryeng
非常出色,非常感谢。 它完美地运作了。 但是,如果我可以问一下,最后一个矩阵([2 1 3])有什么用? 如果您可以给我一个思路,那就太好了。 - Nigussu Sima
1
@NigussuSima 没有问题。[2 1 3] 是用于 permute 函数的。它重新排列维度以达到所需的顺序。这意味着输出矩阵的第一维是输入矩阵的第二维,输出矩阵的第二维是输入矩阵的第一维,最后一个维度保持不变。通过交换第一和第二维,您有效地独立地转置每个 2D 切片。我们这样做是因为 MATLAB 是列优先的,所以在执行 sprintf 时,它展开列,因此您实际上是按行处理。 - rayryeng
@NigussuSima 对不起,我不太明白你的问题。512 x 512 的图像与 3 x 3 x 3 的矩阵有什么关系? - rayryeng
i = imread( %一张大小为512X512的图片 ); rgb实体被保存为 i(: , : , 1) , i(: , : , 2), i(: , : , 3),行和列大小均为512像素 我的目标是将这些值转换为单个字符串,对它们进行修改以使用Wang算法嵌入秘密图像,最后将其返回到3D RGB矩阵以在屏幕上显示最终图像。 - Nigussu Sima
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接