C ++ AMP使用16位图像上的纹理计算渐变

时间:2014-04-27 21:29:09

标签: c++ opencv c++11 gradient c++-amp

我正在处理从kinect中检索到的16位深度图像。由于索引或图像的大小,我发现制作自己的滤镜时遇到了一些困难。 我正在使用Textures,因为它允许使用任何大小的图像。

所以,我正在尝试计算一个简单的渐变来理解错误或为什么它没有像我预期的那样工作。

当我使用y目录时,您可以看到出现了问题。

对于x:

对于y:

那是我的代码:

typedef concurrency::graphics::texture<unsigned int, 2> TextureData;
typedef concurrency::graphics::texture_view<unsigned int, 2> Texture

cv::Mat image = cv::imread("Depth247.tiff", CV_LOAD_IMAGE_ANYDEPTH);

//just a copy from another image
cv::Mat image2(image.clone() );


concurrency::extent<2> imageSize(640, 480);
int bits = 16;

const unsigned int nBytes = imageSize.size() * 2; // 614400


{
    uchar* data = image.data;

    // Result data
    TextureData texDataD(imageSize, bits);
    Texture texR(texDataD);


    parallel_for_each(
        imageSize,
        [=](concurrency::index<2> idx) restrict(amp)
    {
        int x = idx[0];
        int y = idx[1];

        // 65535 is the maxium value that can take a pixel with 16 bits (2^16 - 1)
        int valX = (x / (float)imageSize[0]) * 65535;
        int valY = (y / (float)imageSize[1]) * 65535;

        texR.set(idx, valX);
    });
    //concurrency::graphics::copy(texR, image2.data, imageSize.size() *(bits / 8u));
    concurrency::graphics::copy_async(texR, image2.data, imageSize.size() *(bits) );

    cv::imshow("result", image2);
    cv::waitKey(50);
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

您的索引在两个地方交换。

int x = idx[0];
int y = idx[1];

请记住,C ++ AMP使用row-major indices for arrays。因此idx[0]指的是行,y轴。这就是为什么你需要的图片&#34;对于x&#34;看起来像texR.set(idx, valY)所期望的那样。

同样,图像的范围也使用交换值。

int valX = (x / (float)imageSize[0]) * 65535;
int valY = (y / (float)imageSize[1]) * 65535;

此处imageSize[0]指的是列数(y值)而不是行数。

我不熟悉OpenCV,但我假设它还使用cv::Mat的行主格式。它可能会将y轴反转为0,0左上角而非左下角。 Kinect数据可能会做类似的事情,但同样,它是行主要的。

您的代码中可能还有其他地方存在同样的问题,但我认为如果您仔细检查使用indexextent的方式,则应该可以解决此问题。