2015-03-26 5 views
1

Est-ce que quelqu'un sait comment recadrer une image avec une fenêtre coulissante dans Matlab? par exemple. J'ai une image de 1000x500 pixels, je voudrais recadrer à partir de cette image des blocs de 50x50 pixels ... Bien sur je dois gérer des divisions inégales, mais il n'est pas nécessaire d'avoir un bloc de même taille.Matlab: recadrer l'image avec une fenêtre coulissante?

+0

[Eventuellement connexe] (http://stackoverflow.com/q/ 12078825/2065121) –

+1

Si vous ne trouvez pas un moyen avec Matlab, il s'agit d'un simple interligne avec ImageMagick qui est installé sur la plupart des distributions Linux et est disponible pour OSX et Windows ... 'convert -crop 50x50 in.png tile% d.png' et vos 200 tiles seront créés en tant que 'tile0.png' à' tile199.png'. N'hésitez pas à changer tout 'png' en' jpg' ou 'tif' ou' bmp' ou ce dont vous avez besoin. –

+0

Je dois trouver un moyen dans matlab; D c'est seulement une partie du problème que je dois résoudre! Merci ... – Kevin

Répondre

1

Je voudrais d'abord regarder dans la fonction blockproc pour voir si elle peut faire ce que vous voulez. Si vous êtes sûr de vouloir recadrer manuellement l'image en blocs, vous pouvez utiliser ce script. Il écrit les images recadrées dans des fichiers .png et enregistre les images recadrées dans les pages d'un tableau 3D. Vous pouvez le modifier selon vos besoins.

Ce script suppose que l'image est uniformément divisible par la taille du bloc. Si ce n'est pas le cas, vous devrez le remplir de zéros.

[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 
+0

Merci beaucoup pour la réponse fournie .... Mais gérer les divisions inégales, comme demandé, est fondamentale ... Avez-vous une idée? – Kevin

+0

@Kevin Je ne comprends pas ce que vous entendez par "division inégale". Comme dans l'image largeur/hauteur n'est pas un multiple pair de la taille du bloc?Pourrais-je simplement ajouter un remplissage nul pour résoudre ce problème? – eigenchris

+0

oui bien sûr ... – Kevin

2

Quelques détails qui me ont aidé dans le passé à raison (i) des moyens de diviser une image alors que le traitement des blocs et (ii) « division inégale », comme mentionné par OP.

(i) moyens pour diviser/traiter une image:

1. Processus de non-chevauchement des blocs:

l'aide du paramètre par défaut { 'de BorderSize', [0 0]}, cette peut être manipulé avec blockproc comme ci-dessous.

Exemple pour (i) -1: Notez la nature bloquée de la sortie. Ici, chaque bloc non-chevauchant de taille 32 x 32 est utilisé pour calculer std2() et la valeur de sortie std2 est utilisée pour remplir ce bloc particulier. L'entrée et la sortie sont de taille 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'); 

image d'entrée et de sortie:

(i)-1 Example: Crop an image with non-overlapping blocks

(i) -2: Processus de blocs se chevauchent:

l'aide du paramètre {'BorderSize', [VH]}: des lignes V sont ajoutées au-dessus et au-dessous du bloc et des colonnes H sont ajoutées à gauche et à droite du bloc. Le bloc traité a (N + 2 * V) lignes et (M + 2 * H) colonnes. En utilisant le paramètre par défaut {'TrimBorder', true}, la bordure de la sortie est réduite à la taille de bloc d'entrée originale de N lignes et M colonnes.

Exemple pour (i) -2: Le code ci-dessous utilisant blockproc utilise {'BorderSize', [15 15]} avec [N M] = [1 1]. Ceci est similaire au filtrage de chaque pixel de l'image avec un noyau personnalisé. L'entrée de l'unité de traitement est donc un bloc de taille (1 + 2 * 15) lignes et (1 + 2 * 15) colonnes. Et puisque {'TrimBorder', true} par défaut, le bloc std2 du bloc de 31 lignes par 31 colonnes est fourni en sortie pour chaque pixel. La sortie est de taille 1 par 1 après la bordure de coupe. Par conséquent, notez que cet exemple de sortie est 'non-bloqué' contrairement à l'exemple précédent. Ce code prend beaucoup plus de temps pour traiter tous les pixels.

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'); 

d'entrée et de l'image de sortie:

Example of overlapping block processing

(ii) "division inégale":

1. Zéro/répétition/rembourrage symétrique:

Zéro remplissage de sorte qu'un multiple entier des blocs (N lignes par M cols size) peut couvrir la [image + zéros de délimitation] dans la dimension inégale. Cela peut être réalisé en utilisant le paramètre par défaut {'PadMethod', 0} avec {'PadPartialBlocks', true} (qui est faux par défaut). Si une zone englobante de zéros provoque une discontinuité élevée dans les valeurs calculées à partir des blocs englobants, {'PadMethod', 'replicate'} ou {'PadMethod', 'symmetric'} peuvent être utilisés.

2. Supposons une « région active » dans l'image pour le traitement des blocs

Pour le cas de traitement de chaque pixel, comme dans le cas (i) -2, on pourrait supposer une région de délimitation de sol (block_size/2) pixels sur tous les côtés le long de la périphérie de l'image qui est utilisée comme "Dummy" région. La région active pour le traitement de bloc est contenue dans la région Dummy. Quelque chose de similaire est utilisé dans les capteurs d'imagerie où les pixels fictifs situés à la périphérie d'une matrice d'imagerie de pixels actifs permettent une opération comme l'interpolation de couleur de tous les pixels de la zone active. Comme l'interpolation de couleur nécessite habituellement un masque de 5x5 pixels pour interpoler les valeurs de couleur d'un pixel, une périphérie fictive de 2 pixels peut être utilisée.

En supposant l'indexation MATLAB, la région (floor_size/2) + 1) à (Input_Image_Rows - floor (block_size)/2)) Rows by (floor (block_size/2) + 1) à (Input_ImageCols - floor (block_size)/2)) Les colonnes sont considérées comme des régions actives (en supposant un bloc carré de coté, block_size) qui subit un traitement de bloc pour chaque pixel comme dans (i) -2.

En supposant une taille de bloc carré de 5 par 5, ceci est représenté par ce qui suit:

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