手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)

简介: 今天和大家一起来看一下在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中,如下图所示:
image.png

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

image.png

image.png

image.png

二、TensorFlow pb文件的生成和调用

1.TensorFlow2 Keras模型(mnist)

注:本范例必须使用tensorflow 2.x版本

如下图所示所示为数据集以及LabVIEW与Python推理和训练代码,相关源码可在链接中下载。

image.png

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)

image.png

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模型:

image.png

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)

image.png

三、LabVIEW OpenCV DNN实现手写数字识别

1、实现手写数字识别并实现MNIST数据简单的可视化(mnist_loadpb_simple.vi)

(1)读取mnist测试数据集二进制文件
image.png

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

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

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

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

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

image.png

2、实现手写数字识别并实现MNIST数据高级的可视化(mnist_loadpb.vi)

与简单的可视化区别仅仅有以下几项:

(1)多了getLayerName读出所有的网络层名字
image.png

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

总体源码如下:
image.png

运行效果如下:
image.png

四、源码下载

链接:https://pan.baidu.com/s/1NU_OcHgS0-5zNXQVkEt5uw
提取码:8888

目录
相关文章
|
7月前
|
算法 API 计算机视觉
[opencv学习笔记] jiazhigang 30讲源码C++版本(含Makefile)
[opencv学习笔记] jiazhigang 30讲源码C++版本(含Makefile)
82 0
|
7月前
|
算法 计算机视觉 开发者
OpenCV中使用Eigenfaces人脸识别器识别人脸实战(附Python源码)
OpenCV中使用Eigenfaces人脸识别器识别人脸实战(附Python源码)
386 0
|
2月前
|
机器学习/深度学习 监控 算法
基于计算机视觉(opencv)的运动计数(运动辅助)系统-源码+注释+报告
基于计算机视觉(opencv)的运动计数(运动辅助)系统-源码+注释+报告
67 3
|
7月前
|
计算机视觉 Python
OpenCV获取视频文件的属性并动态显示实战(附Python源码)
OpenCV获取视频文件的属性并动态显示实战(附Python源码)
116 0
|
2月前
|
缓存 并行计算 Ubuntu
Jetson 学习笔记(十一):jetson agx xavier 源码编译ffmpeg(3.4.1)和opencv(3.4.0)
本文是关于在Jetson AGX Xavier上编译FFmpeg(3.4.1)和OpenCV(3.4.0)的详细教程,包括编译需求、步骤、测试和可能遇到的问题及其解决方案。还提供了Jetson AGX Xavier编译CUDA版本的OpenCV 4.5.0的相关信息。
93 4
Jetson 学习笔记(十一):jetson agx xavier 源码编译ffmpeg(3.4.1)和opencv(3.4.0)
|
2月前
|
Ubuntu 应用服务中间件 nginx
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
本文是关于Ubuntu系统中使用ffmpeg 3.2.16源码编译OpenCV 3.4.0的安装笔记,包括安装ffmpeg、编译OpenCV、卸载OpenCV以及常见报错处理。
219 2
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
|
2月前
|
Ubuntu 编译器 计算机视觉
Ubuntu系统编译OpenCV4.8源码
【10月更文挑战第17天】只要三步即可搞定,第一步是下载指定版本的源码包;第二步是安装OpenCV4.8编译需要的编译器与第三方库支持;第三步就是编译OpenCV源码包生成安装文件并安装。
|
5月前
|
Ubuntu 编译器 计算机视觉
Ubuntu系统下编译OpenCV4.8源码
在Ubuntu上源码安装OpenCV 4.8分为三步:1) 下载源码包,使用`wget`命令;2) 安装依赖,如`g++`, `cmake`, `make`等;3) 创建编译目录,运行`cmake`配置,接着`make`编译,最后`sudo make install`安装。安装完成后,通过编写和运行一个简单的OpenCV C++程序来验证环境配置正确性。
164 10
|
5月前
|
计算机视觉 iOS开发 C++
【OpenCV】在MacOS上源码编译OpenCV
【7月更文挑战第9天】在MacOS上源码编译OpenCV需分步进行: 1. 准备工作: 安装Xcode, Command Line Tools及依赖如CMake, Homebrew. 2. 获取OpenCV源码: 从官网下载并解压所需版本. 3. 编译OpenCV. 4. 安装OpenCV: 编译后使用`sudo make install`进行安装. 5. 验证安装: 编写简单C++程序测试OpenCV功能, 如读取并显示图片.
198 1
|
7月前
|
XML 算法 计算机视觉
使用OpenCV进行人脸检测和戴墨镜特效实战(附Python源码)
使用OpenCV进行人脸检测和戴墨镜特效实战(附Python源码)
350 1