检查大图像的像素值(指针偏移量大到64位?)

时间:2012-12-03 01:45:01

标签: image pointers opencv processing offset

在将大灰度图像转换为颜色时,我似乎遇到了指针偏移问题。我正在将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位,所以我可能会遗漏一些东西。

谢谢!

1 个答案:

答案 0 :(得分: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的任何东西。