2010-06-09 8 views
1

Salutations tous,Obtenir des tranches d'avion à partir des données du tableau

je lis les données de la grille 3D (à partir de plusieurs images TIF) dans une structure comme suit:

typedef struct VolumeData{ 
int nx; 
int ny; 
int nz; 
unsigned char *data; // size is nx*ny*nz 
} 

Maintenant, je veux obtenir les tranches d'avion de cette 1-D des données de la grille:

par exemple:

unsigned char* getXYPlaneStack(VolumeData *vol,int z); 

I could implement above function because the *data array stores image stack. 

Mais j'ai du mal à mettre en œuvre une les autres axes longs:

unsigned char* getYZPlaneStack(VolumeData *vol,int x); 

et

unsigned char* getXZPlaneStack(VolumeData *vol,int y); 

tout algorithme simple pour cela? merci d'avance.

Répondre

1

Les 2ème et 3ème fonctions rééchantillonnent votre ensemble de données (elles expriment essentiellement votre image dans un nouveau référentiel).

Ils doivent réorganiser les données:

  1. Créer un nouveau tableau de taille ny*nz pour YZ et nx*nz pour XZ
  2. Remplissez le tableau avec les données de pose dans le même plan
  3. Retour le pointeur le tableau nouvellement attribué

(Dans ce scénario, l'appelant est responsable de désaffecter la mémoire nouvellement allouée.)

Votre algorithme pour le plan YZ est:

// I assume this sorting order: 
//  Z^  Slices are 
//  /   stacked along 
//  /   the Z axis 
//  +-------> X 
//  | 
//  | 
// Y v 

// Assumes your data is stored in row major order: 
//   +-------> X  +---------> X 
// slice 0: | 0 1 2 | slice 1: | 6 7 8 | etc. 
//   | 3 4 5 |   | 9 10 11 | 
//  Y v    Y v 
// Assumes x is the column index, y the row index, z the slice index. 
// For example, you want element #9: 
// - col 0 -> x = 0 
// - row 1 -> y = 1 
// - slice 1 -> z = 1 
// I suggest you rename nx, ny, nz into nbCols, nbRows, nbSlices to make 
// things explicit 
index computeIndex(VolumeData *vol, int x, int y, int z) 
{ 
    int nx = vol->nx, // nb cols 
     ny = vol->ny, // nb rows 
     nz = vol->nz; // nb slices 
    int index = nx*ny*z // size of one slice, multiplied by slice index 
       + nx*y // size of one row (nb cols), multiplied by row index 
       + x;  // offset in row (column index) 
    return index; 
} 

unsigned char* getYZPlaneStack(VolumeData *vol,int x) 
{ 
    int nx = vol->nx, // nb rows 
     ny = vol->ny, // nb columns 
     nz = vol->nz; // nb slices 
    unsigned char *newData = new unsigned char[ny*nz]; 
    // Depth is now along the X axis 
    // +-----> Z 
    // | 
    // | 
    // Y v 
    for(int y = 0; y < ny; ++y)  // For each row 
     for(int z = 0; z < nz; ++z) // For each column 
     { 
      int i = computeIndex(vol, x, y, z); 
      newData[nz*y+z] = vol->data[i]; 
     } 
    return newData; 
} 
+0

Merci beaucoup! juste ce que je voulais –

1

Les tableaux sont toujours séquentiels en mémoire. Qu'est-ce que vous recherchez semble qu'il faudrait une relation plus compliquée entre l'adresse des éléments suivants, que d'ajouter simplement la taille de l'élément.

Je pense que vous devrez soit l'abstraire davantage, afin d'obtenir une fonction (getAt() ou quelque chose) à appeler pour indexer dans le tableau, ou créer dynamiquement de nouvelles tranches et copier les données.

1

Ceci n'est pas possible avec le type de retour que vous avez mentionné.

Je vais vous expliquer.

Dans la première fonction, vous renvoyez un pointeur et l'appelant attend l'adresse des données en continu. C'est correct, parce que la structure originale le supporte. Pour la deuxième fonction, si vous voulez renvoyer l'adresse du plan compressé en continu, vous devrez faire [1] réordonner, c'est-à-dire le copier ailleurs [2] en allouant la mémoire, à cause de la copie ailleurs, et [3] libérer la mémoire, en raison de l'attribution faite dans 2.

Si la copie est acceptable du point de vue des performances, la meilleure approche consiste à utiliser des objets intelligents qui géreront le travail pour vous. Std :: vector de STL est probablement le meilleur.

Si vous avez des données ou des performances très importantes, alors vous devrez concevoir une approche différente sans copier les données. Vous devez implémenter des indexeurs personnalisés, c'est-à-dire éviter la transformation que vous demandez.

Questions connexes