OpenCV使用Tensorflow2-Keras模型

前言

最近工作上需要在C++上快速集成Tensorflow/Keras训练好的模型,做算法验证。首先想到的就是opencv里面的dnn模块了,但是它需要的格式文件比较郁闷,是pb格式的模型,但是keras通常保存的是h5文件,查阅了很多资料,最后找到了很方便的方法。

国际惯例,参考博客

Frozen_Graph_TensorFlow

这个地址的大佬用fashion mnist写的训练和测试,我这里用更简单的线性回归为例。

训练

老样子,引入相关的包,创建数据集

import numpy as np
import tensorflow as tf# build data
input_x = np.random.rand(1000, 4)
output_y = np.dot(input_x,np.array([[3],[14],[6],[10]]))

然后创建简单的模型

# build model
inputs = tf.keras.layers.Input(shape=(4,));
outputs = tf.keras.layers.Dense(units=1)(inputs)
model = tf.keras.Model(inputs=inputs,outputs=outputs)

编译、训练

model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),loss='mse')
model.fit(x=input_x,y=output_y,epochs=100,validation_split=0.1)

看看训练完毕的权重是否接近我们创建的权重

model.get_weights()
'''
[array([[ 2.669988],[13.562156],[ 5.622848],[ 9.587276]], dtype=float32),array([0.80391794], dtype=float32)]
'''

保存

保存的时候就需要注意了,要保存成pb格式的,不要直接model.saveh5格式的,如果你已经保存完了,可以model.load_model载入进来,然后再执行如下函数

# Convert Keras model to ConcreteFunction
full_model = tf.function(lambda x: model(x))
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()]
print("-" * 50)
print("Frozen model layers: ")
for layer in layers:print(layer)print("-" * 50)
print("Frozen model inputs: ")
print(frozen_func.inputs)
print("Frozen model outputs: ")
print(frozen_func.outputs)# Save frozen graph from frozen ConcreteFunction to hard drive
tf.io.write_graph(graph_or_graph_def=frozen_func.graph,logdir="./frozen_models",name="frozen_graph.pb",as_text=False)
'''
--------------------------------------------------
Frozen model layers: 
x
model/dense/MatMul/ReadVariableOp/resource
model/dense/MatMul/ReadVariableOp
model/dense/MatMul
model/dense/BiasAdd/ReadVariableOp/resource
model/dense/BiasAdd/ReadVariableOp
model/dense/BiasAdd
Identity
--------------------------------------------------
Frozen model inputs: 
[<tf.Tensor 'x:0' shape=(None, 4) dtype=float32>]
Frozen model outputs: 
[<tf.Tensor 'Identity:0' shape=(None, 1) dtype=float32>]
'''

这样就会在./frozen_models/frozen_graph.pb目录下看到模型了。

使用TensorFlow调用

在参考博客中,作者也提供了对应的调用方法

def wrap_frozen_graph(graph_def, inputs, outputs, print_graph=False):def _imports_graph_def():tf.compat.v1.import_graph_def(graph_def, name="")wrapped_import = tf.compat.v1.wrap_function(_imports_graph_def, [])import_graph = wrapped_import.graphprint("-" * 50)print("Frozen model layers: ")layers = [op.name for op in import_graph.get_operations()]if print_graph == True:for layer in layers:print(layer)print("-" * 50)return wrapped_import.prune(tf.nest.map_structure(import_graph.as_graph_element, inputs),tf.nest.map_structure(import_graph.as_graph_element, outputs))

通过tensorflow1.x载入模型

with tf.io.gfile.GFile("./frozen_models/frozen_graph.pb", "rb") as f:graph_def = tf.compat.v1.GraphDef()loaded = graph_def.ParseFromString(f.read())

随后生成预测函数

frozen_func = wrap_frozen_graph(graph_def=graph_def,inputs=["x:0"],outputs=["Identity:0"],print_graph=True)

调用这个预测函数试验一下:

test_x = np.array([[1,1,1,1]],np.float32)
pred_y = frozen_func(x=tf.constant(test_x))[0]
print(pred_y)#tf.Tensor([[32.246185]], shape=(1, 1), dtype=float32)
true_y = np.dot(test_x,np.array([[3],[14],[6],[10]]))
print(true_y) #[[33.]]

使用OpenCV-python调用模型

这个非常简单了,四句话完成创建测试数据、读取模型、载入数据、预测

test_x = np.array([[1,1,1,1]],np.float32)
net = cv2.dnn.readNetFromTensorflow("./frozen_models/frozen_graph.pb")
net.setInput(test_x)
pred = net.forward()
print(pred)#[[32.246185]]

