ラズパイで動体検知+ハードウェア・アクセラレーション

家で眠っている機材を利用しよう

Raspberry PiとWebカメラが家で余っていたので、動体検知サーバーをたててみました。動体検知したときのみ録画してくれるので、無駄にストレージを圧迫しません。今回は動画圧縮にハードウェア・アクセラレーションを用いています。また、ライブカメラのストリーミングも見られる設定にしてみました。

使ったもの

設定手順

まずはRaspberry PiのOSとして最新のRaspbian Stretchをインストール。CUI操作のみで十分なので今回はGUI無しのLiteをインストールしました。注意点として、Raspbianの一つ前のバージョンのRaspbian Jessieだとaptで後述のFFmpegがインストールできないので避けるのが無難だと思われます。OSのインストール及びネットワーク接続の解説は割愛。

以降、SSHが繋がった後の話とします。

FFmpegのインストール

FFmpegはaptでもすぐにインストールできるのですが、それだとRaspberry Piのハードウェア・アクセラレーションを用いた動画エンコーディングが有効にならず、CPUのみのエンコーディングとなってしまうので、こちらのサイトを参考にFFmpegのビルドを行います。

まず/etc/apt/sources.listを開き、deb-srcで始まる行(おそらく3行目のはず)をアンコメントします。これでapt sourceが使えるようになります。

依存ライブラリをインストールするために一回aptでFFmpegをインストール(もしかしたらいらないかも)し、apt build-depapt sourceでビルドに必要なものを引っ張ってきます。

$ sudo apt update
$ sudo apt install ffmpeg
$ sudo apt build-dep ffmpeg
$ mkdir ~/ffmpeg && cd $_
$ sudo apt source ffmpeg
$ cd ffmpeg-3.2.9

あとはconfiguremake。今回configureは必要最低限でよいので

$ ./configure --enable-mmal --enable-omx-rpi --prefix=$HOME/usr/local
$ make -j2
$ sudo make install

で大丈夫なはずです。コンパイルにはかなり時間がかかります。

configureに関しては、不安であれば、既にインストールされているffmpegを起動したときに出てくるものをコピペすればよいかと思います。

--prefixは好きな場所を指定します(PATHを通すのをお忘れなく)。--prefixを省略すると/usr/local/binにインストールされます。既にaptでインストールされているffmpeg/usr/binにあるので、PATHの優先順位を調整するか、sudo make installの前にsudo apt remove ffmpegでアンインストールします。

以下のような出力が得られればインストール完了です。

$ ffmpeg -encoders 2> /dev/null | grep omx
V..... h264_omx             OpenMAX IL H.264 video encoder (codec h264)

Motionサーバーをインストール

FFmpegのインストールが終わったら、次にカメラによる動体検知・記録を可能とするMotionサーバーをインストールします。

$ sudo apt update
$ sudo apt instal motion

設定ファイル/etc/motion/motion.confのパラメータを編集します。
ここはお好みですが、今回は以下の部分のみ変更しました。

daemon on  # サービスとして実行
width 1280  # 記録する映像の幅(任意)
height 720  # 記録する映像の高さ(任意)
framerate 5  # フレームレート(なぜか実際にはもっと低くなる…)
threshold 15000  # 動体検知の閾値。変化のあったピクセル数。適宜調整しつつ運用。

use_extpipe on  # 記録した動画を外部プログラムに渡す
extpipe ffmpeg -y -f rawvideo -loglevel warning -pix_fmt yuv420p -video_size %wx%h -framerate %fps -i pipe:0 -vcodec h264_omx -f mp4 %f.mp4  # 今回の肝。FFmpegにrawvideoを投げつけてh264_omxでエンコード。

locate_motion_mode on  # 認識した動体の位置を示す。デフォルトでは長方形で図示。

target_dir /home/Kiichi/Videos  # 保存先ディレクトリ
movie_filename %v-%Y%m%d-%H%M%S  # 動画のファイル名

stream_maxrate 10  # ストリーミングで滑らかに動くため
stream_localhost off  # localhost以外からでもストリーミングにアクセスできるようにする
stream_auth_method 1  # ストリーミングにBasic認証をかける
stream_authentication username:password  # 認証時のIDとPass

あくまで感覚ですが、heightwidthを大きくするとフレームレートが下がるので、うまく調整してあげることが必要です。

extpipeの項目で動体を検知した際の動画をFFmpegに渡す設定を書いています。渡された動画はFFmpegによってH.264に変換・出力されるので、そこまで大きなサイズにはなりません。しかもハードウェア・アクセラレーションの恩恵によって低負荷・高速に変換されます。

あとはMotionサーバーをsudo motion -nで動かしてあげればテスト終了です。http://(RaspberryPiのIPアドレス):8081でライブカメラのストリーミングを視聴することもできます。今回は割愛しますが、ストリーミングを有効にするに際しては必ずファイアウォール等を設定しましょう。

サービスとして起動するには/etc/default/motionの中のstart_motion_daemonnoからyesに変更すればOKです。サービスはrootではなくmotionというユーザーとして起動されるので、先程のテストsudo motion -nでroot権限で作ってしまったディレクトリ/var/log/motionは削除しておきます。また、動画の保存先のパーミッションも変更しておきます。

$ sudo rm -R /var/log/motion
$ chmod 777 /home/Kiichi/Videos  # target_dirで指定したディレクトリ
$ sudo service motion restart

これで無事Motionがサービスとして起動するはずです。Raspberry Pi起動時にデーモンも動かしたければsysv-rc-conf等で設定できます。

参考サイト