copencviplimage

openCV grayscale / color addressing pixel


I have written a block matching algorithm in c++ using opencv for my thesis . It is working on grayscale pictures and addresses the IPLImage by his absolute pixeladress.

I have to devide the IPLImage in blocks of the same size (8x8 pxls). In order to access the pixel values within the blocks, I compute the pixeladress and access the pixel value in this way:

 for (int yBlock = 0; yBlock < maxYBlocks; yBlock++){
    for (int xBlock = 0; yxlock < maxXBlocks; xBlock++){
       for (int yPixel = 0; yPixel < 8; yPixel++){
          for (int xPixel = 0; xPixel < 8; xPixel++){

                pixelAdress = yBlock*imageWidth*8 + xBlock*8 + yPixel*imageWidth + xPixel;

                unsigned char* imagePointer = (unsigned char*)(img->imageData);
                pixelValue = imagePointer[pixelAdress];
    }
   }
  }
 }

I do NOT really itterate over rows and cols and it works great!

Now I have a colored IPLImage (no grayscale) and don't know how to access the r, g, b pixelvalues.

I found this on this forum

for( row = 0; row < img->height; row++ ){
    for ( col = 0; col < img->width; col++ ){
      b = (int)img->imageData[img->widthStep * row + col * 3];
      g = (int)img->imageData[img->widthStep * row + col * 3 + 1];
      r = (int)img->imageData[img->widthStep * row + col * 3 + 2];
}
}

but I'm not sure how to use it on my computed pixelAdress. Is it correct just to multiply it by 3 (because I do not iterate over rows and the add 0, 1 or 2? For example:

pixelValueR = imagePointer[pixelAdress*3 + 2]; 
pixelValueG = imagePointer[pixelAdress*3 + 1]; 
pixelValueB = imagePointer[pixelAdress*3 + 0]; 

or do I have to use widthStep where I used imageWidth before, like this:

pixelAdressR = pixelAdress = yBlock*img->widthStep*8 + xBlock*8*3 + yPixel*img->widthStep + xPixel*3 + 2;
pixelAdressG = pixelAdress = yBlock*img->widthStep*8 + xBlock*8*3 + yPixel*img->widthStep + xPixel*3 + 1;
pixelAdressB = pixelAdress = yBlock*img->widthStep*8 + xBlock*8*3 + yPixel*img->widthStep + xPixel*3;

and so access

pixelValueR = imagePointer[pixelAdressR];
pixelValueG = imagePointer[pixelAdressG];
pixelValueB = imagePointer[pixelAdressB];

Solution

  • not sure about your whole algorithm and can't test it at the moment, but for IplImages, the memory is aligned as this:

    1. row
    baseadress + 0 = b of [0]
    baseadress + 1 = g of [0]
    baseadress + 2 = r of [0]
    baseadress + 3 = b of [1]
    etc
    
    2. row
    baseadress + widthStep + 0 = b
    baseadress + widthStep + 1 = g
    baseadress + widthStep + 2 = r
    

    so if you have have n*m blocks of size 8x8 unsigned char bgr data and you want to loop over variables [x,y] in block [bx,by] you can do it like this:

    baseadress + (by*8+ y_in_block)*widthStep + (bx*8+x)*3 +0 = b
    baseadress + (by*8+ y_in_block)*widthStep + (bx*8+x)*3 +1 = g
    baseadress + (by*8+ y_in_block)*widthStep + (bx*8+x)*3 +2 = r
    

    since row by*8+y is adressbaseadress + (by*8+ y_in_block)*widthStep`

    and column bx*8+x is adress offset (bx*8+x)*3