目 录
摘要 I
ABSTRACT II
1 绪论 1
1.1 数字识别研究现状 1
1.2 深度学习的发展与现状 1
1.3 研究意义 2
1.4 论文结构 3
2 卷积神经网络基本原理 4
2.1 卷积神经网络 4
2.1.1 卷积神经网络概述 4
2.1.2 卷积神经网络的重要组成部分 4
2.1.3 权值共享和局部连接 5
2.2 神经网络的前向传播和反向传播 6
2.2.1 神经元 6
2.2.2 神经网络的连接形式 7
2.2.3 神经网络的前向传播 8
2.2.4 神经网络的反向传播算法 8
2.3 优化方法——梯度下降 9
2.3.1 批梯度下降 9
2.3.2 随机梯度下降 11
2.3.3 小批量梯度下降 11
2.4 小结 11
3 Keras深度学习框架 12
3.1 Keras简介 12
3.2 Keras编程 12
3.2.1 Keras模型构建 12
3.2.2 Keras常用函数及用法 12
3.3 Keras环境配置 13
3.4 小结 14
4 经典LeNet-5实验探究 15
4.1 数据集MNIST介绍 15
4.2 LeNet-5实现 16
4.2.1 LeNet-5介绍 16
4.2.2 LeNet实现 16
4.3 模型探究 18
4.3.1 不同网络结构 18
4.3.2 卷积核大小数量 20
4.3.2 权值初始化 22
4.3.3 激活函数选择 24
4.4 小结 26
5 手写数字识别算法应用实践 27
5.1 OpenCV图像处理部分 27
5.1.1 OpenCV介绍 27
5.1.2 OpenCV安装配置 27
5.1.3 寻找数字 28
5.1.4 数字处理 32
5.2 实现摄像头的手写数字实时识别 33
5.2.1 手写数字识别模型训练 33
5.2.2 模型的保存与调用 35
5.2.3 结果 36
5.3小结 36
6 总结 38
致 谢 39
参考文献 40
5 手写数字识别算法应用实践
本文将用训练好的高识别率手写数字模型应用到摄像头实现对镜头画面中数字的实时识别。本章将介绍如何使用计算机视觉库OpenCV调用电脑摄像头、找到帧画面中的数字并对数字进行识别前的处理,最后调用训练好的手写数字模型将识别结果在原帧画面中显示出来。
5.1 OpenCV图像处理部分
5.1.1 OpenCV介绍
OpenCV是一个开源的跨平台计算机视觉库,它可在Linux、Windows和Mac OS操作系统上运行。因为由C和C++编写,所以它很高效,并且提供了许多其他语言的接口如Python、Ruby、MATLAB等。OpenCV的功能有基本的图像处理如去燥、边缘检测、角点检测、色彩变化等。
本文将运用部分OpenCV的功能,调取电脑自带的摄像头,对每一帧的画面进行处理,在画面中找到数字并截取出来,调用数字识别模型进行识别,并用矩形框出每个数字把识别结果标注在旁边。
5.1.2 OpenCV安装配置
(1)安装依赖包
依赖包包含了linux程序在安装、运行中所必须的相关编译工具、安装工具等。程序本身并不包含这些需要的库,在不重复造轮子的前提下,程序在运行中相应的功能时会需要调用相应的库。如本文所使用的OpenCV需要对Python不同版本的支持、对图片视频读写的支持等。
sudo apt-get install --assume-yes build-essential cmake git
sudo apt-get install --assume-yes build-essential pkg-config unzip ffmpeg qtbase5-dev python-dev python3-dev python-numpy python3-numpy
sudo apt-get install --assume-yes libOpenCV-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev
sudo apt-get install --assume-yes libavcodec-dev libavformat-dev libswscale-dev libxine2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt-get install --assume-yes libv4l-dev libtbb-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev
sudo apt-get install --assume-yes libvorbis-dev libxvidcore-dev v4l-utils
(2)编译
在当前目录下创建build文件夹,进入build文件夹,配置编译选项,最后执行编译命令。
mkdir build
cd build/
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=O -D WITH_OPENGL=ON -D WITH_CUBLAS=ON -D CUDA_NVCC_FLAGS=“-D_FORCE_INLINES”
make -j
(
(
((
(((nproc) + 1))
(3)安装
以root权限执行安装命令make install,利用输出重定向,创建OpenCV相关动态链接库配置文件,使用动态库管理命令ldconfig,让OpenCV的相关链接库被系统共享,最后更新系统源。
sudo make install
sudo /bin/bash -c ‘echo “/usr/local/lib” > /etc/ld.so.conf.d/OpenCV.conf’
sudo ldconfig
sudo apt-get update
(4)检查安装
以root权限执行安装checkinstall,执行checkinstall命令检查安装。
sudo apt-get install checkinstall
sudo checkinstall
(5)确认安装
进入Python解释器输入“import cv2”无报错即成功安装。
5.1.3 寻找数字
(1)方案选择
要进行数字识别,首先要让程序能够寻找到画面中的数字。安装好的OpenCV中有自带的分类器,但是很不幸的是自带的分类器仅有关于人脸识别方向的,如果是做人脸识别方向的研究使用该分类器将会非常方便。至此,本文需要自己开发一个寻找数字的分类器或程序。有两种方案,一是训练一个关于数字识别的级联分类器,二是直接对画面中的元素进行寻找。方案一训练一个级联分类器并不容易,它需要准备正负两种样本。正样本中全是不同字体数字的图片集合,负样本要求是与数字可能出现的场景中非数字本身的物品图片集合。该方案适用于对识别要求严格的商业级软件开发。本文转载自http://www.biyezuopin.vip/onews.asp?id=14623方案二相对于方案二适用于比较简单的测试环境,可以容忍一定识别误差。训练级联分类器对于负样本要求的范围广泛,数据量巨大。与深度学习目前所遇到的问题一样,虽然目前有大数据的支持,但是数据的标注代价是巨大的。本文以研究学习为目的且最终测试的环境简单,所以采用第二种方案。
#coding=utf-8importcv2importnumpy as np
def where_num(frame):
rois =[]
# 灰度处理
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
element = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
# 二次腐蚀处理
gray2 = cv2.dilate(gray, element)
gray3 = cv2.dilate(gray2, element)#cv2.imshow("dilate", gray3)
# 二次膨胀处理
gray2 = cv2.erode(gray2, element)
gray2 = cv2.erode(gray2, element)#cv2.imshow("erode", gray2)
# 膨胀腐蚀做差
edges = cv2.absdiff(gray, gray2)#cv2.imshow("absdiff", edges)
# 使用算子进行降噪
x = cv2.Sobel(edges, cv2.CV_16S,1,0)
y = cv2.Sobel(edges, cv2.CV_16S,0,1)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
dst = cv2.addWeighted(absX,0.5, absY,0.5,0)#cv2.imshow("sobel", dst)
# 选择阀值对图片进行二值化处理
ret_1, ddst = cv2.threshold(dst,50,255, cv2.THRESH_BINARY)
# 寻找图片中出现过得轮廓
im, contours, hierarchy = cv2.findContours(
ddst, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 在保存的轮廓里利用宽度和高度进行筛选
for c in contours:
x, y, w, h = cv2.boundingRect(c)if w >12and h >24:
rois.append((x, y, w, h))return rois
def resize_image(image, height=28, width=28):
top, bottom, left, right =(0,0,0,0)
h, w, _ = image.shape
longest_edge =max(h, w)if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
right = dw - left
else:
pass
BLACK =[0,0,0]
ret, thresh2 = cv2.threshold(image,170,255, cv2.THRESH_BINARY_INV)
constant = cv2.copyMakeBorder(
thresh2, top, bottom, left, right, cv2.BORDER_CONSTANT, value=BLACK)
onstant = cv2.copyMakeBorder(
constant,30,20,20,20, cv2.BORDER_CONSTANT, value=0)return cv2.resize(onstant,(height, width))
image = cv2.imread('./test.jpg')
num =where_num(image)
x, y, w, h = num[0]
num7 = image[y:y + h, x:x + w]
num1 =resize_image(num7)
print num1.shape
cv2.imshow('num1', num1)
num3 = cv2.imread('./test7.jpeg')
print num3.shape
cv2.imshow('num3', num3)#forr in num:#x, y, w, h = r#numimage= image[y:y + h, x:x + w]#cv2.rectangle(image,(x, y),(x + w, y + h),(0,255,0),2)#cv2.imshow('thenum', numimage)
cv2.waitKey(0)
cv2.destroyAllWindows()
版权归原作者 biyezuopinvip 所有, 如有侵权,请联系我们删除。