2016-05-16 1 views
3

Я создал класс, который имитирует массив 3D bool, сохраняя данные в массиве 1D и перегружая () operator. Я уже пробовал каждый подход я мог бы найти и думать и в то время как, например, этот кусок кода:Цитирование через 3d-индексный массив 1d в C++

bool operator()(unsigned x, unsigned y, unsigned z) const { return _data[_zSize*_ySize*x + y*_ySize + z]; } 

позволяет мне получить доступ к каждому элементу мне нужно (я знаю, что (х, у, г) здесь фактически (z, y, x), но это не зависит от меня), я сталкиваюсь с проблемами, когда пытаюсь выполнить итерацию по массиву. Рассмотрим 3D-массив глубины: 3, высота: 4 и ширина 5, каждый элемент инициализируется значением false. Когда я пытаюсь перевернуть все значения в массиве (где sx() возвращает depth, sy() - height, sz() - width)

for (unsigned i = 0; i < x.sx(); ++i) 
     for (unsigned j = 0; j < x.sy(); ++j) 
      for (unsigned k = 0; k < x.sz(); ++k) 
       x(i, j, k) = !x(i, j, k); 

я получаю следующий результат (две остальные поверхности выглядеть одинаково):

11110 
01110 
01110 
01111 

Таким образом, очевидно, что некоторые элементы доступны и обращаются дважды. Шаблон меняется, когда я пытаюсь использовать различные методы индексирования массива. В чем проблема?

+2

'y * _ySize' должно быть, должно быть' y * _zSize' – Jarod42

ответ

4

Правильный оператор

bool operator()(unsigned x, unsigned y, unsigned z) const { 
    return _data[_zSize*_ySize*x + y*_zSize + z]; 
} 
1

позвольте мне дать обобщать подход с размером шага. Предположим, у вас есть 3D-массив, и доступ осуществляется в (х, у, х)

По этой индексации, я предполагаю, размеры матрицы, как Есть г количество плоскостей и Каждая плоскость имеет размер у, х , y ширина и y - высота.

Сначала нам нужно визуализировать трехмерную структуру и то, как мы собираемся получить доступ к элементу.

якобы мы тусклый, чтобы получить доступ (3,4,1)

Использование нулевого индексирование

Здесь г = 3, у = 4, х = 1, Наша Желаемая плоскость четвёртая плоскость, Наша Требуемая строка - 4-й, а обязательный элемент - 1-й.

Таким образом, для перехода на требуемую плоскость: г * (размер плоскости) = г * (ширина * высота)

Для перехода на нужную строку, у * sizeo рядных = у * (высота)// or y * row_bytes

Чтобы перейти к требуемой точке, просто добавьте x * sizeof (одна точка) // Определяется для многоканальных данных при наличии 3 или 4 значений на точку, например, в 3-канальных данных Opencv.

Таким образом, окончательное уравнение будет

Учитывая 3 Данные канала т.е. 3 значения на одну точку размером Uchar,

значение = Z * (ширина * высота) + у * (высота) + X * (3 * sizeof (uchar))

Таким образом, как только вы получите значение, вы не извлекаете каждое значение пикселя по одному.

PS: 3 * sizeof (uchar) заменена версия Vec3b, обычно используемая в OpenCV для доступа к данным 3-канального канала.

Смежные вопросы