与上面用tensorflow调用的结果一模一样。

使用opencv-C++调用模型

核心就在于opencv的readNetFromTensorflow接受的输入固定是InputArray类型的,这个类型等价于Mat、vector等,具体可以上网查。这里我们需要创建一个大小为(1,4)Mat数据;

下面这个函数就是使用数组去初始化Mat数据

void InitMat(Mat& m,float* num)
{for(int i=0;i<m.rows;i++)for(int j=0;j<m.cols;j++)m.at<float>(i,j)=*(num+i*m.rows+j);
}

创建一个Mat数据

float sz[] = {1,1,1,1};
Mat input(1,4,CV_32F);
InitMat(input, sz);

接下来就是读取模型、载入数据、预测

dnn::Net net = dnn::readNetFromTensorflow("./frozen_models/frozen_graph.pb");
net.setInput(input);
Mat pred = net.forward();
cout<<pred<<endl; //[32.246185]

后记

上面基本贴出了所有的代码,如果运行不了,可以进入公众号,在公众号简介的github中找到源码。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246575.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3D人脸表情驱动——基于eos库

前言 之前出过三篇换脸的博文&#xff0c;遇到一个问题是表情那一块不好处理&#xff0c;可行方法是直接基于2D人脸关键点做网格变形&#xff0c;强行将表情矫正到目标人脸&#xff0c;还有就是使用PRNet的思想&#xff0c;使用目标人脸的顶点模型配合源人脸的纹理&#xff0c…

3D姿态估计——ThreeDPose项目简单易用的模型解析

前言 之前写过tensorflow官方的posenet模型解析&#xff0c;用起来比较简单&#xff0c;但是缺点是只有2D关键点&#xff0c;本着易用性的原则&#xff0c;当然要再来个简单易用的3D姿态估计。偶然看见了ThreeDPose的项目&#xff0c;感觉很强大的&#xff0c;所以把模型扒下来…

简易的素描图片转换流程与实现

前言 之前经常在网上看到用PS实现真实图片到素描图片的转换&#xff0c;但是流程都大同小异&#xff0c;身为一只程序猿&#xff0c;必须来个一键转化额。 国际惯例&#xff0c;参考博客&#xff1a; Photoshop基础教程&#xff1a;混合模式原理篇 颜色减淡的原理讲解以及应…

一个简单好用的磨皮祛斑算法理论和python实现

前言 最近看了一个磨皮算法祛斑感觉效果不错&#xff0c;效果图看文末就行&#xff0c;个人觉得效果非常不错滴。 国际惯例&#xff0c;参考博客&#xff1a; 磨皮算法的源码&#xff1a;YUCIHighPassSkinSmoothing How To Smooth And Soften Skin With Photoshop 图像算法…

OpenVINO——配置与道路分割案例

前言 最近看到了一个深度学习库OpenVINO&#xff0c;专门用于Intel硬件上部署深度学习模型&#xff0c;其内置了非常非常多使用的预训练模型&#xff0c;比如道路分割、人脸提取、3D姿态估计等等。但是配置和调用有点小恶心&#xff0c;这里以道路分割为例&#xff0c;展示如何…

图像颜色迁移《color transfer between images》

前言 前段时间&#xff0c;在深度学习领域不是有个比较火的方向叫风格迁移的嘛&#xff0c;对于我这种不喜欢深度学习那种不稳定结果的人来说&#xff0c;还是想看看传统图像处理领域有什么类似的技术&#xff0c;发现了一个颜色迁移的算法&#xff0c;很久前的论文了。 国际…

ColorSpace颜色空间简介

前言 如果看过之前的介绍的图像颜色迁移《color transfer between images》和颜色协调模型Color Harmoniztion就会发现&#xff0c;大部分图像处理算法虽然输入输出是RGB像素值&#xff0c;但是中间进行算法处理时很少直接更改RGB值&#xff0c;而是转换到其它空间&#xff0c…

Ogre共享骨骼与两种骨骼驱动方法

前言 最近业务中用到Ogre做基于3D关键点虚拟角色骨骼驱动&#xff0c;但是遇到两个问题&#xff1a; 身体、头、眼睛、衣服等mesh的骨骼是分开的&#xff0c;但是骨骼结构都是一样的&#xff0c;需要设置共享骨骼驱动的时候可以直接修改骨骼旋转量&#xff0c;或者将旋转量存…

仿射变换和透视变换

前言 在前面做换脸的博客中提到了使用仿射变换和透视变换将两张不同的人脸基于关键点进行对齐&#xff0c;保证一张人脸贴到另一张人脸时&#xff0c;大小完全一致&#xff1b;所以有必要理解一下这两个概念的区别&#xff0c;由于以实用性为目的&#xff0c;所以所有的图像算…

