Android:将calcOpticalFlowPyrLK与MatOfPoint2f一起使用

我无法将calcOpticalFlowPyrLK与MatOfPoint2f一起使用。 我宣布我的类型如下:

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

并使用以下内容查找和跟踪function(我的代码基于Robert Laganiere在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()  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> ,我将通过使用fromList实例化fromList并将其传递给calcOpticalFlowPyrLK来在类型之间进行转换。

但是,我想不再这样做,因为从列表到列表的转换会丢失initial pointspoints之间的对应关系。 我想保留这种对应关系,所以我可以通过同时迭代两个矩阵中的项来绘制光流线。

不幸的是,现在我有以下断言失败:

 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_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来解决我的问题吗?

calcOpticalFlowPyrLK点参数的类型为MatOfPoint2f,其内部为CV_32FC2。

solvePnP第一个参数是MatOfPoint3f ,内部是CV_32FC3 。 尝试转换为它,看看它是否修复。

一些opencv函数期望特定的Mat类型,我想出于效率原因你必须手动选择正确的类型,而不是自动进行opencv猜测/转换。

其他人中的某个人之前有这个问题。 我最近在OpenCV4Android的光流function中遇到了这个问题(Assertion)。 此解决方案仅在您无法处理以前的点矩阵时才有效:

您应该将matOfKeyPoints.ToArray()中的Keypoint []数组的每个元素放入matOfPoints2f数组中,而不是使用convertTo()方法。

原因在本页解释:

  KeyPoint[] arrayOfkp = keypoints.toArray(); org.opencv.core.Point[] arrayOfp = new org.opencv.core.Point[arrayOfkp.length]; for(int j =0;j