Matlab:使用滑动 window 裁剪图像?

Matlab: crop image with a sliding window?

有人知道如何在 Matlab 中使用滑动 window 裁剪图像吗? 例如我有一个 1000x500 像素的图像,我想从这个图像中裁剪 50x50 像素的块...当然我必须处理不均匀的分割,但没有必要具有相同大小的块。

我会先研究函数 blockproc 看看它是否能满足您的需求。


如果您确定要手动将图像裁剪成块,可以使用此脚本。它既将裁剪后的图像写入 .png 文件,又将裁剪后的图像保存在 3D 数组的页面中。您可以根据需要进行修改。

此脚本假定图像可以被块大小整除。如果不是,则需要用零填充它。

[rowstmp,colstmp]= size(myImage);
block_height     = 50;
block_width      = 50;

blocks_per_row   = rows/block_height;
blocks_per_col   = cols/block_width;
number_of_blocks = blocks_per_row*blocks_per_col;

%// pad image with zeros if needed
if ~(mod(rowstmp-1,block_height)==0)
    rows = ceil(rowstmp/block_height)*block_height;
end
if ~(mod(colstmp-1,block_width)==0)
    cols = ceil(colstmp/block_width)*block_width;
end
Im = uint8(zeros(rows,cols));
Im(1:rowstmp,1:colstmp) = myImage;

%// make sure these image have type uint8 so they save properly
cropped_image    = uint8(zeros(rows,cols));
img_stack        = uint8(zeros(rows,cols,number_of_blocks));

%// loop over the image blocks
for i = 1:blocks_per_row
    for j = 1:blocks_per_col
        %// get the cropped image from the original image
        idxI = 1+(i-1)*block_height:i*block_height;
        idxJ = 1+(j-1)*block_width :j*block_width;
        cropped_image(idxI,idxJ) = Im(idxI,idxJ);

        %//imshow(cropped_image)

        %// write the cropped image to the current folder
        filename = sprintf('block_row%d_col%d.png',i,j);
        imwrite(cropped_image,filename);
        cropped_image(idxI,idxJ) = 0;

        %// keep all the blocks in a 3D array if we want to use them later
        img_stack(:,:,(i-1)*blocks_per_col+j);
    end
end

过去对我有帮助的一些细节涉及 (i) 在块处理时划分图像的方法和 (ii) "uneven division",如 OP 所述。

(i) divide/process 图片的方法:

1.处理非重叠块:

使用默认参数 {'BorderSize',[0 0]},这可以用 blockproc 处理,如下所示。

(i)-1 的示例:注意输出的阻塞性质。这里每个大小为 32 x 32 的非重叠块用于计算 std2() 并且输出 std2 值用于填充该特定块。输入和输出的大小为 32 x 32。

fun = @(block_struct) std2(block_struct.data) * ones(size(block_struct.data));
I2 = blockproc('moon.tif',[32 32],fun);
figure; subplot(1, 2, 1);
imshow('moon.tif'); title('input');
subplot(1,2, 2)
imshow(I2,[]); title('output'); 

输入和输出图像:

(i)-2:处理重叠块:

使用参数{'BorderSize',[V H]}:在块的上下添加V行,在块的左右添加H列。处理的块有 (N + 2*V) 行和 (M + 2*H) 列。使用默认参数 {'TrimBorder',true},输出的边框被修剪为 N 行 M 列的原始输入块大小。

(i)-2 的示例:下面使用 blockproc 的代码使用 {'BorderSize',[15 15]} 且 [N M] = [1 1]。这类似于使用自定义内核过滤图像的每个像素。因此,处理单元的输入是一个大小为 (1 + 2*15) 行和 (1 + 2*15) 列的块。由于 {'TrimBorder',true} 默认情况下,31 行 x 31 列块的 std2 作为每个像素的输出提供。修剪边框后输出大小为 1 x 1。因此,请注意,与前面的示例相比,此示例输出为 'non-blocked'。此代码需要更长的时间来处理所有像素。

fun = @(block_struct) std2(block_struct.data) * ones(size(block_struct.data));
I2 = blockproc('moon.tif',[1 1],fun,'BorderSize',[15 15]);
figure; subplot(1, 2, 1);
imshow('moon.tif'); title('input');
subplot(1,2, 2)
imshow(I2,[]); title('output');

输入和输出图像:

(ii) "Uneven division":

1. Zero/replicate/symmetric 填充:

零填充,以便整数倍的块(N 行乘以 M 列大小)可以覆盖不均匀维度中的 [图像 + 边界零点]。这可以通过使用默认参数 {'PadMethod', 0} 以及 {'PadPartialBlocks' , true}(默认情况下为 false)来实现。如果零边界区域导致从边界块计算的值高度不连续,则可以使用 {'PadMethod'、'replicate'} 或 {'PadMethod'、'symmetric'}。

2。假设图像中有一个"Active Region"进行分块处理

对于处理每个像素的情况,如情况 (i)-2,我们可以假设使用的图像周边的所有边上有一个 floor(block_size/2) 个像素的边界区域作为 "Dummy" 区域。块处理的活动区域包含在虚拟区域中。

成像传感器中使用了类似的东西,其中位于有源像素成像阵列外围的虚拟像素允许像所有有源区域像素的颜色插值这样的操作。由于颜色插值通常需要 5x5 像素掩码来插值像素的颜色值,因此可以使用 2 个像素的边界虚拟外围。

假设 MATLAB 索引,区域 ( floor(block_size/2) + 1 ) 到 ( Input_Image_Rows - floor(block_size)/2) ) 行由 ( floor(block_size/2) + 1 ) to ( Input_ImageCols - floor(block_size)/2) ) 列被认为是活动区域(假设方块边,block_size)经历块如 (i)-2 中那样对每个像素进行处理。

假设方块大小为 5 x 5,如下所示:

block_size  = 5;
buffer_size = floor(block_size/2);
for i = (buffer_size+1):(image_rows-buffer_size)
    for j = (buffer_size+1):(image_cols-buffer_size)
        ...  % block processing for each pixel Image(i,j)
    end
end

Matlab 版本:R2013a