如何在 MATLAB 中以(恒定)任意步幅将图像平铺成(恒定)任意大小的块?

How can I tile an image into patches of (constant) arbitrary size at (constant) arbitrary stride in MATLAB?

我有一个任意尺寸的图像 ROWSCOLS。我想将此图像平铺成任意但恒定大小 blockSize = [blockSizeR, blockSizeC] 的块,给定任意但恒定的步幅 stride = [strideR, strideC]。当行或列方向上的补丁数乘以相应的块大小分别不等于行数或列数时(即如果有备用行或列),我不关心它们(即它们可以是忽略)。如果图像从左上角像素开始被平铺成完全适合图像的所有可能的补丁就足够了。

网络上有很多可能的解决方案,但有些不允许重叠,有些不允许在有备用行或列的情况下输出,有些则低效地使用 for 循环。

最接近我需要的可能是https://de.mathworks.com/matlabcentral/answers/330357-how-do-i-store-a-series-of-rgb-images-in-a-2d-array上发布的解决方案:

%img: source image
stride = [5, 5];       %height, width
blocksize = [11, 11];  %height, width
tilescount = (size(img(:, :, 1)) - blocksize - 1) / stride + 1;
assert(all(mod(tilescount, 1) == 0), 'cannot divide image into tile evenly')
tiles = cell(tilescount);
tileidx = 1;
for col = 1 : stride(2) : size(img, 2 ) - blocksize(2)
   for row = 1 : stride(1) : size(img, 1) - blocksize(1)
      tiles{tileidx} = img(row:row+stride(1)-1, col:col+stride(2)-1, :);
      tileidx = tileidx + 1;
   end
end

但是,它似乎也只有在没有多余的行或列时才有效。我如何才能使其适应具有任意数量通道的图像的有效解决方案(我试图将其应用于单通道图像和 RGB 图像)?

上面的代码没有完全起作用,所以我想出了以下基于它的解决方案。选择的变量名称是不言自明的。

tilesCountR = floor((ROWS - rowBlockSize - 1) / rowStride + 1);
tilesCountC = floor((COLS - colBlockSize - 1) / colStride + 1);

tiles = cell(tilesCountR * tilesCountC,1);
tileidx = 1;
for col = 1 : colStride : COLS - colBlockSize
   for row = 1 : rowStride : ROWS - rowBlockSize
      tiles{tileidx} = img(row:row+rowBlockSize-1, col:col+colBlockSize-1, :);
      tileidx = tileidx + 1;
   end
end