2010-04-20 2 views
2

Qu'est-ce qu'une manière rapide et élégante d'utiliser MatLab pour former un sous-réseau autour d'un élément particulier? Les éléments sont sélectionnés aléatoirement à partir des données, de sorte que vous ne pouvez pas prendre un sous-réseau de la manière normale (il doit être généralisé pour les éléments sélectionnés). Ce que je veux dire est, formant un tableau par exemple 5x5 ou 7x7 ou quelque chose, où l'élément du milieu est celui que vous voulez.Méthode générale de création de sous-réseaux autour d'un élément particulier


Merci, mais je veux dire une approche plus générale. Excusez-moi de ne pas avoir été clair. Ce que je veux dire quelque chose comme, disons que

a = magic(10)   
b = find(a<8) %giving linear indices  
m = size(a)  
[r,c] = ind2sub(m,b) %giving rows and columns of the elements that you later want to select 

puis je pensais à faire le reste à l'aide pour les boucles, mais ne suis pas vraiment sûr de savoir comment généraliser et je me demandais, comme je l'ai dit, s'il y a un moyen plus facile de le faire en utilisant MatLab. La raison d'une telle approche générale est que je veux analyser n'importe quel tableau pour des éléments avec certaines propriétés et ensuite être capable de former un sous-tableau autour de chaque élément pour zoomer dessus pour d'autres analyses de données si cela a du sens.

Répondre

1

Voici quelques exemples de la façon dont vous pouvez aborder ce problème:

mat = rand(10); %# A 10-by-10 array of random elements 

vec = -3:3;  %# To make a 7-by-7 subarray 
subArray = mat(5+vec,4+vec); %# Get subarray centered on element (5,4) 

vec = -2:2;  %# To make a 5-by-5 subarray 
subArray = mat(3+vec,3+vec); %# Get subarray centered on element (3,3) 

Bien sûr, vous aurez à se méfier des conditions où vos indices vont au-delà des limites de la matrice que vous indexez et Décidez alors comment vous voulez traiter une telle situation (c'est-à-dire renvoyer seulement la partie du sous-tableau qui se trouve dans la matrice plus grande, ou tamponner les bords de la matrice plus grande en utilisant PADARRAY pour éviter une telle situation, etc.).

EDIT:

Généraliser ci-dessus pour des ensembles de points que vous souhaitez obtenir autour de sous-zones, the solutions given by Jonas devrait bien fonctionner. Le seul inconvénient est que vous auriez besoin d'avoir accès au Image Processing Toolbox. Voici une solution qui fonctionnera sans boîtes à outils supplémentaires, en utilisant a, r et c que vous les avez définis dans la question:

blockSize = 3;        %# Block size around each point 
padSize = floor(blockSize/2);    %# Padding size for the matrix 
aPad = padarray(a,[padSize padSize],NaN); %# Pad the matrix with NaNs 
rPad = r+padSize;       %# Shift the row indices 
cPad = c+padSize;       %# Shift the column indices 
blockIndices = (1:blockSize)-ceil(blockSize/2); %# Create indices for a block 
getBlockFcn = @(r,c) aPad(r+blockIndices,c+blockIndices); %# Function to get 
                  %# a block 
subArrays = arrayfun(getBlockFcn,rPad,cPad,... %# Create a cell array with 
        'UniformOutput',false); %# one block per cell 

Cela vous donnera un réseau de cellules N par 1 subArrays, où N est le nombre de points que vous avez. Si, par exemple, vous voulez obtenir la valeur maximale du sous-tableau pour le point 3, vous pouvez effectuer les opérations suivantes:

maxValue = max(subArrays{3}(:)); %# MAX will ignore NaN values 

Pour prendre une moyenne de l'ensemble du sous-tableau, vous devez soit supprimer NaN premier (en utilisant la fonction ISNAN), ou utiliser la fonction NANMEAN du Statistics Toolbox:

mat = subArray{3}(:);    %# Values from subarray 
meanValue = mean(mat(~isnan(mat))); %# Mean of non-NaN values 
%# Or... 
meanValue = nanmean(subArrays{3}(:)); %# Mean of non-NaN values 
1

Si vous voulez rassembler l'individu (qui peuvent se chevaucher) les quartiers dans un tableau afin que vous pouvez traiter chaque quartier individuellement, vous pouvez utiliser IM2COL . Si vous souhaitez créer un "halo" autour de chaque élément pour capturer facilement toutes les régions candidates, afin que les chevauchements ne soient pas comptés deux fois, vous pouvez utiliser IMDILATE.

Exemple im2col

%# create array and get linear index of interesting elements 
a = magic(10); 
b = find(a<8); 

%# define region size 
subSz = 3; %# for 3x3 array 
halfSz = floor(subSz/2); %# for a 3x3 array, there window extends 1 pix to each side 

%# pad a with NaNs so that sub-window never goes outside the image 
ap = padarray(a,[halfSz halfSz],NaN); 

%# convert ap to columns - there are 9 rows (for 3x3 window) and as many columns as there 
%# are elements in a (100 in this example) 
apCol = im2col(ap,[subSz,subSz]); 

%# select columns of interest 
%# the first column contains the first neighborhood of interest, the second column 
%# the second neighborhood etc. 
interestingColumns = apCol(:,b); 

%# take e.g. the average of each neighborhood 
avg = nanmean(interestingColumns,1); 

Exemple imdilate

%# create array and get logical mask where 1 indicates an interesting element 
a = magic(10); 
bw = (a<8); 

%# define region size 
subSz = 3; %# for 3x3 array 

%# grow each element, so that a single 'good' pixel is in the center of a 3x3 mask 
bwDil = imdilate(bw,strel('square',subSz)); 

%# show the centers in white, 'halo' in grey 
%# note the overlaps 
figure,imshow(bw+bwDil,[]) 

%# take the average of all 'labeled' pixels 
avg = mean(a(bwDil)); 
+0

+1: Nice solutions. La seule limitation est la nécessité pour l'Image Processing Toolbox d'utiliser les fonctions IM2COL et IMDILATE. – gnovice

+0

En ce qui concerne la première solution, je pense que vous avez oublié d'ajuster les indices 'b' pour prendre en compte le remplissage ajouté à la matrice. – gnovice

+1

Je ne pense pas. im2col avec la fenêtre glissante par défaut donne les colonnes (nRowArray-nRowWindow + 1) * (nColArray-nColWindow + 1). Si vous utilisez la moitié de la taille de la fenêtre, vous obtenez exactement les sous-fenêtres nRowArray * nColArray. Ainsi, vous indexez directement avec b. – Jonas

Questions connexes