techno_memo

個人用の技術メモ。python・ROS・AI系のソフトウェア・ツールなどの情報を記載

Raspberry pi でWebカメラ映像を処理する方法(OpenCV)

この記事の目的

 Raspberry piWebカメラを用いて撮影したカメラ動画をストリーミング配信して、他端末からの画像の確認/データ処理する方法をまとめる

1. Webカメラ動画のストリーミング配信

Raspberry pi に接続したWebカメラの映像を他デバイスに配信することで低コストで監視カメラや移動ロボット用カメラとして利用することができる。 本記事では、下記の環境で動画のストリーミングを行った。

項目 バージョン
Raspberry pi Raspberry pi 3
OS Ubuntu Mate 16.04
Camera Logicool C615
OpenCV 3.1 (Python)

Webカメラのストリーミングはmjpg-streamerというソフトを利用する。下記のコマンドでインストールできる。

sudo apt-get update
sudo apt-get install -y cmake libv4l-dev libjpeg-dev imagemagick   #mjpg-streamerに必要なパッケージのインストール
svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer   #mjpg-streamerのダウンロード
cd mjpg-streamer   #ディレクトリの移動
sudo make install   #makeとインストールの実施

次に、Webカメラの起動とストリーミング配信を行う。Webカメラが正しく接続されているかを下記コマンドで確認する。

lsusb
#正しくWebカメラが認識できていれば下記のようにカメラ名が表示される
#Bus 001 Device 005: ID XXXXXXXXX Logitech, Inc. Webcam C615

上記で正しくWebカメラが認識できていた場合、下記コマンドでストリーミングの開始ができる

sudo ./mjpg_streamer -i "./input_uvc.so -f 10 -r 320x240 -d /dev/video0 -y -n" -o "./output_http.so -w ./www -p 8080"

#フレームレート10fps サイズ 320×240 の画像をポート8080から配信

この際、ストリーミングのオプションを下記のように設定することができる。

引数 オプションの内容 設定例
-d バイス名(複数接続時の識別用) /dev/video0
-r ビデオ解像度 320x240
-f フレームレート 10
-y YUVフォーマットの有効・無効 追記時に有効
-q ポート番号 8080
-p 画質YUVフォーマット時のみ有効 80

繰り返し使う処理とする場合には、下記サイトに紹介されているようにshファイルとして作成しておくと管理しやすい

nyabot.hatenablog.com

正しく実行できたら、LAN上の他端末でブラウザからRaspberry pi のアドレス:ポート番号のurlにアクセスできる。

http://192.168.0.X:8080

ストリーミングを終了するには、起動させたターミナルでctrl + c を押す。

2. Webカメラの画像をOpenCVで処理する

上記によりRaspberry pi からWebカメラの画像を配信することはできたが、実際にはこれらの画像を入力として各種の画像処理(物体検出など)を加えたい場合も多い。 そこで、Raspberry pi 上でOpenCVで画像を処理する場合とPCでストリーミングした画像を取得してOpenCVで処理する2パターンについて実装する。 物体検出などの計算量の多い処理をさせるのであれば、Raspberry piWebカメラで撮影データをストリーミングさせるだけにしておいた方が良い。

2.1 Raspberry pi 上でWebカメラ画像を処理する

OpenCVWebカメラにアクセスする機能(VideoCapture)を用いて画像を処理する。

サンプルコードは下記のようになる。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2

cap = cv2.VideoCapture(0) # VideoCaptureのインスタンスを作成する。(複数のカメラがあるときは引数で識別)

while True:
    ret, frame = cap.read()     # 1フレーム読み込む

    # 画像を表示する
    cv2.imshow('Image', frame)

    k = cv2.waitKey(1)  #引数は待ち時間(ms)
    if k == 27: #Esc入力時は終了
        break

# 終了処理
cap.release()
cv2.destroyAllWindows()

2.2 ストリーミングした画像を取得してOpenCVで処理をする

ストリーミングされた動画を別PCで受信して処理する方法

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2

 #mjpg-streamerを動作させているPC・ポートを入力
URL = "http://192.168.0.10:8080/?action=stream"
s_video = cv2.VideoCapture(URL)

while True:
    ret, img = s_video.read()
    cv2.imshow("WebCamera form Raspberry pi",img)
    key = cv2.waitKey(1)
    if k == 27: #Esc入力時は終了
        break