4

MatOfPoint2fでcalcOpticalFlowPyrLKを使用できませんでした。私は自分のタイプを次のように宣言しました:

private Mat mPreviousGray;                  // previous gray-level image
private List<MatOfPoint2f> points;          // tracked features
private MatOfPoint initial;                 // initial position of tracked points

そして、以下を使用して機能を見つけて追跡します(私のコードは、RobertLaganiereによるC++のサンプルオプティカルフローアプリケーションに基づいています)。

// Called whenever a new frame m is captured
private void OpticalFlow(Mat m, int maxDetectionCount, double qualityLevel,
    double minDistance) {

    if (points.get(0).total() < maxDetectionCount/2)                // Check if new points need to be added
    {
        // maxDetectionCount = 500
        // qualityLevel = 0.01
        // minDistance = 10
        Imgproc.goodFeaturesToTrack(m, initial, maxDetectionCount, qualityLevel, minDistance);

        // add the detected features to the currently tracked features
        points.get(0).push_back(initial);
        // Have checked length of points.get(0), is not zero.
    }

    // for first image of the sequence
    if(mPreviousGray.empty())
        m.copyTo(mPreviousGray);

    if( points.get(0).total() > 0 )   // EMG - 09/22/11 - fix optical flow crashing bug 
    {       
        // 2. track features
        Video.calcOpticalFlowPyrLK(mPreviousGray, m, // 2 consecutive images
                points.get(0), // input point position in first image
                points.get(1), // output point postion in the second image
                status,    // tracking success
                error);      // tracking error
    }

    ...

    m.copyTo(mPreviousGray);

    ...
}

以前は、変数pointsは型List<List<Point>>であり、MatOfPoint2fをインスタンス化してcalcOpticalFlowPyrLKに渡すことにより、型間で変換しfromListていました。

initialただし、このリストからのリストからリストへの変換では、とのポイント間の対応が失われるため、これはもう行いたくありませんでしたpoints。この対応関係を維持したいので、両方の行列の項目を同時に繰り返すことでオプティカルフローラインを描画できます。

残念ながら、現在、次のアサーションエラーが発生しています。

09-24 10:04:30.400: E/cv::error()(8216): OpenCV Error: Assertion failed ((npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0) in void cv::calcOpticalFlowPyrLK(const cv::_InputArray&, const cv::_InputArray&, const cv::_InputArray&, const cv::_OutputArray&, const cv::_OutputArray&, const cv::_OutputArray&, cv::Size, int, cv::TermCriteria, int, double), file X:\Dev\git\opencv-2.4\modules\video\src\lkpyramid.cpp, line 593
09-24 10:04:30.400: E/AndroidRuntime(8216): FATAL EXCEPTION: Thread-321
09-24 10:04:30.400: E/AndroidRuntime(8216): CvException [org.opencv.core.CvException: X:\Dev\git\opencv-2.4\modules\video\src\lkpyramid.cpp:593: error: (-215) (npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0 in function void cv::calcOpticalFlowPyrLK(const cv::_InputArray&, const cv::_InputArray&, const cv::_InputArray&, const cv::_OutputArray&, const cv::_OutputArray&, const cv::_OutputArray&, cv::Size, int, cv::TermCriteria, int, double)
09-24 10:04:30.400: E/AndroidRuntime(8216): ]
09-24 10:04:30.400: E/AndroidRuntime(8216):     at org.opencv.video.Video.calcOpticalFlowPyrLK_2(Native Method)
09-24 10:04:30.400: E/AndroidRuntime(8216):     at org.opencv.video.Video.calcOpticalFlowPyrLK(Video.java:445)

不思議なことに、このアサーションを自分で追加すると、calcOpticalFlowPyrLKを呼び出す前に、失敗しません。

誰かが本当の問題がどこにあるのか、そしてフレーム間の追跡されたポイント間のこの関係をどのように維持できるのかを理解するのを手伝ってくれることを願っています。

編集:このアサーションエラーを回避するために何をする必要があるかを発見しました。アプリケーションは正しく動作しますが、次のようになります。

  • 理由はわかりません。
  • Calib3d.solvePnPについても同様の問題が発生していますが、convertToをimagePointsとobjectPointsに適用しても、ここでは問題が解決されませCvType.CV_32FC2CvType.CV_32FCvType.CV_64F

の場合のアサーションの失敗を修正するために、次のようにcalcOpticalFlowPyrLK変更しました。points.get(0).push_back(initial);

Imgproc.goodFeaturesToTrack(m, initial, maxDetectionCount, qualityLevel, minDistance);

MatOfPoint2f initial2f = new MatOfPoint2f();
initial.convertTo(initial2f, CvType.CV_32FC2);
// add the detected features to the currently tracked features
trackedpoints.get(0).push_back(initial2f);

だから私の質問は次のように変わりました:Calib3d.solvePnPで私の問題を解決する方法も知っているように、誰かが私のために一般的なケースを説明できますか?

4

2 に答える 2

1

calcOpticalFlowPyrLKポイントパラメータは、内部的にCV_32FC2であるMatOfPoint2fタイプです。

SolvePnPの最初のパラメーターはMatOfPoint3fで、内部的にはCV_32FC3です。それが修正されるかどうかを確認するためにそれに変換してみてください。

一部のopencv関数は、特定のマットタイプを想定しています。効率上の理由から、opencvが自動的に推測/変換するのではなく、適切なものを手動で選択する必要があると思います。

于 2012-10-01T10:27:25.480 に答える