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

在您的代码中,您没有考虑由于对齐而可能出现的数据间隙。它被称为步进。你可以在这里阅读大量有用的信息:

垫::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 回答