手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)
@
前言
今天和大家一起来看一下在LabVIEW中如何使用OpenCV DNN模块实现手写数字识别
一、OpenCV DNN模块
1.OpenCV DNN简介
OpenCV中的DNN(Deep Neural Network module)模块是专门用来实现深度神经网络相关功能的模块。OpenCV自己并不能训练神经网络模型,但是它可以载入别的深度学习框架(例如TensorFlow、pytorch、Caffe等等)训练好的模型,然后使用该模型做inference(预测)。而且OpenCV在载入模型时会使用自己的DNN模块对模型重写,使得模型的运行效率更高。所以如果你想在OpenCV项目中融入深度学习模型,可以先用自己熟悉的深度学习框架训练好,然后使用OpenCV的DNN模块载入。
2.LabVIEW中DNN模块函数
DNN模块位于程序框图-函数选板-Addons-VIRobotics-opencv_yiku中,如下图所示:

Net选版中的函数与python中的函数对比如下:




二、TensorFlow pb文件的生成和调用
1.TensorFlow2 Keras模型(mnist)
注:本范例必须使用tensorflow 2.x版本
如下图所示所示为数据集以及LabVIEW与Python推理和训练代码,相关源码可在链接中下载。

2.使用Keras搭建cnn训练mnist(train.py),训练部分源码如下:
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() #创建一个Sequential模型
# 第一层卷积:6个卷积核, 大小:5*5, 激活函数:relu
model.add(Conv2D(6, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
# 第二层池化:最大池化
model.add(MaxPooling2D(pool_size=(2, 2)))
# 第三层卷积:16个卷积核, 大小: 5*5, 激活函数:relu
model.add(Conv2D(16, kernel_size=(5, 5), activation='relu'))
# 第四层池化:最大池化
model.add(MaxPooling2D(pool_size=(2, 2)))
# 进行扁平化
model.add(Flatten())
# 全连接层一:输出节点为120个
model.add(Dense(120, activation='relu'))
# 全连接层二:输出节点为84个
model.add(Dense(84, activation='relu'))
# 输出层:用softmax激活函数计算分类的概率
model.add(Dense(10, activation='softmax')) # 最后是10个数字,10个分类
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('准确率:', accuracy)

3.训练结果保存成冻结模型(pb文件)(train.py),训练结果保存为冻结模型的源码如下:
注:无需安装tensorflow也可以运行
#以下是生成pb的代码。注意:用model.save生成的pb文件不能被opencv调用
# 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"\frozen_models",
name="frozen_graph.pb",
as_text=False)
运行之后可生成如下图所示的pb模型:

4.python opencv调用冻结模型(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"\train-images-idx3-ubyte.gz"
test_image = datapath+r"\t10k-images-idx3-ubyte.gz"
train_label = datapath+r"\train-labels-idx1-ubyte.gz"
test_label = datapath+r"\t10k-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实现手写数字识别
1、实现手写数字识别并实现MNIST数据简单的可视化(mnist_loadpb_simple.vi)
(1)读取mnist测试数据集二进制文件

(2)载入pb神经网络模型

(3)从二进制文件里读取某一幅图并显示出来

(4)blobImage,并把blob的结果用强度图显示出来

(5)把blob的结果送入神经网络推理,获取结果

(6)总体源码及效果如下:


2、实现手写数字识别并实现MNIST数据高级的可视化(mnist_loadpb.vi)
与简单的可视化区别仅仅有以下几项:
(1)多了getLayerName读出所有的网络层名字

(2)使用了多通道的forward(输入为名称数组)
(3)将前六层(两次卷积——relu——池化用强度图显示出来)

总体源码如下:

运行效果如下:

四、源码下载
链接:https://pan.baidu.com/s/1NU_OcHgS0-5zNXQVkEt5uw
提取码:8888
总结
Q:我该使用tensorflow 1还是tensorflow 2?
A:目前看tensorflow 1与opencv dnn模块、树莓派等开源硬件兼容性更好,且视觉对象检测的模型暂时更丰富。Tesnroflow 2的Keras函数训练神经网络非常方便,但对第三方软硬件兼容性还未做到最佳。估计随着后续版本的推出,TF2会逐渐成为主流。有些新的神经网络算子,慢慢地就不支持TF1了。同时opencv、开源硬件也会不断更新适应最新版本的TF。
另外,训练图像神经网络不用局限于TF,pytorch也是很好的选择。目前我们公司已逐渐从TF转向pytorch了。
Q:LabVIEW的opencv及其dnn模块支持哪些硬件和神经网络模型?
A:提供多种框架模型导入模块:包括tensorflow、pytorch、darknet、openvino等多个平台的深度学习模型,官方的物体分类、物体检测、语义分割、实例分割都支持(后续会讲到),第三方的人脸识别、文字识别也已经通过验证。少量的高精度实例分割模型暂时不支持,后续我们会给大家介绍ONNX工具包,支持市面上几乎所有的模型。 支持的硬件方面,支持Nvidia GPU、Intel、TPU、NPU多种硬件加速。
更多关于LabVIEW与人工智能技术,可添加技术交流群进一步探讨。qq群号:705637299,请备注暗号:LabVIEW 机器学习
手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)的更多相关文章
- OpenCV+TensorFlow图片手写数字识别(附源码)
初次接触TensorFlow,而手写数字训练识别是其最基本的入门教程,网上关于训练的教程很多,但是模型的测试大多都是官方提供的一些素材,能不能自己随便写一串数字让机器识别出来呢?纸上得来终觉浅,带着这 ...
- 手把手教你使用LabVIEW OpenCV dnn实现图像分类(含源码)
@ 目录 前言 一.什么是图像分类? 1.图像分类的概念 2.MobileNet简介 二.使用python实现图像分类(py_to_py_ssd_mobilenet.py) 1.获取预训练模型 2.使 ...
- 手把手教你使用LabVIEW OpenCV dnn实现物体识别(Object Detection)含源码
前言 今天和大家一起分享如何使用LabVIEW调用pb模型实现物体识别,本博客中使用的智能工具包可到主页置顶博客LabVIEW AI视觉工具包(非NI Vision)下载与安装教程中下载 一.物体识别 ...
- keras和tensorflow搭建DNN、CNN、RNN手写数字识别
MNIST手写数字集 MNIST是一个由美国由美国邮政系统开发的手写数字识别数据集.手写内容是0~9,一共有60000个图片样本,我们可以到MNIST官网免费下载,总共4个.gz后缀的压缩文件,该文件 ...
- 基于OpenCV的KNN算法实现手写数字识别
基于OpenCV的KNN算法实现手写数字识别 一.数据预处理 # 导入所需模块 import cv2 import numpy as np import matplotlib.pyplot as pl ...
- 基于opencv的手写数字识别(MFC,HOG,SVM)
参考了秋风细雨的文章:http://blog.csdn.net/candyforever/article/details/8564746 花了点时间编写出了程序,先看看效果吧. 识别效果大概都能正确. ...
- opencv实现KNN手写数字的识别
人工智能是当下很热门的话题,手写识别是一个典型的应用.为了进一步了解这个领域,我阅读了大量的论文,并借助opencv完成了对28x28的数字图片(预处理后的二值图像)的识别任务. 预处理一张图片: 首 ...
- Pytorch入门——手把手教你MNIST手写数字识别
MNIST手写数字识别教程 要开始带组内的小朋友了,特意出一个Pytorch教程来指导一下 [!] 这里是实战教程,默认读者已经学会了部分深度学习原理,若有不懂的地方可以先停下来查查资料 目录 MNI ...
- 【YOLOv5】手把手教你使用LabVIEW ONNX Runtime部署 TensorRT加速,实现YOLOv5实时物体识别(含源码)
前言 上一篇博客给大家介绍了LabVIEW开放神经网络交互工具包[ONNX],今天我们就一起来看一下如何使用LabVIEW开放神经网络交互工具包实现TensorRT加速YOLOv5. 以下是YOLOv ...
随机推荐
- 【Unity基础知识】认识常用的生命周期函数(Awake、Start、Update...)
一.了解帧的概念 游戏的本质就是一个死循环 每一次循环都会处理游戏逻辑 并 更新一次游戏画面 之所以能看到画面在动 是因为 切换画面速度达到一定速度时 人眼就会认为画面是动态且流畅的 一帧就是执行了一 ...
- 基于cornerstone.js的dicom医学影像查看浏览功能
最近由于项目需求,需要医学影像.dcm文件的预览功能,功能完成后,基于原生Demo做一个开源分享. 心急的小伙伴可以先看如下基于原生js的全部代码: 一.全部代码 <!DOCTYPE html& ...
- Bert不完全手册6. Bert在中文领域的尝试 Bert-WWM & MacBert & ChineseBert
一章我们来聊聊在中文领域都有哪些预训练模型的改良方案.Bert-WWM,MacBert,ChineseBert主要从3个方向在预训练中补充中文文本的信息:词粒度信息,中文笔画信息,拼音信息.与其说是推 ...
- BI报表与数据开发
先贴个不好看的图让内容好看一点,也顺便说一下数据处理的流程:收集数据,数据清洗与数据加工,数据展示 报表制作一般就是前面的开发兄弟们完成然后把数据交到报表的兄弟们,然后在根据领导要求制作报表.大概就是 ...
- YII总结学习7(在一个视图中显示另外一个视图)
controller\hello <?php namespace app\controllers; use yii\web\Controller; class helloController e ...
- 回溯、贪心、DP的区别和联系
四大常用算法:分治.贪心.回溯.动态规划 回溯算法是个"万金油".基本上能用跟动态规划.贪心解决的问题,都可以用回溯去解决.回溯算法相当于穷举搜索,穷举所有情况,然后得到最优解.不 ...
- 【Prometheus+Grafana系列】监控MySQL服务
前言 前面的一篇文章已经介绍了 docker-compose 搭建 Prometheus + Grafana 服务.当时实现了监控服务器指标数据,是通过 node_exporter.Prometheu ...
- 从零开始搭建react基础开发环境(基于webpack5)
前言 最近利用闲暇时间把webpack系统的学习了下,搭建出一个react环境的脚手架,写篇文章总结一下,帮助正在学习webpack小伙伴们,如有写的不对的地方或还有可以优化的地方,望大佬们指出,及时 ...
- 窗口部件-基础窗口部件 QWidget
1 基础窗口部件 QWidget QWidget 类是所有用户界面对象的基类,被称为基础窗口部件.不多废话直接看代码 main.cpp 如下 #include<QtWidgets> int ...
- 基于Vue的前端UI组件库的比对和选型
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 由于录制视频的需要,要做前端UI组件库的选型.平时国内外也见了不少基于Vue的UI ...