3

フレームからフレームへの機能を追跡するために、goodFeaturesToTrack と calcOpticalFlowPyrLK を使用するプログラムを作成しました。プログラムは確実に動作し、前のフレームから Android カメラのプレビュー画像のオプティカル フローを推定できます。一般的なプロセスを説明するいくつかのスニペットを次に示します。

goodFeaturesToTrack(grayFrame, corners, MAX_CORNERS, quality_level,
        min_distance, cv::noArray(), eig_block_size, use_harris, 0.06);

...

if (first_time == true) {
    first_time = false;
    old_corners = corners;
    safe_corners = corners;
    mLastImage = grayFrame;

} else {

    if (old_corners.size() > 0 && corners.size() > 0) {

        safe_corners = corners;
        calcOpticalFlowPyrLK(mLastImage, grayFrame, old_corners, corners,
                status, error, Size(21, 21), 5,
                TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30,
                        0.01));
    } else {
        //no features found, so let's start over.
        first_time = true;
    }

}

上記のコードは、反復ごとに新しいプレビュー フレームが取得されるループ内で何度も実行されます。Safe_corners、old_corners、および corners はすべて、クラス ベクトル < Point2f > の配列です。上記のコードはうまく機能します。

さて、私が特定した機能ごとに、機能に関する情報を割り当てたいと思います...見つかった回数、おそらく機能の記述子、誰が知っている...私の最初のアプローチこれは。。。でした:

class Feature: public Point2f {
private:
  //things about a feature that I want to track
public: 
  //getters and fetchers and of course:
  Feature() {
    Point2f();
  }
  Feature(float a, float b) { 
    Point2f(a,b);
  }
}

次に、すべての outputArrays が vector < Point2f > から vector < Feature > に変更されます。これは、Feature が Point2f の子孫クラスとして定義されているため、私自身のねじれた世界では機能するはずです。ポリモーフィズムが適用されました。他に何かひどく間違ったことをしない限り、これが私を怒らせる正当な理由を想像できません。

これが私が得るエラーメッセージです。

OpenCV エラー: 無効な cv::Mat::convertTo(cv::OutputArray, int, double, double) const、ファイル /home/reports/ci/slave50-SDK/opencv/modules/ でアサーションが失敗しました (func != 0) core/src/convert.cpp、1095 行目

それで、フォーラムへの私の質問は、OpenCV 関数が Point2f ベクトルを本当に必要とするのか、それとも Point2f の子孫クラスも同様に機能するのかということです。次のステップは、gdb を Android フォンのモバイル コードで動作させ、クラッシュする場所をより正確に確認することですが、私のアプローチに根本的な欠陥がある場合は、その道をたどりたくありません。

あるいは、上記のアプローチを使用してフィーチャが複数のフレームにわたって追跡される場合、各ポイントのメモリ内のアドレスは変化しますか?

前もって感謝します。

4

2 に答える 2

0

私は自分で OpenCV を始めたばかりなので、コードのその側面に対処することはできませんが、問題はコードのバグであり、初期化されていない基本クラスが発生する可能性があります (少なくとも期待どおりに初期化されません)。コードは次のようになります。

Feature()
  : Point2f()
{
}
Feature(float a, float b)
  : Point2f(a,b)
{
}

実装により、コンストラクターで 2 つの一時的な Point2f オブジェクトが作成されます。これらの一時オブジェクトは Feature オブジェクトの Point2f 基本クラスを初期化せず、それらの一時オブジェクトはコンストラクターの最後で破棄されます。

于 2013-05-06T16:19:29.673 に答える
0

短い答えはYESです。OpenCV 関数はstd::vector<cv::Point2f>引数として必要です。

ベクトルにはへのポインタcv::Point2fではなく、オブジェクト自体が含まれているため、ポリモーフィックな動作はありません。cv::Point2f

さらに、Feature継承元を持つことcv::Point2fはおそらく理想的な解決策ではありません。Feature この場合、正しい関係 ( has-a ) をモデル化することは言うまでもなく、コンポジションを使用する方が簡単cv::Point2fです。

メモリ内のオブジェクトの場所に依存することも、おそらく良い考えではありません。むしろ、選択したデータ構造を読んでください。

于 2013-05-06T15:15:58.027 に答える