首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不复制将OpenCV Mat导入到C++ Tensorflow

不复制将OpenCV Mat导入到C++ Tensorflow
EN

Stack Overflow用户
提问于 2016-09-07 22:08:53
回答 2查看 8.6K关注 0票数 10

我的目标是实时运行TensorFlow模型,从学习的模型中控制车辆。我们的车辆系统使用ROS (机器人操作系统),它与OpenCV紧密相连。因此,我收到了一个包含ROS感兴趣的图像的OpenCV Mat。

代码语言:javascript
复制
    cv::Mat cameraImg;

我想直接从这个OpenCV矩阵中的数据创建一个Tensorflow张量,以避免复制矩阵逐行的开销。使用这个问题的答案,我设法让网络向前通过,使用以下代码:

代码语言:javascript
复制
cameraImg.convertTo(cameraImg, CV_32FC3);

Tensor inputImg(DT_FLOAT, TensorShape({1,inputheight,inputwidth,3}));
auto inputImageMapped = inputImg.tensor<float, 4>();
auto start = std::chrono::system_clock::now();
//Copy all the data over
for (int y = 0; y < inputheight; ++y) {
    const float* source_row = ((float*)cameraImg.data) + (y * inputwidth * 3);
    for (int x = 0; x < inputwidth; ++x) {
        const float* source_pixel = source_row + (x * 3);
        inputImageMapped(0, y, x, 0) = source_pixel[2];
        inputImageMapped(0, y, x, 1) = source_pixel[1];
        inputImageMapped(0, y, x, 2) = source_pixel[0];
    }
}
auto end = std::chrono::system_clock::now();

然而,使用这种方法,张量的拷贝在80到130 to之间,而整个向前通过(对于一个10层的卷积网络)只需要25 to。

tensorflow文档中,似乎有一个接受分配器的张量构造函数。然而,我没有找到任何与此功能或特征映射类相关的Tensorflow或特征文档,因为它与张量有关。

有谁对如何加快这段代码有任何洞察力,最好是通过重用我的OpenCV内存?

编辑:我已经成功地实现了@mrry建议的内容,并且可以重用OpenCV分配的内存。我打开了github第8033期,请求将其添加到tensorflow源代码树中。我的方法没那么漂亮,但很管用。

编译外部库并将其链接到libtensorflow.so库仍然非常困难。tensorflow cmake库可能会在这方面有所帮助,我还没有试过。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-07 23:16:26

TensorFlow can (相对于C++ API)导出TF_NewTensor()函数,它允许您从指针和长度创建张量,并且可以将结果对象传递给TF_Run()函数。

目前,这是在预分配缓冲区中创建TensorFlow张量的唯一公共API。没有支持将TF_Tensor*转换为tensorflow::Tensor的方法,但是如果您查看实现,就会发现有一个具有friend访问权限的私有API可以做到这一点。如果您对此进行了实验,并且可以显示明显的加速比,我们将考虑使用特征请求将其添加到公共API中。

票数 9
EN

Stack Overflow用户

发布于 2017-09-25 22:28:44

我知道这是一个旧线程,但是使用现有的C++ API,您的问题有一个零拷贝解决方案:我用我的解决方案更新了您的github问题。tensorflow/issues/8033

为了记录在案,我在这里复制我的解决方案:

代码语言:javascript
复制
// allocate a Tensor
Tensor inputImg(DT_FLOAT, TensorShape({1,inputHeight,inputWidth,3}));

// get pointer to memory for that Tensor
float *p = inputImg.flat<float>().data();
// create a "fake" cv::Mat from it 
cv::Mat cameraImg(inputHeight, inputWidth, CV_32FC3, p);

// use it here as a destination
cv::Mat imagePixels = ...; // get data from your video pipeline
imagePixels.convertTo(cameraImg, CV_32FC3);

希望这能有所帮助

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39379747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档