opencv DNN模块 +tensorflow

使用的版本是tensorflow0.12.0 + python3.6,搭建一个简单的模型,用来训练得到pb文件。

opencv3.4.1 + 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文件测试

接下来可以在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()

C ++调用:

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

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

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

#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;
}

 

猜你喜欢

转载自blog.csdn.net/rj1457365980/article/details/83140921