树莓派基于tensorflow的数字识别

树莓派基于tensorflow的数字识别
目前博主只试过python3.7.3+tensorflow1.13.1版本,其它tensorflow版本的还没试
一、安装tensorflow环境
  • 检查python环境
1 python3 --version
2 pip3 --version
  • 更新软件源
sudo apt update
sudo apt upgrade
  • 执行安装相应环境
1 sudo apt-get install python3-pip python3-dev
  • 若使用pip3 install tensorflow==1.13.1安装可能需要等待漫长的时间,可以先在网上下载 tensorflow-1.13.1-cp37-none-linux_armv7l.whl,然后复制到树莓派系统上,再执行以下代码可以安装成功
1 sudo pip3 install tensorflow-1.13.1-cp37-none-linux_armv7l.whl
  • 运行以下程序检验环境是否安装成功
import tensorflow as tf
hello = tf.constant(“Hello, World!”)
sess = tf.Session()
print(sess.run(hello))
  • 解决numpy和h5py的依赖
1 sudo apt install libatlas-base-dev
2 sudo apt install libhdf5-dev
3 sudo apt install python-h5py
  • 安装numpy和h5py
1 sudo pip3 install h5py
2 sudo pip3 install numpy
  • 配置opencv2环境
 1 sudo apt-get install build-essential cmake git pkg-config
 2 sudo apt install build-essential cmake git pkg-config libgtk-3-dev libcanberra-gtk*
 3 sudo apt install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev
 4 sudo apt install libjpeg-dev libpng-dev libtiff-dev gfortran openexr libatlas-base-dev opencl-headers
 5 sudo apt install python3-dev python3-numpy libtbb2 libtbb-dev libdc1394-22-dev
 6 sudo apt-get install libjpeg8-dev
 7 sudo apt-get install libtiff5-dev
 8 sudo apt-get install libjasper-dev
 9 sudo apt-get install libpng12-dev
10 sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
11 sudo apt-get install libgtk2.0-dev
12 sudo apt-get install libatlas-base-dev gfortran
  • 安装opencv2
1 // 下载OpenCV
2 sudo apt-get install libopencv-dev
3 sudo apt-get install python-opencv
 
二、程序分析
  • 项目文件结构,生成模型放置在model文件夹,测试数据集在testimage,训练数据集在trainimage,mnist.py为训练模型程序,main.py为部署模型程序
  • mnist.py部分程序分析
    • 导入库(使用tensorflow框架)
1 # -*- coding: UTF-8 -*-
2 import tensorflow as tf
3 import tensorflow.keras as keras
4 from tensorflow.keras import Sequential
5 from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPooling2D, Dropout, MaxPool2D
6 from tensorflow.keras.datasets import mnist
7 from tensorflow.keras import backend as K
8 import json
 
    • 设置参数(batch_size为每次训练所选取的样本数,epochs为训练次数)
1 # 设置参数
2 batch_size = 128
3 num_classes = 10
4 epochs = 10
5  
6 # 输入数据维度
7 img_rows, img_cols = 28, 28
    •  加载数据集
 1 # 加载数据集,调用库中已有mnist数据集from tensorflow.keras.datasets import mnist
 2 (x_train, y_train), (x_test, y_test) = mnist.load_data()
 3 
 4 if K.image_data_format() == 'channels_first':
 5     x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
 6     x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
 7     input_shape = (1, img_rows, img_cols)
 8 else:
 9     x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
10     x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
11     input_shape = (img_rows, img_cols, 1)
12     
13 x_train = x_train.astype('float32') / 255
14 x_test = x_test.astype('float32') / 255
    • 构造神经网络模型(损失函数使用交叉熵损失函数,优化器使用adam,衡量模型指标为准确率)
 1 # 构建网络
 2 model = Sequential()
 3 # 第一个卷积层,32个卷积核,大小5x5,卷积模式SAME,激活函数relu,输入张量的大小
 4 model.add(Conv2D(filters=32, kernel_size=(5, 5), padding='Same', activation='relu',
 5                  input_shape=(28, 28, 1)))
 6 model.add(Conv2D(filters=32, kernel_size=(5, 5), padding='Same', activation='relu'))
 7 # 池化层,池化核大小2x2
 8 model.add(MaxPool2D(pool_size=(2, 2)))
 9 # 随机丢弃四分之一的网络连接,防止过拟合
10 model.add(Dropout(0.25))
11 model.add(Conv2D(filters=64, kernel_size=(3, 3), padding='Same', activation='relu'))
12 model.add(Conv2D(filters=64, kernel_size=(3, 3), padding='Same', activation='relu'))
13 model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
14 model.add(Dropout(0.25))
15 # 全连接层,展开操作,
16 model.add(Flatten())
17 # 添加隐藏层神经元的数量和激活函数
18 model.add(Dense(256, activation='relu'))
19 model.add(Dropout(0.25))
20 # 输出层
21 model.add(Dense(10, activation='softmax'))
22 model.summary()
23 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    • 模型训练
1 model.fit(x_train, y_train, batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(x_test, y_test))
2 score = model.evaluate(x_test, y_test, verbose=0)
3 print('Test loss:', score[0])
4 print('Test accuracy:', score[1])
    • 模型及其参数保存(保存格式为h5)
