Using cv::gpu::FAST_GPU with cv::gpu::PyrLKOpticalFlow in OpenCV 2.4.13.6.
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)
{
vec.resize(d_mat.cols);
cv::Mat mat(1, d_mat.cols, CV_32FC2, (void*)&vec[0]);
d_mat.download(mat);
}
static void download(const cv::gpu::GpuMat& d_mat, std::vector<uchar>& vec)
{
vec.resize(d_mat.cols);
cv::Mat mat(1, d_mat.cols, CV_8UC1, (void*)&vec[0]);
d_mat.download(mat);
}
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 (!mImageLprv.data || !mImageLcur.data) 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);
detector2(d_mImageLprv,d2_prevPts);
//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);
d_prevPts.copyTo(d1_prevPts);
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;
}
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.