簡體   English   中英

Matlab:用推拉窗裁剪圖像?

[英]Matlab: crop image with a sliding window?

有人知道如何在Matlab中使用滑動窗口裁剪圖像嗎? 例如,我有1000x500像素的圖像,我想從這個50x50像素的圖像塊中裁剪...當然我必須處理不均勻的分割,但是沒有必要具有相同大小的塊。

過去幫助我的一些細節涉及(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)-1示例:裁剪具有非重疊塊的圖像

(i)-2:處理重疊塊:

使用參數{'BorderSize',[VH]}:在塊的上方和下方添加V行,並將H列添加到塊的左側和右側。 處理的塊具有(N + 2 * V)行和(M + 2 * H)列。 使用默認參數{'TrimBorder',true},輸出的邊框被修剪為N行和M列的原始輸入塊大小。

(i)-2的示例:使用blockproc的代碼使用{'BorderSize',[15 15]}和[NM] = [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大小)可以覆蓋不均勻維度中的[圖像+邊界零]。 這可以通過使用默認參數{'PadMethod',0}以及{'PadPartialBlocks',true}來實現(默認情況下為false)。 如果零的邊界區域導致從邊界塊計算的值的高度不連續性,則可以使用{'PadMethod','replicate'}或{'PadMethod','symmetric'}。

2.假設圖像內的“活動區域”用於塊處理

對於處理每個像素的情況,如在情況(i)-2中,我們可以假設沿着用作“虛擬”區域的圖像的周邊的所有側面上的floor(block_size / 2)像素的邊界區域。 用於塊處理的活動區域包含在虛擬區域中。

在成像傳感器中使用類似的東西,其中位於有源像素成像陣列外圍的虛擬像素允許像所有有源區域像素的顏色插值那樣的操作。 由於顏色插值通常需要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

我首先看看函數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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM