Tensorflow框架 -- 使用C++ API 接口

本文主要使用介绍使用 tensorflow API接口的基本流程,配合OpenCV读取图像数据。

#define COMPILER_MSVC
#define NOMINMAX
#define PLATFORM_WINDOWS

#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include <tensorflow/core/public/version.h>

#include "tensorflow/cc/ops/const_op.h"
#include "tensorflow/cc/ops/image_ops.h"

#include "tensorflow/core/framework/graph.pb.h"
#include "tensorflow/core/framework/tensor.h"

#include "tensorflow/core/graph/default_device.h"
#include "tensorflow/core/graph/graph_def_builder.h"

#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/core/threadpool.h"
#include "tensorflow/core/lib/io/path.h"
#include "tensorflow/core/lib/strings/stringprintf.h"

#include "tensorflow/core/util/command_line_flags.h"

#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/types.h"

#include <string.h>
#include <fstream>
#include <utility>
#include <Eigen/Core>
#include <Eigen/Dense>
#include<opencv2/opencv.hpp>
#include <iostream>

using tensorflow::string;
using namespace tensorflow;
using namespace std;
using namespace cv;

// Mat 数据转化为 Tensor
void CVMat_to_Tensor(Mat img, Tensor* output_tensor, int input_rows, int input_cols)
{
	//imshow("input image",img);
	//图像进行resize处理
	// resize(img, img, cv::Size(input_cols, input_rows));
	//imshow("resized image",img);
	
	// 遍历 Mat数据结构
	//for (int i = 0; i < input_rows; i++) 
	//	for (int j = 0; j < input_cols; j++) 
		{
	//		//cout << float((img.at<uchar>(i, j))) << endl;  // 直接输出uchar,将无法终端显示
	//		img.at<float>(i, j) = (float(img.at<uchar>(i, j)) - 2) / (4.0);
	//		cout << float((img.at<uchar>(i, j))) << endl;
	//	}
	
	// 利用Opencv计算图像的均值和方差
	Mat img_mean, img_std;
	cv::meanStdDev(img, img_mean, img_std);
	cout << "均值方差:" << img_mean.at<double>(0, 0) << " " << img_std.at<double>(0, 0) << endl;
	
	//创建一个指向tensor的内容的指针
	float *p = output_tensor->flat<float>().data();
	
	//创建一个Mat,与tensor的指针绑定,改变这个Mat的值,就相当于改变tensor的值
	cv::Mat tempMat(input_rows, input_cols, CV_32FC1, p);
	img.convertTo(tempMat, CV_32FC1);
	
	// 图像预处理通常放在 img.convertTo(tempMat, CV_32FC1)之后
	tempMat = (tempMat - img_mean.at<double>(0, 0))/(img_std.at<double>(0, 0) + 1e-8);
}

vector<cv::Point> DL_Predict(string modelname)
{
	/*--------------------------------配置关键信息------------------------------*/
	string model_path = "./model-v4-240.pb";
	//string image_path = "./test_data/wenshing3_0.png";
	string path = "./test_data/tfile/" + modelname + "_0.png";
	cout << "path: " << path << endl;
	
	int input_height = 480;
	int input_width = 240;
	string input_tensor_name = "image";
	string output_tensor_name = "Mconv7_stage6_L2/BiasAdd";

	/*--------------------------------创建session------------------------------*/
	Session* session;
	Status status = NewSession(SessionOptions(), &session);  //创建新会话Session

	/*--------------------------------从pb文件中读取模型--------------------------------*/
	GraphDef graphdef; //Graph Definition for current model

	Status status_load = ReadBinaryProto(Env::Default(), model_path, &graphdef); //从pb文件中读取图模型;
	if (!status_load.ok()) {
		cout << "ERROR: Loading model failed ..." << model_path << std::endl;
		cout << status_load.ToString() << "\n";
		exit(0);
	}

	Status status_create = session->Create(graphdef); // 将模型导入会话Session中;
	if (!status_create.ok()) {
		cout << "ERROR: Creating graph in session failed..." << status_create.ToString() << std::endl;
		exit(0);
	}
	cout << "<----Successfully created session and load graph.------->" << endl;

	/*---------------------------------载入测试图片-------------------------------------*/
	cout << endl << "<------------loading test_image-------------->" << endl;
	Mat img = imread(path, 0);
	
	if (img.empty())
	{
		cout << "can't open the image!!!!!!!" << endl;
		exit(0);
	}

	//创建一个tensor作为网络输入的接口(接收输入数据)
	Tensor resized_tensor(DT_FLOAT, TensorShape({ 1,input_height,input_width,1 }));

	//将Opencv的Mat格式的图片存入tensor
	CVMat_to_Tensor(img, &resized_tensor, input_height, input_width);
	cout << "输入:" << resized_tensor.DebugString() << endl;

	/*-----------------------------------用网络进行测试-----------------------------------------*/
	cout << endl << "<-------------Running the model with test_image--------------->" << endl;
	//前向运行,输出结果一定是一个tensor的vector
	vector<tensorflow::Tensor> outputs;
	string output_node = output_tensor_name;
	Status status_run = session->Run({ { input_tensor_name, resized_tensor } }, { output_node }, {}, &outputs);

	if (!status_run.ok()) {
		cout << "ERROR: RUN failed..." << std::endl;
		cout << status_run.ToString() << "\n";
		exit(0);
	}

	// 获取网络输出的tensor结构,输出预测结果
	cout << "Output tensor size:" << outputs.size() << std::endl;
	for (std::size_t i = 0; i < outputs.size(); i++) {
		cout << outputs[i].DebugString() << endl;
	}

	Tensor t = outputs[0];                   // Fetch the first tenso
	auto tmap = t.tensor<float, 4>();        // 输出为特征图,所以shape为4

	// 输出预测结果,并后处理
	ofstream fout("heapmap.txt");
	float max = numeric_limits<float>::min();
	float value;
	
	vector<cv::Point> joint;
	cv::Point p_joint;
	for (int i = 0; i < 8; i++)
	{
		max = numeric_limits<float>::min();
		for (int j = 0; j < 60; j++)
		{
			for (int k = 0; k < 30; k++)
			{
				// cout << tmap(0, j, k, i) << " " << std::endl;
				// fout << tmap(0, j, k, i) << " ";
				value = tmap(0, j, k, i);  // 注意tensor的索引[batch, height, width, depth]
				if (value > max)
				{
					max = value;
					p_joint.x = k*8;
					p_joint.y = j*8;
				}
			}
		}
		cout << "坐标值:" << p_joint.x << " " << p_joint.y << endl;
		joint.push_back(p_joint);
	}
	return joint;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值