Deep Learningで画像認識してみようと、手持ちのRaspberry Pi 2にUSBカメラを接続してから半年以上、進捗が無いので、とにかく何か動かしてみる。
現在Deep Learningのプラットフォームとして最もメジャーなTensorFlowが公式にRaspberry Piをサポートしているので、まずはTensorFlowを使うことにする。
TensorFlowはpipでインストールできる。筆者のRaspberry Piでは機械学習関係のPython環境はPython 2.7で揃えており、しかしながらPython 3のpipもインストールしており、pipをアップデートするとPython 3のpipが壊れるので、virtualenvを使用して、Python 2.7用のTensorFlowをインストールする。
公式ページの手順に従って、
とすると、.whlファイルのダウンロードが途中で失敗し、virtualenv --system-site-packages -p python2.7 ./venv source ./venv/bin/activate pip install --upgrade pip pip install --upgrade tensorflow
THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.というエラーになった。何度やっても、
pip install --no-cache-dir tensorflow
とやっても、
pip install tensorflow==1.12
などとバージョンを変えても、
時間帯を変えてやっても日を改めても駄目で、他に適当な方法が見つからなかったので、ダウンロードに失敗する.whlをwgetで取得してインストールした。
wget -t 0 https://www.piwheels.org/simple/tensorflow/tensorflow-1.13.1-cp27-none-linux_armv7l.whl pip install tensorflow-1.13.1-cp27-none-linux_armv7l.whl
今回はKeras DocumentationのApplicationのページを参考に、ImageNetで学習済みのモデルで画像認識させる。
同ページの"Classify ImageNet classes with ResNet50"の所にあるコードと、以前に作成したUSBカメラを動かすコードを組み合わせ、ResNet50をより少し小さく少し認識精度が高いとされるInceptionV3に変えて、次のコードにすると、無事に動いた。
from tensorflow.keras.applications.inception_v3 import InceptionV3 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.inception_v3 import preprocess_input, decode_predictions import numpy as np import cv2 model = InceptionV3(weights='imagenet') WINNAME = "Capture" FRAME_INTERVAL = 30 # msec CAPTURE_WIDTH = 1280 CAPTURE_HEIGHT = 720 CENTER_CROP_X1 = int((CAPTURE_WIDTH - CAPTURE_HEIGHT) / 2) CENTER_CROP_X2 = CAPTURE_WIDTH - CENTER_CROP_X1 DISPLAY_WIDTH = 480 DISPLAY_HEIGHT = 480 ret = False while ret == False: cap = cv2.VideoCapture(0) cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, CAPTURE_WIDTH) cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, CAPTURE_HEIGHT) ret, img = cap.read() key = 0 while key != ord('q'): ret, img = cap.read() img = img[:, CENTER_CROP_X1:CENTER_CROP_X2] # crop center square cv2.moveWindow(WINNAME, 0, 0) x = cv2.resize(img, (299, 299)) # input size of InceptionV3 x = image.img_to_array(x) x = x[:, :, [2,1,0]] # BGR -> RGB x = np.expand_dims(x, axis=0) x = preprocess_input(x) preds = model.predict(x) preds = decode_predictions(preds, top=3)[0] img = cv2.resize(img, (DISPLAY_WIDTH, DISPLAY_HEIGHT)) for i in range(3): _, class_name, accuracy = preds[i] if accuracy >= 0.2: print("{} ({:.3f})".format(class_name, accuracy)) cv2.rectangle(img, (0, 20*(i+1)), (200, 20*i), (255, 255, 0), cv2.cv.CV_FILLED) cv2.putText(img, "{} ({:.3f})".format(class_name, accuracy), (0, 20*(i+1)-5), cv2.cv.CV_FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0)) cv2.imshow(WINNAME, img) key = cv2.waitKey(FRAME_INTERVAL) if key == ord('s'): cv2.imwrite('result.jpg', img) cap.release() cv2.destroyAllWindows()
●結果(Raspberry Pi 2 + Webcam C270で実施)
遅いだろうとは思っていたが、2011年製のMacBook Air(Intel Core i5 1.6GHz)でも起動に30秒、画像認識に1フレーム当たり0.5秒くらいかかるが、Raspberry Pi 2(v1.2)だと起動に3分、画像認識5秒くらいかかる。
やってみれば1日か2日でできることだが、この所、この1日や2日が取れない。
Raspberry Piにふさわしい小規模なニューラルネットワークを学習させたり、重み係数を8bitや1bitに量子化して計算量を下げたり、C言語にして高速化したりするのは、いつになることやら...
コメント