AITCシニア勉強会

Raspberry Piで画像認識をしてみよう
2021年2月26日
先端IT活用推進コンソーシアム
クラウド・テクノロジー活用部会
リーダー 荒本道隆

今日のスケジュール
各自のラズパイ上で、各サンプルプログラムを実行
 OpenCV の解説＆モロモロ：20分
 OpenCV で、顔検出：30分
 posenet で、姿勢検出：20分
 yolov5 で、物体検出：20分
 3月のハッカソンのご相談：30分
事前準備がまだの人は、今から実行してください
cd
wget http://cloud.aitc.jp/20210226_RaspberryPi4/install.txt
bash ./install.txt# 約45分2

インストール作業の解説
 install.txt の作り方

◦ 手順をテキストファイルに順番に書いた
 人力で、最小のステップでできるように最適化
 できるだけ人手を介さないように「-y」を付けた
 ラズパイのOSを真っ新にして、何度もテスト実行◦ 今回の写経は、python に集中 一番大変だったのは◦ 姿勢検出を４種類試し、ラズパイで動作したのは１種類◦ 以前は動いた手順が、使えなくなっていた◦ yolov5 は、直前でサンプルの一部が変わった
3

顔検出とは
 画像から人間の顔を検出する◦ OpenCV では「顔の中の目」も検出できる◦ OpenCV には、ネコの顔の検出器も入っている haarcascade_frontalcatface_extended.xml

 「顔識別」の準備に、顔だけを撮影するのに便利4姿勢検出とは
 画像から人のスケルトン（実際の骨じゃない）を検出する◦ 本家OpenPoseでは、
 GPUパワーがあれば、指や顔のパーツも検出可能

5

物体検出とは
 画像から物体を検出する◦ 学習済の物体じゃないと検出できない
 学習させるためには、対象の画像データが大量に必要 → 様々なオープンデータがある◦ 顔検出や目検出も、物体検出です6画像処理と処理性能
 精度と速度のバランスが重要◦ 高精度にすると、速度が下がる◦ 速度が下がると、遅延が大きくなる
 遅延が発生する理由：OpenCVの場合◦ バッファに入らなくなるまで画像を貯める（10枚程度）◦ 1枚を取り出して、画像処理を行う◦ 1枚分の空きができたから、1枚の画像(A)がバッファに入る◦ 1枚分の処理が３秒だと、画像(A)を取り出すのは30秒後◦ → １枚分の処理を早くするか、取出専用スレッドを作る

OpenCVのバッファ

7

性能が足りないのであれば
 ハードウエアを追加 → サンプルコードが少ない 別ハードウエアで実行 → 構築手順が違う◦ マイナーなものじゃなければ、ググれば見つかる
 クラウドを利用 → 超賢い、使った分だけ課金が8

OpenCVとは 概要
画像処理・画像解析および機械学習等の機能を持つC/C++、Java、Python、MATLAB用ライブラリ [1] [2]。プラットフォームとして
Mac OS XやFreeBSD等全てのPOSIXに準拠したUnix系OS、Linux、Windows、Android、iOS等をサポートしている。

 できること

Wikipediaより◦ たくさんあるのでWikipediaを参照
 http://ja.wikipedia.org/wiki/OpenCV◦ Windows/Macで開発して、ラズパイで実行

9

OpenCVのメリット
 安心して使用できる◦ BSDライセンス
 様々な画像操作が簡単にできる◦ 拡大縮小回転、合成、保存読み込み、が１操作
 画像操作が容易◦ 8x8の画像の例→◦ 配列として操作できる
 [0, 0]：先頭ピクセル

10ラズパイでOpenCVを動かすために 動作状況を表示するために◦ ラズパイにモニタを接続して、GUIを起動◦ もしくは、パソコンにX-Windowサーバを導入
 Windows：Xming を導入
 接続方法：TeraTermの『X Forwarding』を有効にする
 もしくは：「export DISPLAY=WindowsのIPアドレス:0 」を設定

 Mac：標準装備
 接続方法：ターミナルから「ssh -Y pi＠IPアドレス」

 OSに依存しないやり方◦ PCやスマホのブラウザで結果画像を表示 ← 今回はこっち◦ ブロードバンドルータのポート転送で、Internet公開も可◦ 注意：操作はできません◦ 注意：SDカードとネットワークが高負荷になります11OpenCVでカメラ映像表示ー１
 PCのブラウザで、結果画面を表示◦ http://ラズパイのIP/viewx/

12OpenCVでカメラ映像表示ー２
 ちょっとだけプログラムを修正◦ cd ~/opencv/samples/python/◦ vi video.py
218:

インデントに注意
スペースで、先頭を合わせる#cv.imshow('capture %d' % i, img)
# この行をコメントアウト
import os
cv.imwrite("/tmp/tmp.jpeg", img)
# チラつき防止
os.rename("/tmp/tmp.jpeg", "/var/www/html/viewx/img/capture.jpeg")

 実行

ラズパイにHDMIモニタを接続し、X-Windowを起動していれば、修正は一切不要◦ python3 video.py◦ 謎の美女（Lennaさん）が表示された場合
 → USBカメラを認識していない
 → ラズパイを再起動「sudo reboot」を実行
13

