前言
今天和大家一起來(lái)看一下在LabVIEW中如何使用OpenCV DNN模塊實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別
一、OpenCV DNN模塊
1.OpenCV DNN簡(jiǎn)介
**OpenCV中的DNN(Deep Neural Network module)模塊是專門用來(lái)實(shí)現(xiàn)深度神經(jīng)網(wǎng)絡(luò)相關(guān)功能的模塊。OpenCV自己并不能訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型,但是它可以載入別的深度學(xué)習(xí)框架(例如TensorFlow、pytorch、Caffe等等)訓(xùn)練好的模型,然后使用該模型做inference(預(yù)測(cè))。而且OpenCV在載入模型時(shí)會(huì)使用自己的DNN模塊對(duì)模型重寫(xiě),使得模型的運(yùn)行效率更高。所以如果你想在OpenCV項(xiàng)目中融入深度學(xué)習(xí)模型,可以先用自己熟悉的深度學(xué)習(xí)框架訓(xùn)練好,然后使用OpenCV的DNN模塊載入。 **
2.LabVIEW中DNN模塊函數(shù)
DNN模塊位于程序框圖-函數(shù)選板-Addons-VIRobotics-opencv_yiku中,如下圖所示:
Net選版中的函數(shù)與python中的函數(shù)對(duì)比如下:**
**
二、TensorFlow pb文件的生成和調(diào)用
1.TensorFlow2 Keras模型(mnist)
注:本范例必須使用tensorflow 2.x版本
** 如下圖所示所示為數(shù)據(jù)集以及LabVIEW與Python推理和訓(xùn)練代碼,相關(guān)源碼可在鏈接中下載。**
2.使用Keras搭建cnn訓(xùn)練mnist(train.py),訓(xùn)練部分源碼如下:
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1)
test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)
train_images = train_images / 255.0
test_images = test_images / 255.0
?
train_labels = to_categorical(train_labels, 10)
test_labels = to_categorical(test_labels, 10)
?
model = Sequential() #創(chuàng)建一個(gè)Sequential模型
# 第一層卷積:6個(gè)卷積核, 大小:5*5, 激活函數(shù):relu
model.add(Conv2D(6, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
# 第二層池化:最大池化
model.add(MaxPooling2D(pool_size=(2, 2)))
# 第三層卷積:16個(gè)卷積核, 大小: 5*5, 激活函數(shù):relu
model.add(Conv2D(16, kernel_size=(5, 5), activation='relu'))
# 第四層池化:最大池化
model.add(MaxPooling2D(pool_size=(2, 2)))
# 進(jìn)行扁平化
model.add(Flatten())
# 全連接層一:輸出節(jié)點(diǎn)為120個(gè)
model.add(Dense(120, activation='relu'))
# 全連接層二:輸出節(jié)點(diǎn)為84個(gè)
model.add(Dense(84, activation='relu'))
# 輸出層:用softmax激活函數(shù)計(jì)算分類的概率
model.add(Dense(10, activation='softmax')) # 最后是10個(gè)數(shù)字,10個(gè)分類
model.compile(optimizer=keras.optimizers.Adam(), loss=keras.metrics.categorical_crossentropy, metrics=['accuracy'])
model.fit(train_images, train_labels, batch_size=32, epochs=2, verbose=1)
loss, accuracy = model.evaluate(test_images, test_labels,verbose=0)
#model.save("A:\\code\\tensorflow\\course\\1_fashion_mnist\\mymodel")
print('損失:', loss)
print('準(zhǔn)確率:', accuracy)
3.訓(xùn)練結(jié)果保存成凍結(jié)模型(pb文件)(train.py),訓(xùn)練結(jié)果保存為凍結(jié)模型的源碼如下:
注:無(wú)需安裝tensorflow也可以運(yùn)行
#以下是生成pb的代碼。注意:用model.save生成的pb文件不能被opencv調(diào)用
# 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=datapath+r"rozen_models",
name="frozen_graph.pb",
as_text=False)
運(yùn)行之后可生成如下圖所示的pb模型:
4.python opencv調(diào)用凍結(jié)模型(cvcallpb.py)
?
import time
model_path = 'frozen_models\\frozen_graph.pb'
config_path = ''
#net = cv.dnn.readNetFromTensorflow(model_path, config_path)
import gzip
import os
import numpy as np
datapath=os.path.split(os.path.realpath(__file__))[0]
import cv2
?
def get_data():
train_image = datapath+r" rain-images-idx3-ubyte.gz"
test_image = datapath+r" 10k-images-idx3-ubyte.gz"
train_label = datapath+r" rain-labels-idx1-ubyte.gz"
test_label = datapath+r" 10k-labels-idx1-ubyte.gz"
paths = [train_label, train_image, test_label,test_image]
?
with gzip.open(paths[0], 'rb') as lbpath:
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
?
with gzip.open(paths[1], 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
?
with gzip.open(paths[2], 'rb') as lbpath:
y_test = np.frombuffer(lbpath.read(), np.uint8, offset=8)
?
with gzip.open(paths[3], 'rb') as imgpath:
x_test = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
?
return (x_train, y_train), (x_test, y_test)
?
(train_images, train_labels), (test_images, test_labels)=get_data()
?
def to_categorical(labels,number):
a=np.zeros((labels.shape[0],number),dtype=labels.dtype)
count=0
for i in labels:
a[count][i]=1
count+=1
return a
print(train_images.shape)
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1)
test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)
train_images = train_images / 255.0
test_images = test_images / 255.0
?
train_labels = to_categorical(train_labels, 10)
test_labels = to_categorical(test_labels, 10)
?
# Load a model imported from Tensorflow
net = cv2.dnn.readNetFromTensorflow(model_path, config_path)
?
a=test_images[0].reshape(1,1,28,28)
?
net.setInput(a)
# Runs a forward pass to compute the net output
networkOutput = net.forward()
print(networkOutput)
?
三、LabVIEW OpenCV DNN實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別
1、實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別并實(shí)現(xiàn)MNIST數(shù)據(jù)簡(jiǎn)單的可視化(mnist_loadpb_simple.vi)
(1)讀取mnist測(cè)試數(shù)據(jù)集二進(jìn)制文件
(2)載入pb神經(jīng)網(wǎng)絡(luò)模型
**(3)從二進(jìn)制文件里讀取某一幅圖并顯示出來(lái) **
(4)blobImage,并把blob的結(jié)果用強(qiáng)度圖顯示出來(lái)
(5)把blob的結(jié)果送入神經(jīng)網(wǎng)絡(luò)推理,獲取結(jié)果
(6)總體源碼及效果如下:
2、實(shí)現(xiàn)手寫(xiě)數(shù)字識(shí)別并實(shí)現(xiàn)MNIST數(shù)據(jù)高級(jí)的可視化(mnist_loadpb.vi)
與簡(jiǎn)單的可視化區(qū)別僅僅有以下幾項(xiàng):
(1)多了getLayerName讀出所有的網(wǎng)絡(luò)層名字
**(2)使用了多通道的forward(輸入為名稱數(shù)組) **
(3)將前六層(兩次卷積——relu——池化用強(qiáng)度圖顯示出來(lái))**
**
總體源碼如下:
運(yùn)行效果如下:
四、源碼下載
鏈接: https://pan.baidu.com/s/1NU_OcHgS0-5zNXQVkEt5uw
提取碼:8888
總結(jié)
Q:我該使用tensorflow 1還是tensorflow 2?
A:目前看tensorflow 1與opencv dnn模塊、樹(shù)莓派等開(kāi)源硬件兼容性更好,且視覺(jué)對(duì)象檢測(cè)的模型暫時(shí)更豐富。Tesnroflow 2的Keras函數(shù)訓(xùn)練神經(jīng)網(wǎng)絡(luò)非常方便,但對(duì)第三方軟硬件兼容性還未做到最佳。估計(jì)隨著后續(xù)版本的推出,TF2會(huì)逐漸成為主流。有些新的神經(jīng)網(wǎng)絡(luò)算子,慢慢地就不支持TF1了。同時(shí)opencv、開(kāi)源硬件也會(huì)不斷更新適應(yīng)最新版本的TF。
另外,訓(xùn)練圖像神經(jīng)網(wǎng)絡(luò)不用局限于TF,pytorch也是很好的選擇。目前我們公司已逐漸從TF轉(zhuǎn)向pytorch了。
Q:LabVIEW的opencv及其dnn模塊支持哪些硬件和神經(jīng)網(wǎng)絡(luò)模型?
A: 提供多種框架模型導(dǎo)入模塊 :包括tensorflow、pytorch、darknet、openvino等多個(gè)平臺(tái)的深度學(xué)習(xí)模型,官方的物體分類、物體檢測(cè)、語(yǔ)義分割、實(shí)例分割都支持(后續(xù)會(huì)講到),第三方的人臉識(shí)別、文字識(shí)別也已經(jīng)通過(guò)驗(yàn)證。少量的高精度實(shí)例分割模型暫時(shí)不支持,后續(xù)我們會(huì)給大家介紹ONNX工具包,支持市面上幾乎所有的模型。 支持的硬件方面,支持Nvidia GPU、Intel、TPU、NPU多種硬件加速。
審核編輯 黃宇
-
LabVIEW
+關(guān)注
關(guān)注
1977文章
3657瀏覽量
325971 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5518瀏覽量
121613 -
dnn
+關(guān)注
關(guān)注
0文章
60瀏覽量
9095
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
手把手教你使用LabVIEW OpenCV dnn實(shí)現(xiàn)物體識(shí)別(Object Detection)含源碼
![<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>使用<b class='flag-5'>LabVIEW</b> <b class='flag-5'>OpenCV</b> <b class='flag-5'>dnn</b><b class='flag-5'>實(shí)現(xiàn)</b>物體<b class='flag-5'>識(shí)別</b>(Object Detection)<b class='flag-5'>含</b><b class='flag-5'>源碼</b>](https://file1.elecfans.com/web2/M00/81/CD/wKgaomQK3JCAIVbMAAn00yrz0ME572.jpg)
評(píng)論