tensorflow C++接口調用目標檢測pb模型代碼


#include <iostream>
 
#include "tensorflow/cc/ops/const_op.h"
#include "tensorflow/cc/ops/image_ops.h"
#include "tensorflow/cc/ops/standard_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/platform/env.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/util/command_line_flags.h"
 
#include <opencv2/opencv.hpp>
#include <cv.h>
#include <highgui.h>
#include <Eigen/Core>
#include <Eigen/Dense>
 
using namespace std;
using namespace cv;
using namespace tensorflow;
 
 
 
// 定義一個函數講OpenCV的Mat數據轉化為tensor,python里面只要對cv2.read讀進來的矩陣進行np.reshape之后,
// 數據類型就成了一個tensor,即tensor與矩陣一樣,然后就可以輸入到網絡的入口了,但是C++版本,我們網絡開放的入口
// 也需要將輸入圖片轉化成一個tensor,所以如果用OpenCV讀取圖片的話,就是一個Mat,然后就要考慮怎么將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);
 
    //歸一化
    img.convertTo(img,CV_8UC3);  // CV_32FC3
    //img=1-img/255;
 
    //創建一個指向tensor的內容的指針
    uint8 *p = output_tensor->flat<uint8>().data();
 
    //創建一個Mat,與tensor的指針綁定,改變這個Mat的值,就相當於改變tensor的值
    cv::Mat tempMat(input_rows, input_cols, CV_8UC3, p);
    img.convertTo(tempMat,CV_8UC3);
 
 //    waitKey(0);
 
}
 
int main()
{
    /*--------------------------------配置關鍵信息------------------------------*/
    string model_path="../model/coco.pb";
    string image_path="../test.jpg";
    int input_height = 1000;
    int input_width = 1000;
    string input_tensor_name="image_tensor";
    vector<string> out_put_nodes;  //注意,在object detection中輸出的三個節點名稱為以下三個
    out_put_nodes.push_back("detection_scores");  //detection_scores  detection_classes  detection_boxes
    out_put_nodes.push_back("detection_classes");
    out_put_nodes.push_back("detection_boxes");
 
    /*--------------------------------創建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";
        return -1;
    }
    Status status_create = session->Create(graphdef); //將模型導入會話Session中;
    if (!status_create.ok()) {
        cout << "ERROR: Creating graph in session failed..." << status_create.ToString() << std::endl;
        return -1;
    }
    cout << "<----Successfully created session and load graph.------->"<< endl;
 
    /*---------------------------------載入測試圖片-------------------------------------*/
    cout<<endl<<"<------------loading test_image-------------->"<<endl;
    Mat img;
    img = imread(image_path);
    cvtColor(img, img, CV_BGR2RGB);
    if(img.empty())
    {
        cout<<"can't open the image!!!!!!!"<<endl;
        return -1;
    }
 
    //創建一個tensor作為輸入網絡的接口
    Tensor resized_tensor(DT_UINT8, TensorShape({1,input_height,input_width,3})); //DT_FLOAT
 
    //將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;
 
    Status status_run = session->Run({{input_tensor_name, resized_tensor}}, {out_put_nodes}, {}, &outputs);
 
    if (!status_run.ok()) {
        cout << "ERROR: RUN failed..."  << std::endl;
        cout << status_run.ToString() << "\n";
        return -1;
    }
 
    //把輸出值給提取出
    cout << "Output tensor size:" << outputs.size() << std::endl;  //3
    for (int i = 0; i < outputs.size(); i++)
    {
        cout << outputs[i].DebugString()<<endl;   // [1, 50], [1, 50], [1, 50, 4]
    }
 
    cvtColor(img, img, CV_RGB2BGR);  // opencv讀入的是BGR格式輸入網絡前轉為RGB
    resize(img,img,cv::Size(1000,1000));  // 模型輸入圖像大小
    int pre_num = outputs[0].dim_size(1);  // 50  模型預測的目標數量
    auto tmap_pro = outputs[0].tensor<float, 2>();  //第一個是score輸出shape為[1,50]
    auto tmap_clas = outputs[1].tensor<float, 2>();  //第二個是class輸出shape為[1,50]
    auto tmap_coor = outputs[2].tensor<float, 3>();  //第三個是coordinate輸出shape為[1,50,4]
    float probability = 0.5;  //自己設定的score閾值
    for (int pre_i = 0; pre_i < pre_num; pre_i++)
    {
        if (tmap_pro(0, pre_i) < probability)
        {
            break;
        }
        cout << "Class ID: " << tmap_clas(0, pre_i) << endl;
        cout << "Probability: " << tmap_pro(0, pre_i) << endl;
        string id = to_string(int(tmap_clas(0, pre_i)));
        int xmin = int(tmap_coor(0, pre_i, 1) * input_width);
        int ymin = int(tmap_coor(0, pre_i, 0) * input_height);
        int xmax = int(tmap_coor(0, pre_i, 3) * input_width);
        int ymax = int(tmap_coor(0, pre_i, 2) * input_height);
        cout << "Xmin is: " << xmin << endl;
        cout << "Ymin is: " << ymin << endl;
        cout << "Xmax is: " << xmax << endl;
        cout << "Ymax is: " << ymax << endl;
        rectangle(img, cvPoint(xmin, ymin), cvPoint(xmax, ymax), Scalar(255, 0, 0), 1, 1, 0);
        putText(img, id, cvPoint(xmin, ymin), FONT_HERSHEY_COMPLEX, 1.0, Scalar(255,0,0), 1);
    }
    imshow("1", img);
    cvWaitKey(0);
 
    return 0;
}

CMakeLists.txt內容如下

cmake_minimum_required(VERSION 3.0.0)
project(tensorflow_cpp)
 
set(CMAKE_CXX_STANDARD 11)
 
find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
    find_package(OpenCV 2.4.3 QUIET)
    if(NOT OpenCV_FOUND)
        message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
    endif()
endif()
 
set(TENSORFLOW_INCLUDES
        /usr/local/include/tf/
        /usr/local/include/tf/bazel-genfiles
        /usr/local/include/tf/tensorflow/
        /usr/local/include/tf/tensorflow/third_party)
 
set(TENSORFLOW_LIBS
        /usr/local/lib/libtensorflow_cc.so
        /usr/local/lib//libtensorflow_framework.so)
 
 
include_directories(
        ${TENSORFLOW_INCLUDES}
        ${PROJECT_SOURCE_DIR}/third_party/eigen3
)
add_executable(predict predict.cpp)
target_link_libraries(predict
        ${TENSORFLOW_LIBS}
        ${OpenCV_LIBS}
        )

目錄結構如圖所示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM