有人知道如何在Matlab中使用滑动窗口裁剪图像吗? 例如我有一个1000x500像素的图像,我想从50x50像素的图像块中裁剪...当然我必须处理不均匀的分割,但没有必要有相同大小的块。
答案 0 :(得分:2)
过去帮助我的一些细节涉及(i)在块处理时划分图像的方法和(ii)OP提到的“不均匀划分”。
(i)分割/处理图像的方法:
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行31列块的std2作为每个像素的输出提供。修剪边框后,输出大小为1 x 1。因此,请注意,与前一个示例相比,此示例输出是“非阻止”。此代码需要更长的时间来处理所有像素。
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)“分歧不均匀”:
1。零/复制/对称填充:
零填充,以便块的整数倍(N行×M cols大小)可以覆盖不均匀维度中的[image + bounding neros]。这可以通过使用默认参数{'PadMethod',0}以及{'PadPartialBlocks',true}来实现(默认情况下为false)。如果零的边界区域导致从边界块计算的值中存在高度不连续性,则可以使用{'PadMethod','replicate'}或{'PadMethod','symmetric'}。
2。假设图像中的“活动区域”用于块处理
对于处理每个像素的情况,如情况(i)-2,我们可以假设沿着图像周边的所有边上的floor(block_size / 2)像素的边界区域被用作“Dummy”区域。用于块处理的活动区域包含在虚拟区域中。
在成像传感器中使用类似的东西,其中位于有源像素成像阵列外围的虚拟像素允许像所有有源区域像素的颜色插值那样的操作。由于颜色插值通常需要5×5像素掩模来内插像素的颜色值,因此可以使用2个像素的边界虚拟外围。
假设MATLAB索引,区域(floor(block_size / 2)+ 1)到(Input_Image_Rows - floor(block_size)/ 2))行(floor(block_size / 2)+ 1)到(Input_ImageCols - floor(block_size) )/ 2))列被认为是活动区域(假设边的正方形块,block_size),其对于每个像素进行块处理,如(i)-2中所示。
假设方块大小为5乘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 ver:R2013a
答案 1 :(得分:1)
我首先会查看函数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