8

バックグラウンド平均化方法を実装したい。1 秒間に 50 フレームの画像を撮影しましたが、一部のフレームには前景として抽出したい稲妻が含まれています。フレームは固定カメラで撮影され、フレームはグレースケールとして取得されます。私がやりたいことは次のとおりです。

  1. 背景モデルを取得する
  2. その後、各フレームを背景モデルと比較して、そのフレームに照明があるかどうかを判断します。

cvAcc() を使用してこれを行う方法についていくつかのドキュメントを読みましたが、これを行う方法を理解するのが困難です。私を導くコードと、これを実装する方法を理解するのに役立つドキュメントへのリンクをいただければ幸いです。

よろしくお願いします。

4

2 に答える 2

21

私たちのプロジェクトの1つでも同じタスクがありました。

背景モデルを取得するには、クラスBackgroundModelを作成し、最初の(たとえば)50フレームをキャプチャし、平均フレームを計算して、背景モデルのピクセルエラーを回避します。

たとえば、カメラから8ビットのグレースケール画像(CV_8UC1)を取得する場合は、クリッピングを回避するためにモデルをCV_16UC1で初期化します。

cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0));

ここで、最初のフレームがモデルを計算するのを待って、すべてのフレームをモデルに追加し、受信したフレームの量を数えます。

void addFrame(cv::Mat frame) {
    cv::Mat convertedFrame;
    frame.convertTo(convertedFrame, CV_16UC1);
    cv::add(convertedFrame, model, model);
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50
        createMask();
    }
}

createMask()関数は、モデルに使用する平均フレームを計算します。

void createMask() {
    cv::convertScaleAbs(model, mask, 1.0 / learnedFrames);
    mask.convertTo(mask, CV_8UC1);
}

これで、すべてのフレームをBackgroundModelクラスを介して関数subtract()に送信するだけです。結果が空のcv::Matの場合でも、マスクは計算されます。それ以外の場合は、減算されたフレームを取得します。

cv::Mat subtract(cv::Mat frame) {
    cv::Mat result;
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50
        cv::subtract(frame, mask, result);
    }
    else {
        addFrame(frame);
    }
    return result;
}

最後になりましたが、Scalar sum(const Mat&mtx)を使用してピクセルの合計を計算し、ライトが点灯しているフレームかどうかを判断できます。

于 2011-10-14T10:26:09.167 に答える