c++ opencv 加载tensorflow训练的pb模型
·
前言
通过python训练的tensorflow h5模型进行预测的时候,效率不够。本人测试,在i5 16线程的电脑上,运行久后,单次预测的时候会达到500ms以上,很影响效率。这时候,就需要转成c++进行预测了。c++ opencv的dnn模型,正好可以进行预测,效率可以提升至少一倍。很适合在工业场景下使用。
opencv环境搭建
可以参考 https://blog.csdn.net/FFZZHH/article/details/156658651?spm=1001.2014.3001.5501
模型转换
opencv dnn模型,是不能直接加载h5模型的,需要将h5模型转成pb模型,代码如下:
import tensorflow as tf
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2
def h5ToPb(h5_file_path, pb_model_path,pb_model_name):
"""
冻结模型,可以将训练好的.h5模型文件转成.pb文件
:param h5_file_path: h5模型文件路径
:param pb_model_path: pb模型文件保存路径
:param pb_model_name: pb模型文件名称
:return:
"""
model = tf.keras.models.load_model(h5_file_path, compile=False)
model.summary()
full_model = tf.function(lambda input_1: model(input_1))
full_model = full_model.get_concrete_function(tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))
# Get frozen ConcreteFunction
frozen_func = convert_variables_to_constants_v2(full_model)
frozen_func.graph.as_graph_def()
layers = [op.name for op in frozen_func.graph.get_operations()]
tf.io.write_graph(graph_or_graph_def=frozen_func.graph,
logdir=pb_model_path,
name=pb_model_name,
as_text=False)
调用代码:
modelPath="D:\\python\\pbmodel"
h5Path = "D:\\python\\h5model/model.h5"
h5ToPb(h5Path,modelPath,"model.bp")
c++ opencv加载pb模型
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace cv::dnn;
using namespace std;
Net net;
bool setCheckMat(cv::Mat & checkMat){
float f, f2;//预测结果为两个标签, 各自概率
f = checkMat.at<float>(0,0);
f2 = checkMat.at<float>(0,1);
//如果有n个标签,可以这样 checkMat.at<float>(0,2);checkMat.at<float>(0,3);....checkMat.at<float>(0,n-1);
if(f > f2){//标签1的概率大于标签2
return true;
}else{
return false;
}
}
cv::Mat checkPic(const cv::Mat & checkMat,cv::dnn::Net * net){
double d = 1.0/255;//归一化,我用的pb模型有进行归一化,所以这里的数据也要归一化
cv::Scalar mean{0,0,0};
bool swapRB = false;
cv::Mat blob = blobFromImage(checkMat,d,cv::Size(checkWidth,checkHeight),mean,swapRB,false);
net->setInput(blob);
Mat out = net->forward();
blob.release();
return out;
}
bool checkImage(const std::string & path ){
Mat image = cv::imread(path);
Mat outMat = checkPic(image,&net);
image.release();
bool is = setCheckMat(outMat);
outMat.release();
return is;
}
int main(){
string path = "D:\\python\\pbmodel\\model.pb"
net = cv::dnn::readNetFromTensorflow(path);
//设置计算后台
net.setPreferableBackend(DNN_BACKEND_OPENCV);//使用opencv dnn作为后台计算
string imagePath = "D:\\a.png"//可以替换成你们的图片
bool is = checkImage(imagePath);
return 0;
}
更多推荐
所有评论(0)