openCV灰度/颜色寻址像素

时间:2014-03-04 14:27:14

标签: c opencv iplimage

在我的论文中,我使用opencv在c ++中编写了一个块匹配算法。 它正在制作灰度图片,并通过他的绝对像素来处理IPLImage。

我必须在相同大小的块(8x8 pxls)中分配IPLImage。为了访问块内的像素值,我计算像素值并以这种方式访问​​像素值:

 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];
    }
   }
  }
 }

我真的没有对行和列进行迭代,而且效果很好!

现在我有一个彩色的IPLImage(没有灰度),也不知道如何访问r,g,b像素值。

我在这个论坛上发现了这个

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];
}
}

但我不确定如何在我的计算像素上使用它。将它乘以3是否正确(因为我不迭代行并添加0,1或2?例如:

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

或者我必须使用之前使用过imageWidth的widthStep,如下所示:

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;

所以访问

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

3 个答案:

答案 0 :(得分:1)

如果是多频道Mat(本例中为BGR),您可以使用,如here所述

来访问单个像素
Vec3b intensity = img.at<Vec3b>(y, x);
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];

答案 1 :(得分:0)

  1. 适用于Mat(例如Mat img

    • 灰度(8UC1):

      uchar intensity = img.at<uchar>(y, x);
      
    • 彩色图像(BGR颜色排序,imread返回的默认格式):

      Vec3b intensity = img.at<Vec3b>(y, x);
      uchar blue = intensity.val[0];
      uchar green = intensity.val[1];
      uchar red = intensity.val[2];
      
  2. 适用于IplImage(例如IplImage* img

    • 灰度:

      uchar intensity = CV_IMAGE_ELEM(img, uchar, h, w);
      
    • 彩色图片:

      uchar blue = CV_IMAGE_ELEM(img, uchar, y, x*3);
      uchar green = CV_IMAGE_ELEM(img, uchar, y, x*3+1);
      uchar red = CV_IMAGE_ELEM(img, uchar, y, x*3+2);
      

答案 2 :(得分:0)

不确定您的整个算法,目前无法对其进行测试,但对于IplImages,内存对齐如下:

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

所以如果你有n*m个大小为8x8的无符号字符bgr数据块,并且想要在块[x,y]中循环变量[bx,by],你就可以这样做:

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

因为行by*8+y is adress baseadress +(* * 8 + y_in_block)* widthStep`

和列bx*8+x是地址偏移(bx*8+x)*3