本文介绍了C ++ AMP使用16位图像上的纹理计算梯度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用从kinect检索的16位深度图像。我发现一些困难,使我自己的过滤器,由于索引或图像的大小。
我使用纹理,因为允许使用任何位大小的图像。



所以,我试图计算一个简单的渐变,以了解什么是错误


$ b

您可以看到当我使用y dir时有错误。



对于x:



对于y:



这是我的代码:

  typedef concurrency :: graphics :: texture< unsigned int,2> ;纹理数据; 
typedef concurrency :: graphics :: texture_view< unsigned int,2>纹理

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

//只是从另一个图像复制
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;

//结果数据
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是可以取16位像素的最大值(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);
}

任何帮助将非常感激。



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

请记住,C ++ AMP使用。因此 idx [0] 是指行,y轴。这是为什么你为For x的图片看起来像我期望的 texR.set(idx,valY)



类似地,图像的范围也使用交换值。

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

这里 imageSize [0] 列数(y值)而不是行数。



我不熟悉OpenCV,但我假设它也使用行主格式 cv :: Mat 。它可能会反转 y 轴,0,0顶部左上角不是左下角。



在你的代码中可能有其他地方有相同的问题,但我想如果你仔细检查如何您正在使用 index extent ,您应该能够解决这个问题。


I am working with depth images retrieved from kinect which are 16 bits. I found some difficulties on making my own filters due to the index or the size of the images.I am working with Textures because allows to work with any bit size of images.

So, I am trying to compute an easy gradient to understand what is wrong or why it doesn't work as I expected.

You can see that there is something wrong when I use y dir.

For x:

For y:

That's my code:

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

Any help will be very appreciated.

解决方案

Your indexes are swapped in two places.

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

Remember that C++AMP uses row-major indices for arrays. Thus idx[0] refers to row, y axis. This is why the picture you have for "For x" looks like what I would expect for texR.set(idx, valY).

Similarly the extent of image is also using swapped values.

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

Here imageSize[0] refers to the number of columns (the y value) not the number of rows.

I'm not familiar with OpenCV but I'm assuming that it also uses a row major format for cv::Mat. It might invert the y axis with 0, 0 top-left not bottom-left. The Kinect data may do similar things but again, it's row major.

There may be other places in your code that have the same issue but I think if you double check how you are using index and extent you should be able to fix this.

这篇关于C ++ AMP使用16位图像上的纹理计算梯度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 01:59