Tensorflow C Api+ windows 10 + vs2017 部署(详细教程)
一、获得Tensorflow c 库文件
方法一:选择合适版本,在windows下编译成c接口库文件。
方法二:在官网下载合适的版本,直接获得c接口库文件。libtensorflow-cpu-windows-x86_64-1.15.0.zip
二、配置Tensorflow库文件
1.打开VS2017,创建新项目,选择Visual C++下控制台应用。
2.打开项目的属性页,在【配置属性】->【C/C++】->【常规】->【附加包含目录】添加tensorflow的头文件路径
D:\tensorflow\include
3.在打开的属性页里面,【配置属性】->【链接器】->【附加库目录】添加tensorflow的lib文件路径。
D:\tensorflow\lib
4.在打开的属性页里面,【配置属性】->【链接器】->【输入】->【附加依赖项】添加tensorflow的lib文件。
tensorflow.lib
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
comdlg32.lib
advapi32.lib
5.配置完毕,代码测试程序。
std::cout << TF_Version() << std::endl;
6.运行软件
结果为1.15.0.
三、Tensorflow C Api 读取模型并检测示例
1.导入模型
TF_Graph* LoadGraph(const char* graph_path, const char* checkpoint_prefix, TF_Status* status) {
if (graph_path == nullptr) {
return nullptr;
}
auto buffer = ReadBufferFromFile(graph_path);
if (buffer == nullptr) {
return nullptr;
}
MAKE_SCOPE_EXIT(delete_status){ TF_DeleteStatus(status); };
if (status == nullptr) {
status = TF_NewStatus();
} else {
delete_status.dismiss();
}
auto graph = TF_NewGraph();
auto opts = TF_NewImportGraphDefOptions();
TF_GraphImportGraphDef(graph, buffer, opts, status);
TF_DeleteImportGraphDefOptions(opts);
TF_DeleteBuffer(buffer);
if (TF_GetCode(status) != TF_OK) {
DeleteGraph(graph);
return nullptr;
}
auto graph = tf_utils::LoadGraph("Tensorflow.pb"); ///模型路径
SCOPE_EXIT{ tf_utils::DeleteGraph(graph); };
if (graph == nullptr) {
std::cout << "Can't load graph" << std::endl;
return 1;
}
2.导入图像
TF_Tensor* Mat2Tensor(cv::Mat img)
{
const std::vector< std::int64_t>input_dims = { 1, IMAGE_SIZE, IMAGE_SIZE, 3 };
auto data_size = sizeof(std::uint8_t);
for (auto i : input_dims)
{
data_size *= i;
}
cv::resize(img, img, cv::Size(IMAGE_SIZE, IMAGE_SIZE));
cvtColor(img, img, cv::COLOR_BGR2RGB);
TF_Tensor* image_tensor = CreateTensor(TF_UINT8, input_dims.data(), input_dims.size(), img.data, data_size);
if (TF_TensorType(image_tensor) != TF_UINT8) {
std::cout << "Wrong tensor type" << std::endl;
return nullptr;
}
if (TF_NumDims(image_tensor) != static_cast<int>(input_dims.size())) {
std::cout << "Wrong number of dimensions" << std::endl;
return nullptr;
}
for (std::size_t i = 0; i < input_dims.size(); ++i) {
if (TF_Dim(image_tensor, static_cast<int>(i)) != input_dims[i]) {
std::cout << "Wrong dimension size for dim: " << i << std::endl;
return nullptr;
}
}
if (TF_TensorByteSize(image_tensor) != data_size) {
std::cout << "Wrong tensor byte size" << std::endl;
return nullptr;
}
auto tensor_data = static_cast<float*>(TF_TensorData(image_tensor));
if (tensor_data == nullptr) {
std::cout << "Wrong data tensor" << std::endl;
return nullptr;
}
return image_tensor;
}
Mat srcImg = imread("test.jpg"); //使用OpenCV 读取图像
TF_Tensor* input_image = Mat2Tensor(srcImg); //Mat 转换成Tensor
3.输入操作名称为input_4的
auto input_op = TF_Output{TF_GraphOperationByName(graph, "input_4"), 0};
if (input_op.oper == nullptr) {
std::cout << "Can't init input_op" << std::endl;
return 2;
}
4.输出操作名称为output_node0
auto out_op = TF_Output{TF_GraphOperationByName(graph, "output_node0"), 0};
if (out_op.oper == nullptr) {
std::cout << "Can't init out_op" << std::endl;
return 3;
}
5.将模型导入到会话中。
auto status = TF_NewStatus();
SCOPE_EXIT{ TF_DeleteStatus(status); }; // Auto-delete on scope exit.
auto options = TF_NewSessionOptions();
auto sess = TF_NewSession(graph, options, status);
TF_DeleteSessionOptions(options);
if (TF_GetCode(status) != TF_OK) {
return 4;
}
6.运行会话。
TF_SessionRun(sess,
nullptr, // Run options.
&input_op, &input_tensor, 1, // Input tensors, input tensor values, number of inputs.
&out_op, &output_tensor, 1, // Output tensors, output tensor values, number of outputs.
nullptr, 0, // Target operations, number of targets.
nullptr, // Run metadata.
status // Output status.
);
if (TF_GetCode(status) != TF_OK) {
std::cout << "Error run session";
return 5;
}
TF_CloseSession(sess, status);
if (TF_GetCode(status) != TF_OK) {
std::cout << "Error close session";
return 6;
}
TF_DeleteSession(sess, status);
if (TF_GetCode(status) != TF_OK) {
std::cout << "Error delete session";
return 7;
}
7.获得结果
auto data = static_cast<float*>(TF_TensorData(output_tensor));
std::cout << "Output vals: " << data[0] << ", " << data[1] << ", " << data[2] << ", " << data[3] << std::endl;