java - Android:将 calcOpticalFlowPyrLK 与 MatOfPoint2f 结合使用

标签 java android opencv opticalflow feature-tracking

我一直无法将 calcOpticalFlowPyrLK 与 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 之前,它不会失败。

我希望有人能帮助我找出真正的问题所在,以及如何在帧与跟踪点之间保持这种关系。

编辑:我发现需要做些什么来避免这个断言错误,然后应用程序会正常运行,但是:

  • 我不知道为什么
  • 我现在对 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 自动猜测/转换。

关于java - Android:将 calcOpticalFlowPyrLK 与 MatOfPoint2f 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12561292/

相关文章:

android - 跨设备/Android 版本的多点触控不一致

java - 即使更改应用程序名称和 apk 文件名后仍需要替换应用程序吗?

c++ - 在 OpenCV 中使用 hog.compute(...) 访问冲突

c - 如何将矩阵应用于opencv中的图像?

c++ - 循环条件中的空 vector<Point> size() 会导致奇怪的行为

Java 克隆和向下转型

java - 将 javafx 中的表格上传到 Excel 工作表

java - 是否可以有条件地在 Java 中导入库?

android - 为 ListView 的每一行设置按钮 onclick 事件

java - 将对象从 C++ 返回到 Java