我无法将matOpticalFlowPyrLK与MatOfPoint2f一起使用。我宣布我的类型如下:
private Mat mPreviousGray; // previous gray-level image
private List<MatOfPoint2f> points; // tracked features
private MatOfPoint initial; // initial position of tracked points
并使用以下内容查找和跟踪功能 (我的代码基于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() < 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>>
,我会通过使用fromList
实例化MatOfPoint2f并将其传递给calcOpticalFlowPyrLK来在类型之间进行转换。
但是,我想不再那样做,因为从列表到列表的转换会丢失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之前,它不会失败。
我希望有人可以帮我弄清楚真正的问题在哪里,以及如何保持帧之间跟踪点之间的这种关系。
编辑:我发现需要做些什么来避免这个断言错误,然后应用程序行为正常,但是:
CvType.CV_32FC2
,CvType.CV_32F
或CvType.CV_64F
< / LI>
要在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解决我的问题吗?
答案 0 :(得分:1)
calcOpticalFlowPyrLK点参数的类型为MatOfPoint2f,内部为CV_32FC2。
solvePnP第一个参数是 MatOfPoint3f ,其内部是 CV_32FC3 。尝试转换为它以查看它是否已修复。
有些opencv函数需要特定的Mat类型,我想出于效率原因你必须手动选择正确的类型,而不是自动进行opencv猜测/转换。
答案 1 :(得分:0)
而不是使用convertTo()方法,你应该将你从matOfKeyPoints.ToArray()获得的Keypoint []数组的每个元素放入matOfPoints2f数组。
原因在other thread中解释:
KeyPoint[] arrayOfkp = keypoints.toArray();
org.opencv.core.Point[] arrayOfp = new org.opencv.core.Point[arrayOfkp.length];
for(int j =0;j<arrayOfkp.length;j++)
{
arrayOfp[j] = new org.opencv.core.Point(0, 0);
arrayOfp[j].x = (int) arrayOfkp[j].pt.x;
arrayOfp[j].y = (int) arrayOfkp[j].pt.y;
}
prevPts.fromArray(arrayOfp);