Ask Your Question

Using cv::gpu::FAST_GPU with cv::gpu::PyrLKOpticalFlow in OpenCV

asked 2018-03-20 07:37:10 -0600

kjoshi gravatar image

updated 2018-03-21 09:20:05 -0600

I am trying to follow the example provided here: PyrLKOpticalFlow Example

However, once I call the FAST_GPU detector and pass the returned points in GpuMat format to PyrLKOpticalFlow it does not run and I get an assertion error. I have tried several things to change the GpuMat but I can not get PyrLKOpticalFlow to accept the points detected by FAST_GPU.

OpenCV Error: Assertion failed ((npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0) in calcOpticalFlowPyrLK, file /home/ubuntu/build-opencv/opencv/modules/video/src/lkpyramid.cpp, line 845 terminate called after throwing an instance of 'cv::Exception' what(): /home/ubuntu/build-opencv/opencv/modules/video/src/lkpyramid.cpp:845: error: (-215) (npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0 in function calcOpticalFlowPyrLK

I am attaching my code here.

#include <opencv2/opencv.hpp>
#include <opencv2/gpu/gpu.hpp>
#include <chrono>
#include <iostream>
#include <fstream>
static void download(const cv::gpu::GpuMat& d_mat, std::vector<cv::Point2f>& vec)
        cv::Mat mat(1, d_mat.cols, CV_32FC2, (void*)&vec[0]);;

    static void download(const cv::gpu::GpuMat& d_mat, std::vector<uchar>& vec)
        cv::Mat mat(1, d_mat.cols, CV_8UC1, (void*)&vec[0]);;

    int main () {

        //Read the Images prv & cur Left
        cv::Mat mImageLprv = cv::imread("../mImageLprv.pgm", 0);
        cv::Mat mImageLcur = cv::imread("../mImageLcur.pgm", 0);

        //Exit if images are not read
        if (! || ! exit(1);

        //Convert to GPU format
        cv::gpu::GpuMat d_mImageLprv(mImageLprv);
        cv::gpu::GpuMat d_mImageLcur(mImageLcur);

            cv::gpu::GpuMat d_prevPts, d2_prevPts;

            //For comparison test
            cv::gpu::GoodFeaturesToTrackDetector_GPU detector2(3128,0.01,0);

        //FAST GPU Detector
            cv::gpu::FAST_GPU detector(25);
        detector(d_mImageLprv, cv::gpu::GpuMat(), d_prevPts);       

            std::cout<<"Size: "         <<d_prevPts.size()<<" "
                     <<"Type: "         <<d_prevPts.type()<<" "
                     <<"isContinuous: " <<d_prevPts.isContinuous()<<"\n";

        //Call the KLT Tracker
        cv::gpu::PyrLKOpticalFlow d_pyrLK;
        d_pyrLK.winSize.width = 21;
        d_pyrLK.winSize.height = 21;
        d_pyrLK.maxLevel = 3;
        //d_pyrLK.iters = 30;

        cv::gpu::GpuMat d_nextPts;
        cv::gpu::GpuMat d_validIdx;
        cv::gpu::GpuMat d1_prevPts = cv::gpu::createContinuous(d_prevPts.size(),5);
            cv::gpu::GpuMat dx_prevPts = d1_prevPts.reshape(2,1);

            std::cout<<"Size: "         <<dx_prevPts.size()<<" "
                    <<"Type: "         <<dx_prevPts.type()<<" "
                    <<"isContinuous: " <<dx_prevPts.isContinuous()<<"\n";

            d_pyrLK.sparse(d_mImageLprv, d_mImageLcur, d_prevPts, d_nextPts, d_validIdx);

        std::vector<cv::Point2f> prevPtsPyrLK(dx_prevPts.cols);
        download(dx_prevPts, prevPtsPyrLK);

        std::vector<cv::Point2f> nextPtsPyrLK(d_nextPts.cols);
        download(d_nextPts, nextPtsPyrLK);

        std::vector<uchar> validIdx(d_validIdx.cols);
        download(d_validIdx, validIdx);

        return 0;

GpuMat Formats

d2_prevPts is the GpuMat format that is acceptable by gpu::PyrLKOpticalFlow::sparse and d_prevPts is the format that is produced by gpu::FAST_GPU.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2018-03-20 17:40:22 -0600

Tetragramm gravatar image

Which version of OpenCV is this? 2.4. something?

In 3.4.1, there's a built-in convert function. Aaand, in 2.4.13 it's HERE.

That gets you to a vector<keypoint> where you can use the Keypoint::convert function to turn it into a vector<point2f>, and that goes straight into the optical flow.

edit flag offensive delete link more


This is 2.4 version. However, I am trying not to bring the points back to the CPU. I want to operate on it within the GPU memory. There is gpu::PyrCalcOPticalFlow which takes the features detected and returns the flow points. This way I can maximize the use of the GPU.

kjoshi gravatar imagekjoshi ( 2018-03-21 09:04:56 -0600 )edit

Question Tools

1 follower


Asked: 2018-03-20 07:37:10 -0600

Seen: 766 times

Last updated: Mar 21 '18