【发布时间】:2015-05-02 04:26:37
【问题描述】:
如何在不显式迭代每个补丁的情况下循环遍历矩阵补丁的每个索引?
我认为执行此循环的迭代方式是使用 MATLAB 的 circshift 函数。我可以遍历矩阵中的每个 MxN 补丁,并对该补丁的元素执行循环移位。
(注意:circshift 接受一个数组并将第一个(或第 k 个)索引向后移动,将所有内容向前移动以腾出空间。使用矩阵,您只需对其进行矢量化、移动并重新整形,利用 MATLAB 的列优先线性索引)
如果我要遍历较大的 (j*M x k*N for integers j,k) 矩阵的每个 MxN 窗口,那就太好了。但是,我希望能够避免 for 循环并利用 MATLAB 的矢量化代码一举完成此操作。
一个完整的迭代示例(某些矩阵 B 中的 2x2 个补丁)将是:
B = --> B = --> B = --> B =
[ 5 6 7 8 ] --> [ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ]
[ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ] --> [ 5 6 7 8 ]
[ 5 6 7 8 ] --> [ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ]
[ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ] --> [ 5 6 7 8 ]
任何想法如何在不明确迭代每个补丁的情况下使这种转变发挥作用?我觉得线性索引是这里的关键,但我不知道为什么。只要每个补丁元素都在每个补丁索引中结束,我也不关心旋转顺序。
提前致谢!
编辑:这是一个可以复制和粘贴的玩具实现,使用 for 循环来演示我在寻找什么。答案中应该包含的唯一 for 循环是 k-iterator(控制最终需要进行多少次转换)
A = repmat(1:4, 4, 1); % Input matrix
% k represents the total number of shifts to be made
for k = 1:4
% Iterate through each patch
for i = 1:2:size(A,1)
for j = 1:2:size(A,2)
tmp = A(i:i+1,j:j+1); % Isolate specific patch
% Circularly shift the vectorized patch, reshape it to a matrix
% and insert it back into the original matrix
A(i:i+1,j:j+1) = reshape(circshift(tmp(:),1), 2, 2);
end
end
display(A) % Display each completely shifted iteration
end
【问题讨论】:
-
这是一个有趣的问题。你一般可以认为你想要的一切都可以做到。但至少我没有动力去思考你的输入和输出应该如何安排。请发布您准备好复制和粘贴的确切输入以及您希望为该输入获得的输出(也准备好复制和粘贴)。有很多事情要澄清。例如你喜欢单元格数组作为输出吗?还是 3D 矩阵?
-
@thewaywewalk 我添加了一个用于复制/粘贴的玩具示例,希望可以演示我正在寻找的内容。输出应该是与输入相同维度的矩阵。我想避免使用元胞数组,除非它们可以很容易地转换回来。我也考虑过使用元胞数组,因为它们对于将矩阵划分为块很有用,但即便如此,据我所知,它也无助于进行转变。