C ++ AMP使用16位图像上的纹理计算梯度 [英] C++AMP Computing gradient using texture on a 16 bit image
问题描述
我正在使用从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位图像上的纹理计算梯度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!