1 with open('model.json', 'w') as outfile:
2     json.dump(model.to_json(), outfile)
3  
4 model_file = 'model.h5'
5 model.save(model_file)
 
  • 部署模型程序分析
    • 导入库(numpy、tensorflow、matplotlib、cv2、picamera)
 1 # -*- coding: UTF-8 -*-
 2 import numpy as np
 3 import tensorflow as tf
 4 import tensorflow.keras as keras
 5 from tensorflow.keras.preprocessing.image import img_to_array, load_img
 6 import matplotlib.pyplot as plt
 7 import matplotlib.image as mpimg
 8 from PIL import Image
 9 import cv2
10 import os
11 from picamera import PiCamera
12 from time import sleep
 
    • 加载模型model.h5
1 #load model
2 model_file = './model/model.h5'
3 model_file = model_file
4 print(type(model_file))
5 global model
6 model = keras.models.load_model(model_file)
 
    • 调用picamera库来连接树莓派的摄像头,并通过摄像头拍摄一张分辨率为480*480的图片,将其保存至“/home/pi/Desktop/camera/tf_keras_mnist/image_28.jpg”
 1 # 调用打开摄像头库
 2 camera = PiCamera()
 3 # 设置照片分辨率为480*480
 4 camera.resolution = (480, 480)
 5 camera.start_preview()
 6 sleep(2)
 7 camera.capture('/home/pi/Desktop/camera/tf_keras_mnist/image_28.jpg')
 8 camera.stop_preview()
 9 print("Collect Image Finish!")
10 img_file = './image_28.jpg'
 
    • 读取“./image_28.jpg”位置的图片,并将其分辨率更改为28*28,使得满足模型参数输入要求
1 img_array = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE)
2 resized_image = cv2.resize(img_array, (28, 28))
3  
4 img = Image.fromarray(np.uint8(resized_image))
5 img.save('output.jpg')
6 img = mpimg.imread(img_file)
 
    • 把28*28分辨率的图片通过img_to_array把其矩阵中的参数由整数值变为浮点数的数组,再把所得数组放进已训练好的模型中,最后将会输出一个预测值
1 img = img_to_array(load_img(img_file, target_size=(28, 28), color_mode="grayscale")) / 255.
2 img = np.expand_dims(img, axis=0)
3 code = model.predict_classes(img)[0]
4 print("Predict Result: ", code)
 
 全代码区
 1 # -*- coding: UTF-8 -*-
 2 import numpy as np
 3 import tensorflow as tf
 4 import tensorflow.keras as keras
 5 from tensorflow.keras.preprocessing.image import img_to_array, load_img
 6 import matplotlib.pyplot as plt
 7 import matplotlib.image as mpimg
 8 from PIL import Image
 9 import cv2
10 import os
11 from picamera import PiCamera
12 from time import sleep
13 
14 #load model
15 model_file = './model/model.h5'
16 model_file = model_file
17 print(type(model_file))
18 global model
19 model = keras.models.load_model(model_file)
20 
21 
22 def preditc():
23     print("Get ready to capture images and place the camera")
24     count = 5
25     while count >= 1:
26         print("Count Down: ", count, "s")
27         count = count - 1
28         sleep(1)
29 
30     # 调用打开摄像头库
31     camera = PiCamera()
32     # 设置照片分辨率为480*480
33     camera.resolution = (480, 480)
34     camera.start_preview()
35     sleep(2)
36     camera.capture('/home/pi/Desktop/camera/tf_keras_mnist/image_28.jpg')
37     camera.stop_preview()
38     print("Collect Image Finish!")
39     img_file = './image_28.jpg'
40 
41     img_array = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE)
42     resized_image = cv2.resize(img_array, (28, 28))
43 
44     img = Image.fromarray(np.uint8(resized_image))
45     img.save('output.jpg')
46     img = mpimg.imread(img_file)
47 
48     img = img_to_array(load_img(img_file, target_size=(28, 28), color_mode="grayscale")) / 255.
49     img = np.expand_dims(img, axis=0)
50     code = model.predict_classes(img)[0]
51     print("Predict Result: ", code)
52 
53     plt.imshow(np.real(img).squeeze())
54     plt.show()
55 
56 
57 # 主函数
58 if __name__ == '__main__':
59     preditc()

 

posted @ 2020-12-22 22:14  .ivan  阅读(2175)  评论(5编辑  收藏  举报