C ++ Amp从纹理复制16位图像到纹理(从openCV Mat) [英] C++Amp Copying an image of 16 bits from a texture to texture (from a openCV Mat)

查看:873
本文介绍了C ++ Amp从纹理复制16位图像到纹理(从openCV Mat)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是这个问题的下一个步骤



在使用gpu复制后:



我也尝试使用kinect图像看看会发生什么。结果让我吃惊:



原创:



结果:



任何人都知道发生了什么事?



这是我做的修改(可能有用)

  cv :: Mat image = cv :: imread(Depth247。 tiff,CV_LOAD_IMAGE_ANYDEPTH); 
cv :: Mat image2(480,640,CV_16UC1);

一如往常,任何帮助将非常感激。



感谢,
David

解决方案

主要的问题是你试图访问一个非32位的纹理。如果你通过调试器运行这个代码,它实际上抛出了 .set()指令。



MSDN不是AMP团队的博客解释这个很好,但解决方案似乎是声明输入纹理包含 const 类型。我假设你使用VS 2013,如果不是,那么让我知道,我会发布代码为2012年。



这是整个程序。它看起来像我期望的一样。

  #includeopencv2 / highgui / highgui.hpp
#include < amp; h>
#include< amp_graphics.h>
#include< amp_short_vectors.h>

使用命名空间并发;
using namespace std;

int main(int argc,const char ** argv)
{
cv :: Mat image(480,640,CV_16UC1);
cv :: Mat image2(480,640,CV_16UC1);

//创建一个渐变,只是看到有意义的东西
for(int i = 0; i <480; i ++)
{
for = 0; j <640; j ++)
{
/ * int gradientInY =(i / 480.f)* 65535;
image.at< uint16_t>(i,j)= gradientInY; * /

int gradientInX =(j / 640.f)*(i / 480.f)* 65535;
image.at< uint16_t>(i,j)= gradientInX;
image2.at< uint16_t>(i,j)= 65535/2;
}
}

cv :: imshow(image,image);
cv :: waitKey(50);

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

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

//源数据
graphics :: texture< unsigned int,2> texDataS(imageSize,image.data,nBytes,bits);
graphics :: texture_view< const unsigned int,2> texS(texDataS);

//结果数据
graphics :: texture< unsigned int,2> texDataD(imageSize,16);
graphics :: texture_view< unsigned int,2> texD(texDataD);

parallel_for_each(imageSize,[=,& texDataS](concurrency :: index< 2> idx)restrict(amp)
{
int val = texS(idx);

//你的图像处理工作在这里。
int result = val;

texD.set(idx,result);
}

//不要在这里复制,因为你需要立即结果。
concurrency :: graphics :: copy(texDataD,image2.data,imageSize.size()* bits / 8);

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

return 0;
}


This issue is the next step from this one link.

In brief, I am working with depth images from a kinect which retrieve images of 16 bits. With C++Amp we do have some restrictions on the bit size of the data. So, I am trying to use textures to deal with it.

Now, I'm sure I am writing to the proper pixel. However, it seems there is some issue retrieving from my texture original data.

That's the code:

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

cv::Mat image(480, 640, CV_16UC1);
cv::Mat image2(480, 640, CV_16UC1);

// create a gradient, just to see something meaningfull
for (int i = 0; i < 480; i++)
{
    for (int j = 0; j < 640; j++)
    {
        /*int gradientInY = (i / 480.f) * 65535;
        image.at<uint16_t>(i, j) = gradientInY;*/

        int gradientInX = (j / 640.f) * 65535;
        image.at<uint16_t>(i, j) = gradientInX;
        image2.at<uint16_t>(i, j) = gradientInX;
    }
}


cv::imshow("image", image);
cv::waitKey(50);

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

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


{
    uchar* data = image.data;

    // Source Data
    TextureData texDataS(imageSize, data, nBytes, bits);
    Texture texS(texDataS);

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


    parallel_for_each(
        imageSize,
        [=, &texDataS](concurrency::index<2> idx) restrict(amp)
    {
        //I tried either this:
        int val = texDataS(idx);

        // and this:
        //int val = texS(idx);
        texR.set(idx, val);
    });
    //concurrency::graphics::copy(texR, image2.data, imageSize.size() *(bits / 8u));
    concurrency::graphics::copy_async(texR, image2.data, imageSize.size() *(bits / 8u) );

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

And the results:

And after copy using gpu:

I also tried to use a kinect image to see what happen. The result surprises me:

Original:

Result:

Anyone know what's going on?

That's the modification I did to work with a image of 16 bits directly (maybe it's helpful)

cv::Mat image = cv::imread("Depth247.tiff", CV_LOAD_IMAGE_ANYDEPTH);
cv::Mat image2(480, 640, CV_16UC1);

As always, any help will be very gratefully. Do not hesitate to ask me for more details if you think you could help me.

Thanks, David

解决方案

The main issue is that your are trying to access a non-32 bit texture. If you run this code through the debugger it actually throws on the .set() instruction.

Neither MSDN not the AMP team's blog explain this very well but the solution appears to be to declare the input texture as containing a const type. I'm assuming you're using VS 2013, if not then let me know and I'll post the code for 2012.

Here's the whole program. it appears to behave as expected for me.

#include "opencv2/highgui/highgui.hpp"
#include <amp.h>
#include <amp_graphics.h>
#include <amp_short_vectors.h>

using namespace concurrency;
using namespace std;

int main( int argc, const char** argv )
{
    cv::Mat image(480, 640, CV_16UC1);
    cv::Mat image2(480, 640, CV_16UC1);

    // create a gradient, just to see something meaningful
    for (int i = 0; i < 480; i++)
    {
        for (int j = 0; j < 640; j++)
        {
            /*int gradientInY = (i / 480.f) * 65535;
            image.at<uint16_t>(i, j) = gradientInY;*/

            int gradientInX = (j / 640.f) * (i / 480.f) * 65535;
            image.at<uint16_t>(i, j) = gradientInX;
            image2.at<uint16_t>(i, j) = 65535 / 2;
        }
    }

    cv::imshow("image", image);
    cv::waitKey(50);

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

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

    // Source Data
    graphics::texture<unsigned int, 2> texDataS(imageSize, image.data, nBytes, bits);
    graphics::texture_view<const unsigned int, 2> texS(texDataS);

    // Result data
    graphics::texture<unsigned int, 2> texDataD(imageSize, 16);
    graphics::texture_view<unsigned int, 2> texD(texDataD);

    parallel_for_each(imageSize, [=, &texDataS](concurrency::index<2> idx) restrict(amp)
    {
        int val = texS(idx);

        // Do your image processing work here.
        int result = val;

        texD.set(idx, result);
    });

    // Don't copy async here as you need the result immediately.
    concurrency::graphics::copy(texDataD, image2.data, imageSize.size() * bits / 8);

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

    return 0;
}

这篇关于C ++ Amp从纹理复制16位图像到纹理(从openCV Mat)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