樹莓派基於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
-
構造神經網絡模型(損失函數使用交叉熵損失函數,優化器使用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'])
-
模型及其參數保存(保存格式為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()