背景
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 件のコメント :
コメントを投稿