徒然なる日々を送るソフトウェアデベロッパーの記録(2)

技術上思ったことや感じたことを気ままに記録していくブログです。さくらから移設しました。

Raspberry Pi3 でスキップバックレコーダの製作

連休中に購入した Raspberry Pi3 (以下、Pi3 と表記)でスキップバックレコーダを
作ってみた。

  • スキップバックレコーダとは

地震や事故などのイベントが発生した時の状況をカメラで記録しておき、
イベント発生前後の様子を再生する装置。

原理は動画を FIFO に入れておき、イベントが発生して数秒経過したら
蓄積されていた動画を保存する。

今回はイベントとして以下を想定した。

  1. 加速度センサー MMA7455L の X, Y軸のレベル検出
  2. 動画に動きがあった場合の検知
  3. 顔検出

どれかのイベントを検出したらイベントの原因を画面に重畳し、動画保存を行う。
顔検出には OpenCV の Haar 検出器、動画の動きは Y 成分のヒストグラム
変化検出を行った。

  • 画像圧縮の必要性

Pi3 は 1GB の RAM しか乗っていないため、単純に VGA 10fps の画質でも100秒記録
するとメモリを食いつぶしてしまう。
と言って本格的に動画圧縮すると CPU パワーを食い過ぎてフレーム落ちしてしまう。
そのため、各フレームを時系列の JPEG 圧縮リストとして保持することにした。
これにより、25.6秒×2レーン記録しても画像用に消費されるメモリは 100M 以下と
することができた。

  • CPUクロックの制御による顔検出の高速化

顔検出はかなり重い処理で、Raspbian 初期インストール時の governer である
powersave だと頻繁にフレーム落ちが発生する。
これを避けるために governer を ondemand に変更した。ただし CPU 温度が70度
くらいまで上昇するようなので、フィンは必須となる。
governer の変更には cpufrequtils パッケージが必要。

実際にはこれでもフレーム落ちが発生したため、顔検出処理は最終的に外した。

  • 動画出力用 FIFO と書き込み用 FIFO の分離

イベント時の動画記録用の FIFO を2つ用意し、一方を書き込み専用、一方を動画
ファイル出力用とした。イベント発生時に役割を交換する。こうすることで、FIFO
への記録を連続させ、かつ(時間のかかる処理である)動画圧縮を比較的ゆっくり
行うことができる。

  • 動画コーデックの選択

色々なコーデックを試したが、OpenCV で安定的に動作した mpg 形式の MPEG-1 を
採用した。圧縮率や画面のシャープさは他の圧縮方式に比べて弱い印象があったが
比較的高速かつ CPU 負荷が低かった。

  • 動画のアップロード

Pi3 上に Web サーバを構築してもよいが、インターネットから見られた方が
何かと便利なので、録画した動画をレンタルサーバにアップロードするようにした。
cron で 5分に1回、録画した動画があればアップロードを行う。

その際、MPEG-1 から H.264/AVC への変換を行い、web ブラウザ上で動画再生
できるようにした。

Pi3 で再エンコードしなかったのは、レンタルサーバの CPU の方がパフォーマンス
が高いのと、再エンコードすると Pi3 のCPU温度が75度を超えたためである。

  • 動画閲覧サイトの構築

再圧縮された動画は年月日で分類し、同じ日では最も新しいものが先頭に来るように
ソートした。開発言語は PHP を使った。

システム全体の構成は以下の通り。
f:id:minosys:20160511023719p:plain

動画閲覧サイトの一例。
f:id:minosys:20160511024347j:plain