動体検出を軽くする(AAS, CVPR '12)
はじめに
動体検出を使用して物体の検出を行うことがあります。特に最近のカメラは高画素であり、処理が重くなります。そこで、画像の全画素で処理を行わず、物体がありそうなところだけで処理を行う方法が考えられます。
アルゴリズム
ちょっと前の論文ですが、動体検出(背景除去)の高速化を目指した論文がありました。
Active Attentional Sampling for Speed-up of Background Subtraction, CVPR 2012.
これは過去の検出結果から、物体がありそうな確率マップ(probability map)を生成して、確率が高いところで検出処理を行おうとしたものです。それだと新しい侵入物に対応できないので、ランダムに数割程度の画素に対して検出処理をします。下の図は検出結果、probability map、maskを並べたものです。maskの白い部分が重い動体検出処理を行う画素で、黒の部分は処理しないため、全体としての処理は軽くなります。
maskの生成にはいくつかのpropertyを考慮します。
foreground probability map
以上三つをまとめます。
この結果が最初の画像まんなかのprobmapです。
randomly scatter
probability mapは確率のmapで、maskではありません。ここから、実際に使用するmaskを生成していきます。
maskはM_RSとM_SEIとM_SPのORで計算します。
M_RSはrandomly scatterを表し、一定の割合で画像全体に検出点を作ります。
実装はランダムに点を選んでM_RS(i)=1にします。ちょっとしたテクニックですが、前のフレームでrandomly scatterした点が動体だと判定されたら、次のフレームでもM_RS(i)=1にしてます。
まとめ
動体検出(背景除去)を高速化するためのアルゴリズムを調べました。全部探索する必要がないタスクは他にもありそうなので、このアルゴリズムを流用できるかもしれません。
OpenCVで実装したものを一部だけ載せておきます。
void AASampling::process(const cv::Mat1b& d_t) { d_ = 0.0f + d_t; // temporal property m_t_ = (1.0f - ALPHA_T) * m_t_ + ALPHA_T * d_; // spatial property makeSpatialMatrix(s_); m_s_ = (1.0f - ALPHA_S) * m_s_ + ALPHA_S * s_; // frequency property makeFrequencyMatrix(f_); m_f_ = (1.0f - ALPHA_F) * m_f_ + ALPHA_F * f_; // foreground probability map p_fg_ = m_t_.mul(m_s_).mul(1.0f - m_f_); randomlyScattered(m_rs_); spatiallyExpanding(m_sei_); surprisePixel(m_sp_); // active sampling mask generation maskGeneration(result_mask_); pre_p_fg_ = p_fg_.clone(); pre_pre_d_ = pre_d_.clone(); pre_d_ = d_.clone(); }