OpenCV Error: Assertion failed ((npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0) in calcOpticalFlowPyrLK, file /home/jiaxw/opencv/opencv-3.1.0/modules/video/src/lkpyramid.cpp, line 1114
I want to use the calcOptialFlowPyrLK to track FAST feature points and use non-maximum suppression to select feature points. But what does it mean now?
OpenCV Error: Assertion failed ((npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0) in calcOpticalFlowPyrLK, file /home/jiaxw/opencv/opencv-3.1.0/modules/video/src/lkpyramid.cpp, line 1114
terminate called after throwing an instance of 'cv::Exception'
what(): /home/jiaxw/opencv/opencv-3.1.0/modules/video/src/lkpyramid.cpp:1114: error: (-215) (npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0 in function calcOpticalFlowPyrLK
Here is my code:
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <chrono>
using namespace std;
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/video/tracking.hpp>
void selectMax( int window, cv::Mat gray, std::vector<cv::KeyPoint> & kp_0){
int r = window /2;
if( window != 0)
{
for( int i = 0; i < kp_0.size(); i++){
for( int j = 0; j < kp_0.size(); j++)
{
if( (abs(kp_0[i].pt.x - kp_0[j].pt.x) + abs(kp_0[i].pt.y - kp_0[j].pt.y) ) <= 2*r){
if( kp_0[i].response < kp_0[j].response){
std::vector<cv::KeyPoint>:: iterator it = kp_0.begin() + i;
kp_0.erase(it);
selectMax(window, gray, kp_0);
}
else{
std::vector<cv::KeyPoint>::iterator it = kp_0.begin() + j;
kp_0.erase(it);
selectMax(window, gray, kp_0);
}
}
}
}
}
}
int main( int argc, char** argv )
{
if ( argc != 2 )
{
cout<<"usage: useLK path_to_dataset"<<endl;
return 1;
}
string path_to_dataset = argv[1];
string associate_file = path_to_dataset + "/associate.txt";
ifstream fin( associate_file );
if ( !fin )
{
cerr<<"I cann't find associate.txt!"<<endl;
return 1;
}
string rgb_file, depth_file, time_rgb, time_depth;
list< cv::Point2f > keypoints;
cv::Mat color, depth, last_color;
for ( int index=0; index<800; index++ )
{
fin>>time_rgb>>rgb_file>>time_depth>>depth_file;
color = cv::imread( path_to_dataset+"/"+rgb_file );
depth = cv::imread( path_to_dataset+"/"+depth_file, -1 );
std::vector<cv::KeyPoint> kp;
cv::Mat gray;
cv::cvtColor( color, gray, cv::COLOR_BGR2GRAY);
if (index ==0 )
{
std::vector<cv::KeyPoint> kps;
std::vector<cv::KeyPoint>kp_select;
cv::Ptr<cv::FastFeatureDetector> detector = cv::FastFeatureDetector::create();
detector->detect( color, kps );
int window = 7;
selectMax(window, gray, kps);
kp_select.assign(kps.begin(), kps.end());
for ( auto kp:kp_select )
keypoints.push_back( kp.pt );
last_color = color;
continue;
}
if ( color.data==nullptr || depth.data==nullptr )
continue;
vector<cv::Point2f> next_keypoints;
vector<cv::Point2f> prev_keypoints;
for ( auto kp:keypoints )
prev_keypoints.push_back(kp);
vector<unsigned char> status;
vector<float> error;
chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
cv::calcOpticalFlowPyrLK( last_color, color, prev_keypoints, next_keypoints, status, error );
chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>( t2-t1 );
cout<<"LK Flow use time:"<<time_used.count()<<" seconds."<<endl;
int i=0;
for ( auto iter=keypoints.begin(); iter!=keypoints.end(); i++)
{
if ( status[i] == 0 )
{
iter = keypoints.erase(iter);
continue;
}
*iter = next_keypoints[i];
iter++;
}
cout<<"tracked keypoints: "<<keypoints.size()<<endl;
if (keypoints.size() == 0)
{
cout<<"all keypoints are lost."<<endl;
break;
}
cv::Mat img_show = color.clone();
for ( auto kp:keypoints )
cv::circle(img_show, kp, 10, cv::Scalar(0, 240, 0), 1);
cv::imshow("corners", img_show);
cv::waitKey(0);
last_color = color;
}
return 0;
}
yea, what a mess.
have a look, how to use erase correctly, please. then, check, if you actually have any points left, before applying the optflow.
also, your images must be both of same type, 8bit single channel.