Accessing Image Pixel

Image pixel access uses traditional C array element access. Pixel neighbour access uses predefined arrays indexed by conventional Freeman encoding.

Accessing Image Pixel

The declaration of image dimension uses the following conventional order:

Thus, access to a image pixel follows the same convention:

value=ims[row][column]; for 2D image
value=ims[depth][row][column]; for 3D image

For example:

Img3duc image1(64,128,256); // 64 slices, 128 rows and 256 columns 
Img2duc *image2 = new Img2duc(128,256); // 128 rows and 256 columns
int z=12,y=11,x=10;

image1[z][y][x]=12;
(*image2)[y][x]=12;

Accessing Neighbour Pixels

The Freeman encoding assigns a code (an integer) to each immediate neighbour of a pixel (or a voxel in 3D). The encoding depends on the dimension (2D or 3D) and on the connexity (4 or 8 for 2D; 6 or 26 for 3D).

Freeman Encoding for 2D Image

Convention

For 2D, the encoding is given as follows:
fig1.gif

The Freeman encoding for 2D for 4-connexity and 8-connexity.

This encoding guaranties two properties:

  1. Pixels vi for i in [0;1] in 4-connexity (resp. [0;3] in 8-connexity) are visited before the central pixel and pixels vi for i in [2;3] (resp. [4;7]) are visited after.
  2. In 4-connexity, pixel vi and pixel v2+i are symmetrical (resp. vi and v4+i in 8-connexity).

Using Predefined Arrays

Access to a specified neighbour is done by using predefined arrays.

The four arrays v4x[ ], v4y[ ] and v8x[ ], v8y[ ] indicate the x and y shifts to operate from the central pixel to access a given neighbour in 4 and 8 connexity respectively:

int shiftx, shifty;
for (v=0;v<4;v++) { shiftx=v4x[v]+x; shifty=v4y[v]+y; } // In 4-connexity
for (v=0;v<8;v++) { shiftx=v8x[v]+x; shifty=v8y[v]+y; } // In 8-connexity
For example, to perform a mean filter (set the central pixel with the mean of its neighbours), use:
Long x,y;
for (int y=1;y<ims.Height()-1;y++)
   for (int x=1;x<ims.Width()-1;x++) {
        float sum=0.0F;
        for (int v=0;v<8;v++)
                sum+=ims[y+v8y[v]][x+v8x[v]];
        ims[y][x]=sum/8;
   }

The two arrays v4[ ] and v8[ ] give the shifts as a 2D point for 4 and 8 connexity respectively:

Point2d shiftp, p(10,10);
for (v=0;v<4;v++) { shiftp=v4[v]+p; } // In 4-connexity.
for (v=0;v<8;v++) { shiftp=v8[v]+p; } // In 8-connexity.
For example, to perform a mean filter (set the central pixel with the mean of its neighbours), use:
Point2d p;
for (int p.y=1;p.y<ims.Height()-1;p.y++)
   for (int p.x=1;p.x<ims.Width()-1;p.x++) {
        float sum=0.0F;
        for (int v=0;v<8;v++)
                sum+=ims[p+v8[v]]];
        ims[p]=sum/8;
   }

Freeman Encoding for 3D Image

Convention

For 3D, the encoding is given as follows:

fig2.gif

The Freeman encoding for 3D for 6-connexity and 26-connexity.

This encoding guaranties two properties:

  1. Voxels vi for i in [0;2] in 6-connexity (resp. [0;12] in 26-connexity) are visited before the central pixel and voxels vi for i in [3;5] (resp. [13;25]) are visited after.
  2. In 6-connexity, voxel vi and voxel v3+i are symmetrical (resp. vi and v13+i in 26-connexity).

Using Predefined Arrays

Access to a specified neighbours is done by using predefined arrays.

The six arrays v6x[ ], v6y[ ], v6z[ ] and v26x[ ], v26y[ ], v26z[ ] indicate the x, y and z shifts to operate from the central pixel to access a given neighbour in 6 and 26 connexity respectively:

int shiftx, shifty, shiftz;
for (v=0;v<6;v++) { shiftx=v6x[v]+x; shifty=v6y[v]+y; shiftz=v6z[v]+z }
for (v=0;v<26;v++) { shiftx=v26x[v]+x; shifty=v26y[v]+y; shiftz=v6z[v]+z }
For example, to perform a mean filter (set the central pixel with the mean of its neighbours), use:
Long x,y,z;
for (int z=1;z<ims.Depth()-1;z++)
   for (int y=1;y<ims.Height()-1;y++)
        for (int x=1;x<ims.Width()-1;x++) {
            float sum=0.0F;
            for (int v=0;v<26;v++)
                sum+=ims[z+v26z[v]][y+v26y[v]][x+v26x[v]];
            ims[z][y][x]=sum/26;
       }

The two arrays v6[ ] and v26[ ] give the shifts as a 3D point for 6 and 26 connexity respectively:

Point3d shift,p(10,10,10);
for (v=0;v<6;v++) { shift=v6[v]+p; }
for (v=0;v<26;v++) { shift=v26[v]+p; }
For example, to perform a mean filter (set the central pixel with the mean of its neighbours), use:
Point2d p;
for (int p.z=1; p.z<ims.Depth()-1; p.z++)
   for (int p.y=1; p.y<ims.Height()-1; p.y++)
        for (int p.x=1; p.x<ims.Width()-1; p.x++) {
            float sum=0.0F;
            for (int v=0;v<26;v++)
                sum+=ims[p+v26[v]];
            ims[p]=sum/26;
       }

Generalized Access

Arrays prefixed by vc allow generalized access to a specified neighbour from a given connexity:

For example:

Point2d shiftp,p(10,10); int conx=4;
int shiftx, shifty;
for (v=0;v<conx;v++) { shiftp=((Point2d*)vc[conx])[v]+p; }
for (v=0;v<conx;v++) { shiftx=vcx[conx][v]+p.x; shifty=vcy[conx][v]+p.y; }

The Pantheon project
Image Team GREYC Laboratory
UMR CNRS 6072 - ENSICAEN - University of Caen, France
This page was last modified on 19 June 2015