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