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_32FC2
んCvType.CV_32F
。CvType.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で私の問題を解決する方法も知っているように、誰かが私のために一般的なケースを説明できますか?