obj格式解析

前言 最近处理一些网格渲染的时候&#xff0c;需要解析Obj文件&#xff0c;从Free3D上随便找了个免费的人体obj模型解析测试一波 国际惯例&#xff0c;参考博客&#xff1a; 本文所使用的从Free3D下载的模型 .obj文件格式与.mtl文件格式 详解3D中的obj文件格式 3D中OBJ文…

Flask服务部署与简单内网穿透

前言 最近学习部署的时候&#xff0c;想到深度学习里面通常用的部署方法是flask做服务端&#xff0c;然后使用nginx做负载均衡&#xff0c;貌似也能做内网穿透。不过我不太懂负载均衡&#xff0c;只想利用本地电脑搭建一个简单的服务器&#xff0c;实现外部调用API服务的功能。…

OpenCV学习——轮廓检测

前言 轮廓检测是传统视觉中非常常用的功能&#xff0c;这里简单记录一下opencv中的轮廓检测算法使用方法&#xff0c;至于理论&#xff0c;后续有机会再去细品。 国际惯例&#xff1a; OpenCV官方的轮廓检测教程python版 OpenCV中的二值化方法教程 OpenCV轮廓层级官方文档…

RBF神经网络理论与实现

前言 最近发现有挺多人喜欢径向基函数(Radial Basis Function,RBF)神经网络&#xff0c;其实它就是将RBF作为神经网络层间的一种连接方式而已。这里做一个简单的描述和找了个代码解读。 之前也写过一篇&#xff0c;不过排版不好看&#xff0c;可以戳这里跳转 国际惯例&#x…

基于python和unity交互的卡通角色肢体和表情驱动(深度学习)

前言 最近看到了好多卡通角色的肢体驱动的东东&#xff0c;感觉是时候发挥一下读研时候学的东西了&#xff0c;而且虽然现在不炼丹了&#xff0c;但是还是得保持吃丹的技能。这个项目找了很多很多代码进行测试&#xff0c;最终集成了一个3D姿态估计和人脸关键点提取的代码。 …

OpenCV学习——形态学

前言 继续学习图像里面的形态学知识——结构元、腐蚀、膨胀、开运算、闭运算、击中/不击中变换。以及部分基本形态学算法&#xff0c;包括边界提取、空洞填充、连通分量的提取、凸壳、细化、粗化、骨架、裁剪、形态学重建。 其实就是对冈萨雷斯的《数字图像处理》中第9章节《…

径向基函数RBF三维网格变形

前言 之前写过径向基函数(RBF)神经网络做分类或者拟合。然后挖了个坑说在《Phase-Functioned Neural Networks for Character Control》里面提到了用于做地形编辑&#xff0c;所以这篇博客就是解析一下如何用RBF做网格编辑系统。 参考博客&#xff1a; Noe’s tutorial on d…

OBJ可视化——UV还原(修正)

前言 前面写过一篇obj格式解析的博客&#xff0c;但是这篇文章中可视化的工作是参考PRNet的源码进行的&#xff0c;后来细细思考了一下&#xff0c;有点问题&#xff0c;具体看下面。 问题来源 在PRNet源码的render.py中有个函数render_texture&#xff0c;是作者用于将uv展…

Unity中BVH骨骼动画驱动的可视化理论与实现

前言 找了很久使用BVH到unity中驱动骨骼动画的代码&#xff0c;但是都不是特别好用&#xff0c;自己以前写过&#xff0c;原理很简单&#xff0c;这里记录一下。 理论 初始姿态 在BVH或者其它骨骼动画中&#xff0c;一般涉及到三种姿势&#xff1a;A-pose&#xff0c;T-pos…

卡通驱动项目ThreeDPoseTracker——模型驱动解析

前言 之前解析过ThreeDPoseTracker这个项目中的深度学习模型&#xff0c;公众号有兄弟私信一些问题&#xff0c;我刚好对这个项目实现有兴趣&#xff0c;就分析一波源码&#xff0c;顺便把问题解答一下。 这个源码其实包括很多内容&#xff1a;3D姿态估计&#xff0c;坐标平滑…

卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析

前言 之前对ThreeDPoseTracker的深度学习模型和unity中的驱动方法进行过解析&#xff0c;还有一个比较重要的就是从深度学习模型出来的3D关键点数据会有抖动&#xff0c;在ThreeDPoseTracker源码中有做两次平滑&#xff0c;一部分是卡尔曼滤波&#xff0c;还有一部分是低通滤波…