背景
ideinさんのデモの真似です。以前の記事でLCDの使い方と、OpenCVのDNNモジュールでMobileNetを利用した物体判別をする方法を学びました。
学んだことを組み合わせて、物体認識装置を作りました。
備忘録を兼ねて、内容を共有します。
使ったもの
下記2つの記事の内容を実行できるRaspberry Piを使います。Raspberry Piに0.96インチのLCDを付けて、カメラの画像を表示してみた
OpenCVのDNNモジュールをPythonで呼び出し、MobileNetを利用した物体認識をしてみた
プログラムの説明
こちらのプログラムを実行します。
mobilenet_picamera_display.py
import io, picamera, pygame, sys, os import argparse import cv2 import numpy as np from cv2 import dnn from pygame.locals import * os.environ["SDL_FBDEV"] = "/dev/fb1" parser = argparse.ArgumentParser() parser.add_argument("--video", help="number of video device", default=0) parser.add_argument("--prototxt", default="mobilenet_v2_deploy.prototxt") parser.add_argument("--caffemodel", default="mobilenet_v2.caffemodel") parser.add_argument("--classNames", default="synset.txt") args = parser.parse_args() width = 480 height= 640 camera = picamera.PiCamera() camera.resolution = (width, height) camera.rotation = 90 offset = 22 net = dnn.readNetFromCaffe(args.prototxt, args.caffemodel) f = open(args.classNames, 'r') rawClassNames = f.readlines() classNames = [] for nameStr in rawClassNames: spaceIndex = nameStr.find(' ') nameStr = nameStr[spaceIndex:-2] classNames.append(nameStr) inWidth = 224 inHeight = 224 inScaleFactor = 0.017 meanVal = (103.94, 116.78, 123.68) resultText = None pygame.init() screen = pygame.display.set_mode((160, 124), 0, 32) screen.fill(0) basicfont = pygame.font.SysFont(None, 15) # run the game loop while True: screen.fill(0) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() frame = np.empty((width * height * 3), dtype=np.uint8) camera.capture(frame, format='rgb') frame = frame.reshape((height, width, 3)) blob = dnn.blobFromImage(frame, inScaleFactor, (inWidth, inHeight), meanVal) net.setInput(blob) detections = net.forward() maxClassId = 0 maxClassPoint = 0; for i in range(detections.shape[1]): classPoint = detections[0, i, 0, 0] if (classPoint > maxClassPoint): maxClassId = i maxClassPoint = classPoint img = pygame.image.frombuffer(frame.tobytes(), (width, height), 'RGB') img = pygame.transform.scale(img, (int(img.get_width() * 80 / img.get_height()), 80)) screen.blit(img, (0, offset)) if (resultText != None): screen.fill((0, 0, 0), resultText.get_rect()) print("class id: ", maxClassId) print("class point: ", maxClassPoint) print("name: ", classNames[maxClassId]) resultText = basicfont.render(classNames[maxClassId], True, (255, 255, 255)) textrect = resultText.get_rect() textrect.left = img.get_width() textrect.centery = screen.get_rect().centery screen.blit(resultText, textrect) pygame.display.update()
「使ったもの」で紹介した記事で触れていない部分をところどころ解説します。
表示領域が制限されるので、クラス名の先頭に付けられているidのような文字列を削除しました。
f = open(args.classNames, 'r') rawClassNames = f.readlines() classNames = [] for nameStr in rawClassNames: spaceIndex = nameStr.find(' ') nameStr = nameStr[spaceIndex:-2] classNames.append(nameStr)
numpyの空の領域を用意し、そこへPicameraからのrgb形式の画像データを書き込んでいます。
frame = np.empty((width * height * 3), dtype=np.uint8) camera.capture(frame, format='rgb') frame = frame.reshape((height, width, 3))
動作確認
LCDを起動します。modprobe fbtft_device name=adafruit18 gpios=reset:22,dc:27,cs:3 rotate=90
mkdir ~/gitprojects cd ~/gitprojects git clone https://github.com/asukiaaa/raspi_mobilenet_display.git cd raspi_mobilenet_display sudo python3 mobilenet_picamera_display.py
0.2fps(5秒に1回更新)位で処理を行う、物体認識装置ができました。
自動起動設定
下記のような記述を/etc/rc.localに追加すると、Raspberry Pi起動後に物体認識プログラムが動き始めます。フルパスを指定してプログラムを実行する場合、関連ファイルのパスがずれてしまうため、それぞれのファイルもフルパスで指定しています。
/etc/rc.local
modprobe fbtft_device name=adafruit18 gpios=reset:22,dc:27,cs:3 rotate=90 python3 /home/pi/gitprojects/raspi_mobilenet_display/mobilenet_picamera_display.py \ --prototxt=/home/pi/gitprojects/raspi_mobilenet_display/mobilenet_v2_deploy.prototxt \ --caffemodel=/home/pi/gitprojects/raspi_mobilenet_display/mobilenet_v2.caffemodel \ --classNames=/home/pi/gitprojects/raspi_mobilenet_display/synset.txt &
まとめ
0.2fps位で動く物体認識装置を作れました。ideinさんのデモのようなスムーズな処理にはかないませんが、似たものを作れたので個人的に満足です。
何かの参考になれば嬉しいです。
参考
Raspberry Piに0.96インチのLCDを付けて、カメラの画像を表示してみたOpenCVのDNNモジュールをPythonで呼び出し、MobileNetを利用した物体認識をしてみた
Capturing to an OpenCV object | Picamera
0 件のコメント :
コメントを投稿