0

大きなグレースケール イメージをカラーに変換するときに、ポインタ オフセットに問題があるようです。24,000 x 27,000 グレースケール イメージを Direct2D 用の 32 ビット RGB イメージに変換しています (D2D の要件)。

画像のハイライトを行っていますが、カスタム パレットを使用して自動的に行う方法が実際には見つからなかったので、すべてのピクセル値をループして 32 ビット画像に手動で設定しました。小さい画像では問題なく動作しますが、上記で説明したように大きい画像を使用しようとするとクラッシュします。

以下はコードスニペットです。

    CvMat* dst = cvCreateMat(height, width, CV_8UC4);

    #pragma omp parallel num_threads(nThreads)
    {
        #pragma omp for
        for( int Y = 0; Y < height; Y++ )
        {
            for( int X = 0; X < width; X++ ) 
            {
                size_t nOffset = X + Y * width;
                size_t nOffsetRGB = (X  +  Y * width) * 4;

                switch( pPixelData[nOffset] )
                {
                    case 0: //red
                    {
                        dst->data.ptr[nOffsetRGB] = 0;
                        dst->data.ptr[nOffsetRGB + 1] = 0;
                        dst->data.ptr[nOffsetRGB + 2] = 255;
                        //pDestination[nOffsetRGB + 3] = 255; //alpha opacity %
                        break;
                    }
                    default: //GrayScale
                    {
                        dst->data.ptr[nOffsetRGB] = pPixelData[nOffset];
                        dst->data.ptr[nOffsetRGB + 1] = pPixelData[nOffset];
                        dst->data.ptr[nOffsetRGB + 2] = pPixelData[nOffset];
                        //pDestination[nOffsetRGB + 3] = 255; //pSource[nOffset]; //alpha %
                        break;
                    }
                }

            } //next X
        } //next Y
    }

このコードは最終的にメモリへのアクセスに関するエラーでクラッシュしますが、グレースケール画像が良好で、十分なメモリ (16GB) があることを確認したので、これは不可能だと思います。少し小さい画像でも問題なく機能します。

ここで私が間違っている可能性があることは何か、プログラムを64ビットに変換するのはこれが初めてなので、何かが欠けている可能性があります。

ありがとう!

4

1 に答える 1

0

コードでは、配置によって発生する可能性のあるデータのギャップを考慮していません。ステッピングといいます。ここで、それに関する多くの有用な情報を読むことができます:

Mat::isContinuous()

これがエラーの原因であるかどうかはわかりませんが、ポインターによる行列要素へのアクセスはエラーが発生しやすいため、回避することをお勧めします。

OpenCV C++ API は、安全なデータ アクセスの優れた効率的な方法をいくつか提供します。あなたの場合、最もクリーンで読みやすい方法は、反復子を使用することです。このために、明示的に型指定された行列を使用します。サンプルコードは次のとおりです。

cv::Mat1b src = …
cv::Mat4b dest(src.rows, src.cols);
cv::Mat1b::const_iterator its = src.begin();
cv::Mat4b::iterator itd = dest.begin();
for (; its != src.end(); ++its, ++itd)
{
    uchar s = *its;
    cv::Vec4b &d = *itd;
    d[0] = s; d[1] = s; d[2] = s;
}

注:これを機能させるには、最新の OpenCV バージョンが必要です。

OpenCV 2.1 には非常にバグがあります。2.3 未満のものは使用しないでください。

于 2012-12-03T13:39:02.743 に答える