オープンソースの動体検知ソフト、Motionのコアロジックはalg.cに集約されていて非常に読みやすい。次のように、関数名はすべてalg_*と統一されている。
更に、これらのパブリックな関数のほかにalg.cには、次のようなローカル関数も含まれている。
このように、関数名を見ただけでもMotionのコアロジックが、概略どのようなものであるかが想像できるだろう。MMX(MultiMedia eXtensions)アーキテクチャ実装のCPU向けに高速化処理もしている。興味深いのは、私の「頭部補正」と同じような処理をしていることだ。次のプログラムの断片を見ていただくとわかるように、上半分を固定で1.5倍だけ大きく(背伸び)している。
alg.c の関数 alg_locate_center_size より抜粋
if (centc) {
cent->minx = cent->x - xdist / centc * 2;
cent->maxx = cent->x + xdist / centc * 2;
/* Make the box a little bigger in y direction to make sure the
heads fit in so we multiply by 3 instead of 2 which seems to to work well in practical */
cent->miny = cent->y - ydist / centc * 3;
cent->maxy = cent->y + ydist / centc * 2;
}
映像処理のループは、motion.cに含まれる関数motion_loopである。この関数は、2000行ほどの巨大なループを形成している。このループの中は、処理内容ごとに13のセクションに分かれていて、この順序で繰り返し実行されるようになっている。この関数を読めば、Motionの基本的な処理の流れがわかる。先に紹介したコアロジックは、主に④と⑤で使用される。
① | PREPARE FOR NEW FRAME SECTION | 時刻取得など、映像フレーム取得の準備。 |
② | RETRY INITIALIZING SECTION | カメラが使えない場合、見えるようになるまで10秒ごとにこの処理を続ける。 |
③ | IMAGE CAPTURE SECTION | 新しい映像フレームをキャプチャする。 |
④ | MOTION DETECTION SECTION | 差分抽出によって動体検知する。 |
⑤ | TUNING SECTION | 雑音レベルのチューニング。 |
⑥ | TEXT AND GRAPHICS OVERLAY SECTION | 日付や枠を焼きこみ。 |
⑦ | ACTIONS AND EVENT CONTROL SECTION | 画像ファイル保存など、指定されたイベント処理を実行する。トラッキング(カメラの首振り)はここで実行する。 |
⑧ | SETUP MODE CONSOLE OUTPUT SECTION | 調整のためにコンソールに情報を出力する。 |
⑨ | SNAPSHOT FEATURE SECTION | スナップショット作成。 |
⑩ | TIMELAPSE FEATURE SECTION | FFMPEGによる動画ファイル作成。 |
⑪ | VIDEO LOOPBACK SECTION | ビデオ出力およびWebカメラ配信。 |
⑫ | ONCE PER SECOND PARAMETER UPDATE SECTION | 設定変更に対応するよう1秒おきにチェックする。 |
⑬ | FRAMERATE TIMING AND SLEEPING SECTION | 次のキャプチャまでの時間調整のためスリープ。 |
Motionは、映像のソースとして/dev/video、つまりV4L2のビデオキャプチャ装置のほかに、ネットワークカメラ(Webカメラ)にも対応しており、しかも同時に複数の映像ソースを処理できるようになっている。このため、映像処理ループはスレッドで動作する。
pthread_create(&cnt->thread_id, thread_attr, &motion_loop, cnt);