I have created a class which imitates a 3D bool array by storing data in 1D array and overloading the () operator. I have already tried every approach I could find and think of and while, for example, this piece of code:
bool operator()(unsigned x, unsigned y, unsigned z) const { return _data[_zSize*_ySize*x + y*_ySize + z]; }
allows me to access every element I need (I am aware that (x,y,z) is here actually (z,y,x) but it's not up to me), I run into problems when I try to iterate through the array.
Consider a 3D array of depth: 3, height: 4 and width 5 with every element initialized to false. When I try to invert all the values in the array (where sx() returns 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);
I get the following result (two remaining surfaces look the same):
11110
01110
01110
01111
So, obviously some elements are accessed and reversed twice. The pattern changes when I try different methods of indexing the array. What is the problem?
The correct operator is
bool operator()(unsigned x, unsigned y, unsigned z) const {
return _data[_zSize*_ySize*x + y*_zSize + z];
}
let me give a generalize approach with step size. Suppose you have a 3D array ,and accessing is done in (z,y,x)
By this indexing , i assume , Matrix dimensions as There are z number of Planes and Each plane is of size y,x , y width and y is height.
We first need to visualize the 3D structure and how we are going to access the element.
supposedly we wan to access ( 3,4,1)
Using zero based indexing
Here We z = 3 , y = 4 , x = 1 , Our Required Plane is 4th Plane , Our Required Row is 4th and Required Element is 1st .
Thus to go to the Required Plane : z * ( size of Plane ) = z * ( width * height )
To go to the Required Row , y * sizeo of Row = y * ( height) //or y * row_bytes
To go the Required Point , Just add x * sizeof( one Point) //Specific to multichannel data when there are 3 or 4 values per point e.g in Opencv 3 channel data.
Thus Final Equation will be
Considering 3 Channel Data ie 3 values per point of size uchar,
Value = z * (width * height) + y * ( height ) + x * (3 * sizeof(uchar) )
Thus once you get the Value , no you extract each pixel value one by one.
PS : 3 * sizeof(uchar) is replaced version of Vec3b used commonly in OpenCV to access 3 Channel uchar data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With