Tensorflow库向c++的移植和调用方法(GPU)(landmark68点人脸点对齐案例)

Tensorflow库向c++的移植和调用方法(GPU)(landmark68点人脸点对齐案例)

写这篇东西的时候我才发现我都好久没有更新了,这个东西也是差不多一年前做的小东西了,当时是为了将网上找到的landmark68点人脸对齐模型用在c++上替换openface里面的人脸点对其模型,但是实际上这种方法是没有意义的,因为直到半年以后我才发现openface实际上是人脸形状的回归,而且是三维的,这使得网上绝大多数二维的landmark对齐都没有意义。
再后来,也就是差不多一年以后,我发现用tensorflow的模型并不一定需要配置tensorflow的库,其中有两种方法是比较好的。

  1. 将tensorflow模型转成onnx模型,然后在c++配置onnxruntime来调用模型
  2. 直接使用opencv中的dnn模块来调用tensorflow模型

从后来看当时的我还是比较蠢的,但是这也说明自己还是成长了很多,下面我还是会将当时配置的方法分享一下:
由于tensorflow是python的一个库,那么如果我们要在c++使用它,在tensorflow官方没有提供lib、dll的情况下,我们就需要编译源码,源码的编译是比较复杂的,涉及到很多的环境问题,有时候还需要对cmakelist的有一定的了解,参考的这个博客,基本上也算是很全的了windows10+vs2015下编译GPU版本将Tensorflow封装成SDK。但是要注意一点,那就是tensorflow版本的问题,且不说tensorflow2.X和1.X的区别,就光是1.X,只要你使用的是tensorflow-gpu,那么cuda和cudnn一定是一个坑。最好还是要将你所使用的tensorflow-gpu版本和cuda还有cudnn的版本匹配起来,下面是他们的对应关系,
https://www.tensorflow.org/install/source#common_installation_problems
https://www.tensorflow.org/install/source_windows
在这里插入图片描述

这个很重要,即使是在python端的使用也一定要注意,下面是我的demo源码,希望可以给大家一些启发:

#define COMPILER_MSVC
#define NOMINMAX
#define PLATFORM_WINDOWS   // 指定使用tensorflow/core/platform/windows/cpu_info.h

#include <iostream>
#include <opencv2/opencv.hpp>
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h"

using namespace tensorflow;
using namespace std;


void main{
    
    
	// 设置输入图像
	cv::Mat img = cv::imread(image_path);
	cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);
	int height = img.rows;
	int width = img.cols;
	int depth = img.channels();

	// 图像预处理
	img.convertTo(img, CV_32F);
	img = (img - 128) / 128.0;

	// 取图像数据,赋给tensorflow支持的Tensor变量中
	const float* source_data = (float*)img.data;
	tensorflow::Tensor input_tensor(DT_FLOAT, TensorShape({
    
     1, height, width, depth })); //这里只输入一张图片,参考tensorflow的数据格式NHWC
	auto input_tensor_mapped = input_tensor.tensor<float, 4>(); // input_tensor_mapped相当于input_tensor的数据接口,“4”表示数据是4维的。后面取出最终结果时也能看到这种用法                                                                                                      

	// 把数据复制到input_tensor_mapped中,实际上就是遍历opencv的Mat数据
	for (int i = 0; i < height; i++) {
    
    
		const float* source_row = source_data + (i * width * depth);
		for (int j = 0; j < width; j++) {
    
    
			const float* source_pixel = source_row + (j * depth);
			for (int c = 0; c < depth; c++) {
    
    
				const float* source_value = source_pixel + c;
				input_tensor_mapped(0, i, j, c) = *source_value;
			}
		}
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_41240513/article/details/109101213