OpenCVでカメラ映像表示ー３
 OpenCVを使って、映像を加工してみる◦ cp video.py video2.py # 改造用にコピー
赤は、[0, 0, 0xff]◦ vi video2.py
218:
219:
220:
221:

img[50:100, 50:100] = 0# 追加#cv.imshow('capture %d' % i, img)
import os
cv.imwrite("/tmp/tmp.jpeg", img)
# チラつき防止
os.rename("/tmp/tmp.jpeg", "/var/www/html/viewx/img/capture.jpeg")

 実行◦ python3 video2.py(50,50)-(100,100)に、黒い箱を書く

14OpenCVでカメラ映像表示ー４
 OpenCVを使って、Tiktok風ツールを作成◦ vi video2.py
fb = None# 加工済画像入れ
index = 0
# 定義
caps = list(map(create_capture, sources))
shot_idx = 0
while True:
imgs = []for i, cap in enumerate(caps):
ret, img = cap.read()
imgs.append(img)
if fb is None:# １回目だけ
fb = img# FrameBuffer は img とまったく同じとしたい# 縦方向
fb[index:,] = img[index:,]# 線より下をfbにコピー
index = index + 2# スピードfb[index:index+5,] = 0xff
# 白線の太さ# 横方向#fb[:,index:] = img[:,index:]# 線より右をfbにコピー#index = index + 2# スピード#fb[:,index:index+5] = 0xff
# 白線の太さ#cv.imshow('capture %d' % i, img)
import os
cv.imwrite("/tmp/tmp.jpeg", fb)# チラつき防止# 描画をimg -> fb に変更
os.rename("/tmp/tmp.jpeg", "/var/www/html/viewx/img/capture.jpeg")

15

OpenCVで顔認識
 OpenCVの顔認識を動かしてみる◦ vi facedetect.py
68:#cv.imshow('facedetect', vis)
# この行をコメントアウト
import os
cv.imwrite("/tmp/tmp.jpeg", vis)
# チラつき防止
os.rename("/tmp/tmp.jpeg", "/var/www/html/viewx/img/capture.jpeg")

 実行◦ python3 facedetect.py

ラズパイにHDMIモニタを接続し、X-Windowを起動していれば、修正は一切不要 他にも色々とサンプルが入っている◦ ls16posenetで姿勢検出ー１
 posenetの姿勢検出を動かしてみる◦ cd ~/posenet-python◦ vi webcam_demo.py
57:#cv2.imshow('posenet', overlay_image)# この行をコメントアウト
cv2.imwrite("/var/www/html/viewx/img/capture.jpeg", overlay_image) 実行◦ python3 webcam_demo.py ※初回だけ学習済データを取得する時間(8分)がかかる

 精度を下げて、実行速度を上げる◦ python3 webcam_demo.py --cam_width 80
17posenetで姿勢検出ー２
 posenetの処理速度を計ってみる◦ vi webcam_demo.py
59:
60:
61:
62:

frame_count += 1
if cv2.waitKey(1) & 0xFF == ord('q’):
break
print('FPS: ', 1 / (time.time() - start))
start = time.time()

63:

# 追加
# 追加

print('Average FPS: ', frame_count / (time.time() - start))

 実行◦ python3 webcam_demo.py◦ python3 webcam_demo.py --cam_width 80
18

yolov5で物体検出ー１
 サンプル画像を確認◦ ブラウザを見ながら実行◦ cd ~/yolov5◦ cp data/images/bus.jpg /var/www/html/viewx/img/capture.jpeg◦ cp data/images/zidane.jpg /var/www/html/viewx/img/capture.jpeg

 サンプル画像に対して実行◦ python3 detect.py
 ※初回だけ学習済データを取得する時間(1分)がかかる

 結果を確認◦ cp runs/detect/exp*/bus.jpg /var/www/html/viewx/img/capture.jpeg◦ cp runs/detect/exp*/zidane.jpg /var/www/html/viewx/img/capture.jpeg
19yolov5で物体検出ー２
 yolov5 の物体検出を動かしてみる◦ vi detect.py
48:#view_img = check_imshow()
view_img = True

119:
120:

if view_img:#cv2.imshow(str(p), im0)
# この行をコメントアウト
cv2.imwrite("/var/www/html/viewx/img/capture.jpeg", im0)
cv2.waitKey(1) # 1 millisecond

121:# この行をコメントアウト# 常にTrue

# 追加

 実行

◦ python3 detect.py --source 0
 精度を下げて、実行速度を上げる◦ python3 detect.py --source 0 --img-size 100
20

yolov5で物体検出ー３
 検出できるモノのリストを出力◦ vi detect.py
56: # Get names and colors
57: names = model.module.names if hasattr(model, 'module') else model.names
print (names)# 追加
58: colors = [[random.randint(0, 255) for _ in range(3)] for _ in names] 実行◦ python3 detect.py --source 0 --img-size 100
 実は◦ vi ~/yolov5/data/coco.yaml

 次は◦ 検出したいモノの画像を一杯集めて、学習させる

21

過去３回も含めて、もっとやってみたいことを検討
2020年11月20日（金）Raspberry Piのセットアップしよう
2020年12月18日（金）Raspberry Piでセンサーを操作する
2021年 1月22日（金）Raspberry Piでインターネット連携
2021年 2月26日（金）Raspberry Piで画像認識← 現在ここ