2015年3月15日日曜日

raspberry pi 2(とカメラモジュール)を使った動画認識手順のメモ

1.カメラモジュールが使えるようにする(ストリーミング可能にする)
 →前回記事と同様(pi 2でもB+でも同様)

2.opencv(最新版)を導入
参考記事:
とある大学院生のプログラミング 様
http://blog.livedoor.jp/tmako123-programming/archives/41353891.html
 途中のccmakeの部分でgコマンドが効かなかった。ccmakeの後cmake → make とすることで解決した。環境の相違か?インストールには約2~3時間くらいかかった気がする。

3.opencv(python)でストリーミングから画像を取得する。
半日詰まったが以下を参考にして解決。これ以上にスマートな方法は発見できず。
stack over flow
http://stackoverflow.com/questions/21702477/how-to-parse-mjpeg-http-stream-from-ip-camera

(参考ソース:上記URLより引用)
stream=urllib.urlopen('http://localhost:8080/frame.mjpg')
bytes=''
while True:
    bytes+=stream.read(1024)
    a = bytes.find('\xff\xd8')
    b = bytes.find('\xff\xd9')
    if a!=-1 and b!=-1:
        jpg = bytes[a:b+2]
        bytes= bytes[b+2:]
        i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),cv2.CV_LOAD_IMAGE_COLOR)
        cv2.imshow('i',i)
        if cv2.waitKey(1) ==27:
            exit(0)   
~ここまで引用
途中に嫌な感じの部分(byteから特定文字列を検索している)があるが、現状mjpegストリーミングを正しく取得するにはこれしかない模様。あと筆者環境ではcv2.waiKey(1) ==27 が効かなかった。
waikeyの部分をa!=-1 ~のifブロックの外に出し、==27 (escキーのアスキーコード)でなく >-1とすることで中断できるようになった(筆者環境(raspberry pi 2だが)ではesc=27でなかった(100048とかそんな値)。面倒がってキーボードレイアウトをデフォルトにしている(UK)のが原因かもしれない。

4.その他(GUIウィンドウのきれいな閉じ方と特徴量抽出処理の基本)
手順3.のソースでは開いたウィンドウ「i」が正しく閉じない(pythonのexitで強制的に閉じているが)、以下の参考URLの方法でちゃんと閉じられるように改良
参考URL
stack over flow
http://stackoverflow.com/questions/6116564/destroywindow-does-not-close-window-on-mac-using-python-and-opencv

参考コード:上記より一部引用
cv2.namedWindow(WINDOW_NAME, cv.CV_WINDOW_AUTOSIZE)

cv2.startWindowThread()
 
~以下処理ループ~
 
映像処理ループの前にカラのウィンドウを生成しておき、おまじない(starWindowThread)を
行っておく必要がある(多分違うが感覚的にはマルチスレッドのsetDaemonみたいなもの)。
この後 cv2.destroyAllWindows()  や、cv2.DestroyWindow("ウィンドウ名")でウィンドウ
を閉じる。
 
・画像の特徴量抽出、記述、マッチングについては以下のHPにわかりやすくまとめてあった。
参考URL :whoopsidaisies's diary 様
 http://whoopsidaisies.hatenablog.com/entry/2013/12/07/135810
 
ちょっと前まで(FREAKが出たころ)pythonで特徴量抽出などはできなったが最近はできる模様。上記HPはc++で
解説されているが、同様のことがたいていpythonでも可能(公式ドキュメント参照)。
とりあえず抽出:FAST、記述:FREAK あたりでやってみたがストリーミングサイズ320x240で
5fps設定として処理したところ、ちょっとカクつくが処理の結果をリアルタイム(と感じなくも無い速度)で
確認できた。マッチングはまだやっていないため不明。
CPU使用率には余裕があった(30%程度使用)が、普通に使う分(マルチコアの有効活用などを意識しない運用)
にはこのくらいの処理速度が限度かという感じ。