3

私は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);

実行すると、outputRGBValuesは負の値を出力します。ほとんどの場合、R、G、B = -1ですが、他の負の数と少数の正の数の場合もあります。初期化されていないメモリの内容、およびピクセルがメモリに適切に割り当てられていないことについて何か聞いたことがあります。しかし、私はそれを本当に理解しておらず、間違いなくそれを修正する方法を知りません。何が間違っているので、どうすれば修正できますか?

アップデート

fschmittの変更で(上記のように)コードを修正した後、私は少し近づきました。 これは私が使用している画像です。非常に見づらいですが、これは5 * 3'V'の黒いピクセルで、下部に1つの緑色のピクセルがあります。

その上でコードを実行すると、次の出力が得られます。

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

最初の5行は問題なく、正確に本来あるべき姿です。これが画像の一番上の行です。次の行、6行目以降は間違っています。そのはず:

255 255 255
255 255 255
0 0 0

何が原因なのかわかりません。2番目ではなくトップラインでどのように機能しますか?ある種の不一致があり、その値は本来あるべき場所の1ビット左にありますか?

4

4 に答える 4

4

これを試して:

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);
于 2010-10-04T22:10:22.773 に答える
2

IplImage::height画像の寸法(との使用法によって証明される)をすでに知っていてIplImage::width、opencvがピクセル値にアクセスする機能を提供しているのに(1Dインデックスによって)ピクセルデータに盲目的にアクセスしている理由がわかりません( cvGet*D)。

OpenCVによって実行されるバイトパディングを考慮しなかったため、直接ポインターアクセスで奇数の値を取得しています。このため、8ビット画像(width * nChannels <= widthStep)で見つかる場合があります。

簡単に改訂されたコードは次のようになります。

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);

また、通常、OpenCVはデータをBGR形式で配置することに注意してください。これは、で確認できますIplImage::channelSeqカラーモデルを示す、と混同しないでください。IplImage::colorModel

それらを使用する前に、リファレンスを見つけてライブラリを理解する必要があるというPaulRの提案に賛成します。

于 2010-10-05T05:43:41.333 に答える
1

私はOpenCVを使ったことがcvCreateImageありませんが、それは画像の内容を初期化せず、確かに意味のあるものではないと思います。

于 2010-10-04T21:25:29.620 に答える
1

ここでかなりの問題があります:

  • 画像に意味のあるデータを入力する必要があります
  • 画像の作成方法によっては、赤と青を入れ替えた可能性があります
  • unsignedcharredを使用する必要があります
  • ピクセルごとにベクトルを宣言し、使用しないでください
于 2010-10-04T21:29:55.633 に答える