Получение срезов самолета из данных массива - PullRequest
1 голос
/ 09 июня 2010

Привет всем,

Я читаю данные трехмерной сетки (из нескольких изображений TIF) в структуру следующим образом:

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

Теперь я хочу получить срезы плоскости из этой 1-Данные сетки D:

например:

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

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

Но мне трудно реализовать по другим осям:

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

и

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

Есть ли простой алгоритм для этого?заранее спасибо.

Ответы [ 3 ]

1 голос
/ 09 июня 2010

Это невозможно с указанным вами типом возврата.

Я объясню.

В первой функции вы возвращаете указатель, а вызывающая сторона ожидает адрес непрерывно упакованных данных.,Это нормально, потому что исходная структура поддерживает это.

Для второй функции, если вы хотите вернуть адрес непрерывно упакованной плоскости, вам придется выполнить [1] переупорядочение, то есть скопировать его в другое место[2] выделение памяти из-за копирования в другом месте и [3] освобождение памяти из-за выделения, выполненного в 2.

Если копирование приемлемо с точки зрения производительности, лучшим подходом является использованиеумные объекты, которые будут обрабатывать работу для вас.STL :: vector, вероятно, лучший.

Если у вас очень большие объемы данных или производительность, то вам придется разработать другой подход без копирования данных.Вам придется реализовать пользовательские индексаторы, то есть избегать запрашиваемого преобразования.

1 голос
/ 09 июня 2010

2-я и 3-я функции повторяют выборку вашего набора данных (они в основном выражают ваше изображение в новой ссылке)

Таким образом, они должны реорганизовать данные:

  1. Создайте новый массив размером ny*nz для YZ и nx*nz для XZ
  2. Заполнить массив данными, лежащими в заданной плоскости
  3. Возвращает указатель на вновь выделенный массив

(В этом случае вызывающая сторона отвечает за освобождение вновь выделенной памяти.)

Ваш алгоритм для плоскости YZ:

// 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;
}
1 голос
/ 09 июня 2010

C массивы всегда последовательны в памяти. То, что вы ищете, похоже, потребует более сложных отношений между адресами последующих элементов, чем просто добавление размера элемента.

Я думаю, что вам придется либо дополнительно абстрагировать его, чтобы получить функцию (getAt() или что-то) для вызова индекса в массиве, либо динамически создавать новые фрагменты и копировать данные между ними

...