tensorflow+python3训练网络模型,opencv3.4+C++调用

opencv3.3之后推出了DNN的神经网络接口,这样的OpenCV的中就可以调用tensorflow训练得到的网络了。

我这里使用的版本是tensorflow1.4.0 + python3.5,搭建一个简单的模型,用来训练得到pb文件。

opencv3.4.0 + VS2015,用来加载使用pb文件。

  • 训练PD文件。

创建项目,新建save_pb.py。

在该网络中,设置输入结点的名字为:conv1/input,输出结点的名字为:conv1/y,(输入输出结点的名称必须设置)建立网络结构:x*w1*w2=y,w1,w2均为随机数,其中X的尺寸:[1,2],w1:[2,3],w2:[3,1],输出的结点y:[1]。

保存该网络,即保存网络结构,与变量值,即w1和w2两个随机数也保存下来代码如下:

import tensorflow as tf
from tensorflow.python.framework import graph_util


def save_pb(sess):
    constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def, ['conv1/y'])
    with tf.gfile.FastGFile("D://python//hand//graph.pb", mode='wb') as f:
        f.write(constant_graph.SerializeToString())


def main():
    with tf.variable_scope('conv1'):
        w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
        w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
        x = tf.placeholder(tf.float32, shape=(1, 2), name='input')
        a = tf.matmul(x, w1)
        y = tf.matmul(a, w2, name="y")

    with tf.Session() as sess:
        tf.initialize_all_variables().run()
        print(sess.run(y, feed_dict={x:[[7, 9]]}))
        save_pb(sess)

main()

 运行结果:

在相应的位置,也得到了.pb文件:

  • PB文件测试

接下来可以在python中测试一下PB文件是否正确。

从文件中取出.pb文件,获取其输入结点conv1/input,输出结点conv1/y,将参数传入,并得到输出结果。

import tensorflow as tf
from tensorflow.python.platform import gfile


def main():
    with tf.Session() as sess:
        with gfile.FastGFile("D://python//hand//graph.pb", 'rb') as f:
            graph_def = tf.GraphDef()
            graph_def.ParseFromString(f.read())
            sess.graph.as_default()
            tf.import_graph_def(graph_def, name='')
            
        sess.run(tf.global_variables_initializer())
        input_x = sess.graph.get_tensor_by_name('conv1/input:0')

        op = sess.graph.get_tensor_by_name('conv1/y:0')
        print(sess.run(op, feed_dict={input_x:[[7, 9]]}))

main()

运行结果:

与保存时的运行结果一致,所以pb文件保存正确。

  • C ++调用:

在C ++中调用时需要使用到DNN。

使用readNetFromTensorflow得到PD中​​保存的网络模型,在OpenCV中的中的输入输出都为mat类型,所以输入的 mat 需要定义为大小与输入张量相等的[2,1],对输入mat 进行赋值后使用blobFromImage对mat进行处理,执行平均减法来对输入图像进行归一化,从而产生一个已知的斑点形状。得到可以作为网络模型输入的数据。

setInput设置函数为传递参数到输入结点 conv1/input.forword为得到输出结点的值,值的形式为mat型。

#include<opencv2\opencv.hpp>
#include<opencv2\dnn.hpp>
#include<stdlib.h>
#include<iostream>
#include<string.h>

using namespace cv;
using namespace std;
using namespace dnn;

int main() {
	String weights = "D://python//hand//graph.pb";
	Net net = readNetFromTensorflow(weights);
	Mat input(Size(2, 1), CV_8UC1);
	input.at<uchar>(0, 0) = 7;
	input.at<uchar>(0, 1) = 9;
	input = blobFromImage(input, 1.0, Size(2, 1), Scalar(), false, false);
	net.setInput(input, "conv1/input");
	Mat pred = net.forward("conv1/y");
	cout << pred << endl;
	system("pause");
	return 0;
}

运行结果:

输出的结果一致。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值