专栏首页贾志刚-OpenCV学堂Tensorflow的C语言接口部署DeeplabV3+语义分割模型

Tensorflow的C语言接口部署DeeplabV3+语义分割模型

来自:中国电科智慧城市建模仿真与智能技术重点实验室 文字编辑:gloomyfish

前言概述

tensorflow框架一般都是基于Python调用,但是有些时候跟应用场景,我们希望调用tensorflow C语言的接口,在C++的应用开发中使用它。要这么干,首先需要下载tensorflow源码,完成编译,然后调用相关的API函数实现C语言版本的调用,完成模型的加载、前向推理预测与解析。

本文主要讲DeeplabV3+语义分割模型的tensorflow C接口部署,不涉及到模型的训练过程,训练过程可以参考:

https://github.com/tensorflow/models/tree/master/research/deeplab.

官方提供了PASCAL VOC 2012,Cityscapes,ADE20K不同数据集上预训练好的模型,同时还有基于ImageNet预训练好的不同backbone网络, 包括mobilenetv2,xception,resnet,我们可以根据自己的需求来选择合适的backbone。本文不涉及tensorflow C版本的编译,只是讲解如何通过API调用预训练模型进行前向推理预测,模型的导出文件为:

frozen_inference_graph.pb

Mat转Tensor

在tensorflow中,输入数据格式为Tensor格式,有专门的函数读取图片及转换,但这样给图像预处理带来了不便,所以一般情况下,会先用opencv对图像进行读取及预处理,再从opencv的Mat格式转为tensorflow的Tensor格式,代码如下:区区几行代码,却是参考了无数资料及测试才得出来的,真是心酸

TF_Tensor* CreateTensor(TF_DataTypedata_type, conststd::int64_t* dims, std::size_tnum_dims, constvoid* data, std::size_tlen) 
{
    if (dims == nullptr || data == nullptr) 
    {
        returnnullptr;
    }
    TF_Tensor* tensor = TF_AllocateTensor(data_type, dims, static_cast<int>(num_dims), len);
    if (tensor == nullptr) 
    {
        returnnullptr;
    }
    void* tensor_data = TF_TensorData(tensor);
    if (tensor_data == nullptr) 
    {
        TF_DeleteTensor(tensor);
        returnnullptr;
    }
    std::memcpy(TF_TensorData(tensor), data, std::min(len, TF_TensorByteSize(tensor)));
    return tensor;
}

TF_Tensor* Mat2Tensor(cv::Matimg) 
{
    conststd::vector<std::int64_t>input_dims = { 1, 513, 513, 3 };
    autodata_size = sizeof(std::uint8_t);
    for (autoi : input_dims)
    {
        data_size *= i;
    }
    cv::resize(img, img, cv::Size(513, 513));
    cvtColor(img, img, cv::COLOR_RGB2BGR);
    TF_Tensor* image_input = CreateTensor(TF_UINT8, input_dims.data(), input_dims.size(), img.data, data_size);
    returnimage_input;
}

GPU资源设置

我们在执行推理的过程中,可能并不希望模型使用全部的GPU资源,又或者希望不同模型使用不同的GPU资源,这个时候需要设置。代码如下:

TF_SessionOptions *options = TF_NewSessionOptions();
uint8_tconfig[16] = { 0x32, 0xe, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x3f, 0x20, 0x1, 0x2a, 0x1, 0x30};
TF_SetConfig(options, (void*)config, 16, status);

这个是模型使用25%的GPU资源,GPU的id为0,通过如下python代码即可获得配置参数。

import tensorflow as tf
gpu_options = tf.GPUOptions(allow_growth=True,per_process_gpu_memory_fraction=0.25,visible_device_list='0')
config = tf.ConfigProto(gpu_options=gpu_options)
serialized = config.SerializeToString()
list(map(hex, serialized))
print(list(map(hex, serialized)))

利用上面的配置,逐步打开及关闭3个模型的GPU使用情况如下图:

实例演示

这是一个自己训练的用于分割细菌的模型,效果如下图。

本文分享自微信公众号 - OpenCV学堂(CVSCHOOL),作者:小黄弟

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 谷歌2018中国开发者大会第二天tensorflow专场 聆听记录

    第二天我们去的比较早,目标很明确就是为了在tensorflow专场找到一个好位置,到了之后才发现,原来人已经排了四队,还好不是很长,赶快排进了队伍,9点主场的门...

    OpenCV学堂
  • OpenCV+Tensorflow实现实时人脸识别演示

    FaceNet是谷歌提出的人脸识别模型,它跟其他人脸识别模型最大的一个不同就是它不是一个中间层输出,而是直接在欧几里德低维空间嵌入生成人脸特征,这个对以后的各种...

    OpenCV学堂
  • OpenCV4.x中请别再用HAAR级联检测器检测人脸,有更好更准的方法

    我写这篇文章是因为我很久以前写过一些文章,用了人脸检测,我当时用的都是HAAR级联检测器,导致最近几个人问我说这个HAAR级联不太准,我跟他们都解释了一下,Op...

    OpenCV学堂
  • python.InvalidArgumentError: Assign requires shapes of both tensors to match.

    平凡的学生族
  • 微信小程序 navigator 组件跳转小程序或者小游戏(一)

    田超
  • 编译tensorflow-lite-with-select-tf-ops遇到的坑

    官方没有直接给出AAR,而是让自己用巴泽尔去编译一个,实在是有点坑啊。

    vell001
  • 《Java程序设计基础》 第5章手记

    《Java程序设计基础》 第5章手记 - 一维和多维数组的定义 - 数组元素的访问 - 字符串及其应用 这节课给大家发福利,将会在后面贴实验...

    Steve Wang
  • 整合Kafka到Spark Streaming——代码示例和挑战

    作者Michael G. Noll是瑞士的一位工程师和研究员,效力于Verisign,是Verisign实验室的大规模数据分析基础设施(基础Hadoop)的技术...

    CSDN技术头条
  • jenkins 凭证(Credentials)修改

    Jenkins是一个开源软件项目,是基于Java开发的一种[持续集成]工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能

    Anymarvel
  • 真特么激动第一个爬虫----爬取豆瓣电影top250

    之前一直对爬虫有兴趣,但是一直没有真正静下心来去好好学习过,这一段时间跟着b站上的一个教程做了自己人生中第一个爬虫程序,还是很有成就感的。

    萌萌哒的瓤瓤

扫码关注云+社区

领取腾讯云代金券