如何在矩阵的每个补丁索引中循环元素而不显式迭代每个补丁?

我可以想到执行此循环的迭代方法是使用MATLAB的circshift函数.我可以遍历矩阵中的每个MxN补丁,并对该补丁的元素执行循环移位.
(注意:circshift采用一个数组并将第一个(或第k个)索引移动到后面,将所有内容向前移动以腾出空间.使用矩阵,您只需向量化它,移动它并重新形状,利用MATLAB的列 -主要线性索引)
如果我要迭代我更大的每个MxN窗口(j*M xk*N为整数j,k)矩阵,那将是很好的.但是,我希望能够避免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 ]
Run Code Online (Sandbox Code Playgroud)
任何想法如何使这种转变工作没有明确迭代每个补丁?我觉得线性索引是关键,但我不知道为什么.只要每个补丁元素都在每个补丁索引中结束,我也不关心旋转的顺序.
提前致谢!
编辑:这是一个使用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
Run Code Online (Sandbox Code Playgroud)
一个简单的方法是使用blockproc图像处理工具箱中的函数。blockproc将图像(或者一般来说:矩阵)划分为定义大小的块,并对每个块应用一个函数:
B = blockproc(A,blockSize,fun);
Run Code Online (Sandbox Code Playgroud)
使用blockproc,我们可以将矩阵划分A为2 x 2多个补丁,并对每个补丁应用循环移位。请注意,blockproc创建一个block_struct数据类型并调用fun(block_struct). 要获取数据,只需使用data结构体的字段即可。这将导致
B = blockproc(A, [2,2], @(x)reshape(circshift(x.data(:),1),2,2));
Run Code Online (Sandbox Code Playgroud)
或者使用提供的示例代码:
A = repmat(1:4, 4, 1);
for k=1:4
A = blockproc(A, [2,2], @(x)reshape(circshift(x.data(:),1),2,2));
display(A);
end
Run Code Online (Sandbox Code Playgroud)
这会创建所需的输出
[ 1 2 3 4 ] [ 2 1 4 3 ] [ 2 1 4 3 ] [ 1 2 3 4 ]
[ 1 2 3 4 ] -> [ 1 2 3 4 ] -> [ 2 1 4 3 ] -> [ 2 1 4 3 ] -> ...
[ 1 2 3 4 ] [ 2 1 4 3 ] [ 2 1 4 3 ] [ 1 2 3 4 ]
[ 1 2 3 4 ] [ 1 2 3 4 ] [ 2 1 4 3 ] [ 2 1 4 3 ]
Run Code Online (Sandbox Code Playgroud)
您还可以定义如何处理矩阵不能分为2 x 2块的情况,例如,如果它有维度5 x 7(如注释中所述)。通过设置PadPartialBlocks为 true,所有部分块将被填充,以便它们形成完整2 x 2块。PadMethod您可以根据需要将该属性设置为以下值之一:
x其中x是一个数字,所有附加点都将设置为该数字。replicate将重复矩阵的边界元素Asymmetric将A用其自身的对称反射进行填充