3

未知のオブジェクトを追跡するオブジェクト追跡プログラムを構築しています。ユーザーは、追跡するライブ ビデオ ストリーム内の領域を選択する必要があります。私のプロジェクトはこのビデオに似ています。

http://www.youtube.com/watch?v=G5GLIKIkd6E

方法を試しましたが、十分に堅牢ではなく、トラッカーが頻繁に動きます。というわけで、またゼロからスタートです。

ビデオの方法を思い付く方法を知っている人はいますか? 私は emgucv の初心者であり、今のところ、どこからやり直すべきか本当にわかりません。

4

2 に答える 2

8

ビデオはテンプレート マッチングを提案していますが、これは速度が速いため、FFT (高速フーリエ変換) メソッドである可能性が高いと予想されます。これは EMGU で実装するのはかなり簡単ですが、完璧にするのは難しいです。


テンプレートマッチング

最初に、テンプレート マッチング メソッドを作成しました。フィードした画像内のオブジェクトに一致するメソッドを作成しました。FFT は、スペクトルを分割して結果の行列を追加する必要がある色の単一スペクトル画像でのみ機能します。

Point Location;

private bool Detect_object(Image<Gray, Byte> Area_Image, Image<Gray, Byte> image_object)
{
    bool success = false;

    //Work out padding array size
    Point dftSize = new Point(Area_Image.Width + (image_object.Width * 2), Area_Image.Height + (image_object.Height * 2));
    //Pad the Array with zeros
    using (Image<Gray, Byte> pad_array = new Image<Gray, Byte>(dftSize.X, dftSize.Y))
    {
        //copy centre
        pad_array.ROI = new Rectangle(image_object.Width, image_object.Height, Area_Image.Width, Area_Image.Height);
        CvInvoke.cvCopy(Area_Image, pad_array, IntPtr.Zero);

        pad_array.ROI = (new Rectangle(0, 0, dftSize.X, dftSize.Y));

        //Match Template
        using (Image<Gray, float> result_Matrix = pad_array.MatchTemplate(image_object, TM_TYPE.CV_TM_CCOEFF_NORMED))
        {
            Point[] MAX_Loc, Min_Loc;
            double[] min, max;
            //Limit ROI to look for Match

            result_Matrix.ROI = new Rectangle(image_object.Width, image_object.Height, Area_Image.Width - image_object.Width, Area_Image.Height - image_object.Height);

            result_Matrix.MinMax(out min, out max, out Min_Loc, out MAX_Loc);

            Location = new Point((MAX_Loc[0].X), (MAX_Loc[0].Y));
            success = true;
            Results =result_Matrix.Convert<Gray,Double>();

        }
    }
    return success;
}

ほとんどの人が忘れていることは、ゼロを使用するテンプレートのサイズに似たゼロで配列をパディングすることです。これは fft メソッドには影響しないためです。マトリックスをパディングしないと、エッジの周りのデータが適切に処理されず、一致するアイテムを見逃す可能性があります。

2 番目のポイントと、これがどれほど重要かを強調することはできません。現時点では、FFT メソッドはオブジェクトの左上隅に一致するものを返すということです。result_Matrix.MinMax は、オブジェクトが一致する可能性が最も高い場所を見つけます。実験しなければならないことがたくさんあるので、それ以上の問題があれば、ここまたは EMGU に質問してください。できる限りお手伝いします。このソリューションもコピーして貼り付けます。


ビデオの方法

時間に追われているので、ほとんどのコードはあなたに任せますが、実際には、ユーザーはペイントボックスのクリック イベントを使用して、画像内のオブジェクトのセット eX および eY 位置を見つけます。テンプレートは固定サイズなので 100x100

Image<Gray, Byte> template_img = Main_Image.Copy(new Rectangle(x, y, 100, 100);

次に、オブジェクトの周囲の元の画像に ROI を設定します。これは動きを説明します。この例では、テンプレートの周囲に 50 ピクセルのバッファー (ROI) が必要だとします。これは、次の初期 ROI に相当します。

Main_Image.ROI = new Rectangle(x - 50, y - 50, 200, 200);

画像の ROI を操作しているため、処理が遅くなるだけでなく、元の画像の表示が台無しになる可能性があるため、次のようなことを行う方がはるかに優れています。

using( Image<Gray, Byte> img_ROI = Main_Image.Copy(new Rectangle(x - 50, y - 50, 200, 200))
{
    Detect_object(img_ROI, template_img)
}

using ステートメントを使用すると、終了時に余分な画像データが破棄され、リソースが解放されます。

トリックとして、ROI は Detect_object からの結果によって実際に制御されます。これが、Location をグローバル変数として保持する理由です。Location がテンプレートと正常に一致すると、using ステートメントは次のようになります。

using( Image<Gray, Byte> img_ROI = Main_Image.Copy(new Rectangle(Location.X - 50, Location.Y - 50, 200, 200)) 
{
    ...
}

ROI とテンプレートの四角形以外はこれでほぼ完了です。問題がある場合は画像にサイズと位置が描画されますが、コードはすぐに公開されるはずです。

乾杯、

クリス

于 2012-01-06T10:40:36.537 に答える
0

ビデオは、Gary Bradski が説明したCAMSHIFT メソッドに似たものを使用しているようです。camshiftデモ アプリケーションの C++ コードは次のとおりです。C# ではないことはわかっていますが、EmguCV に簡単に移植できるはずです。カムシフトアルゴリズムのコアのドキュメントは次のとおりです。

それが役立つことを願っています!

于 2012-01-05T14:46:08.237 に答える