简体   繁体   English

C ++,使用OpenCV的像素的负RGB值

[英]C++, Negative RGB values of pixels using OpenCV

I'm using OpenCV to iterate through an image and find the colour of each pixel, here's some of the code I'm using: 我正在使用OpenCV迭代图像并找到每个像素的颜色,这里是我正在使用的一些代码:

IplImage* img = cvLoadImage("c:\\test.png");

int pixels = img->height * img->width;
int channels = img->nChannels;

for (int i = 0; i < pixels*channels; i+= channels)
{

    unsigned char red = img->imageData[i + 2];
    unsigned char green = img->imageData[i + 1];
    unsigned char blue = img->imageData[i];

    outputRGBValues(red, green, blue);
    if (red == REDCOLOUR && green == GREENCOLOUR && blue == BLUECOLOUR)
    {
        count++;
    }
}
cvReleaseImage(&img);

When I run it, it outputRGBValues outputs negative values. 当我运行它时,outputRGBValues输出负值。 Most often R, G, B = -1, but occasionally other negative numbers and a handful of positive numbers. 最常见的是R,G,B = -1,但偶尔还有其他负数和少数正数。 I've heard something about uninitialized memory contents, and pixels not being allocated to the memory properly. 我听说过未初始化的内存内容,以及没有正确分配给内存的像素。 But I'm don't really understand it and definitely don't know how to fix it. 但我真的不明白它,绝对不知道如何解决它。 What am I doing wrong and how can I fix it? 我做错了什么,我该如何解决?

UPDATE UPDATE

After fixing the code (as above) with fschmitt's changes, I'm a bit closer. 在使用fschmitt的更改修复代码(如上所述)后,我更接近了。 This is the image I'm using, if it's any help. 是我正在使用的图像,如果有任何帮助的话。 Quite hard to see, but it's just a 5*3 'V' of black pixels with one green one at the bottom. 很难看,但它只是一个5 * 3'V'的黑色像素,底部有一个绿色像素。

Running the code on it, I get this output: 运行代码,我得到这个输出:

0 0 0
255 255 255
255 255 255
255 255 255
0 0 0
255 255 186
0 0 255
255 255 0
And it continues

The first 5 lines are fine, exactly what they should be. 前5行很好,正是它们应该是什么。 That's the top row of the image. 这是图像的第一行。 The next row, 6th line onwards is wrong. 下一行,第6行以后是错误的。 It should be: 它应该是:

255 255 255
255 255 255
0 0 0

I'm not sure what's causing this. 我不确定是什么原因引起的。 How can it work for the top line and not the second? 它如何适用于顶线而不是第二线? Is there some sort of mismatch, and its taking the value one bit to the left of where it should? 是否存在某种不匹配的问题,并且它的价值在左边的位置有一点?

Try this: 尝试这个:

IplImage* img = cvLoadImage("c:\\test.png");

for (int i = 0; i < img->height; i++)
{
    for (int j = 0; j < img->width; j += img->nChannels)
    {
        unsigned char red = img->imageData[i * img->widthStep + j + 2];
        unsigned char green = img->imageData[i * img->widthStep + j + 1];
        unsigned char blue = img->imageData[i * img->widthStep + j];

        outputRGBValues(red, green, blue);
        if (red == REDCOLOUR && green == GREENCOLOUR && blue == BLUECOLOUR)
        {
            count++;
        }
    }
}
cvReleaseImage(&img);

I don't understand why you are accessing pixel data blindly (by 1D index) while you already know the image dimension (proved by the usage of IplImage::height and IplImage::width ) and opencv does provide function to access pixel value ( cvGet*D ). 虽然您已经知道图像尺寸(通过使用IplImage::heightIplImage::width证明)并且opencv确实提供了访问像素值的功能,但我不明白为什么你盲目地访问像素数据(通过1D索引) cvGet*D )。

You are getting odd values in the direct pointer access because you did not factor in the byte padding performed by OpenCV . 您在直接指针访问中得到奇数值,因为您没有考虑OpenCV执行的字节填充 You may find in 8 bit images, (width*nChannels <= widthStep) for this reason. 出于这个原因,您可能会在8位图像中找到(width * nChannels <= widthStep)。

A quick revised code can be as follow: 快速修订的代码如下:

IplImage* img = cvLoadImage("c:\\test.png");
for(int iRow=0; iRow<img->height; ++iRow)
{
    for(int iCol=0; iCol<img->width; ++iCol)
    {
        CvScalar pixelVal = cvGet2D( img, iRow, iCol);
        unsigned char red = pixelVal.val[2];
        unsigned char green = pixelVal.val[1];
        unsigned char blue = pixelVal.val[0];

        outputRGBValues(red, green, blue);
        if (red == REDCOLOUR && green == GREENCOLOUR && blue == BLUECOLOUR)
        {
            count++;
        }
    }
}
cvReleaseImage(&img);

Also, note that usually OpenCV arrange data in BGR format, which can verified at IplImage::channelSeq . 另外,请注意,OpenCV通常以BGR格式排列数据,可以在IplImage::channelSeq验证。 Do not confused by IplImage::colorModel , which tells the color model. 不要混淆IplImage::colorModel ,它告诉颜色模型。

I'll go with Paul R suggestion that you should find a reference and understand the library before attempting to use them. 我将与Paul R建议您在尝试使用它们之前找到参考并理解库。

我从来没有使用过OpenCV,但我认为cvCreateImage不会初始化图像的内容,当然也不会有任何意义。

Quite some issues here: 这里有一些问题:

  • You need to fill the image with meaningful data 您需要使用有意义的数据填充图像
  • Depending on how the image was constructed, you may have swapped red and blue 根据图像的构造方式,您可能已经交换了红色和蓝色
  • You should use unsigned char red 你应该使用unsigned char red
  • You declare a vector for each pixel and don't use it 您为每个像素声明一个向量,不要使用它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM