我正试图在Ubuntu上的opencv 2.4.12中使用以下代码进行视频稳定,我使用了calchopticalflowpyrlk,它抛出了一个断言失败错误:错误如下:
OpenCV错误:CV::calcOpticalFlowPyrLK中的断言失败((npoints=prevPtsMat.checkVector(2,CV_32F,true)>=0),文件主页。。。\opencv\modules\video\src\lkpiramid.cpp,第845行
这是代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <iostream>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int main()
{
int rows = 240;
int cols = 240;
int i = 1;
VideoCapture cap(0);
Mat Canvass;
Canvass.create(rows, cols * 2, CV_8UC3);
for(;;)
{Mat prev,cur;
Mat prev_gray,cur_gray, aligned;
Mat TT(2, 3, CV_64F);
vector <Point2f> cur_corner, cur_corner2, prev_corner2;
vector <Point2f> prev_corner;
Mat prev_grey;
vector <uchar> status;
vector <float> err;
double dx, dy, da;
const int max_no_of_corners = 20000;
const double quality_of_corners = 0.00001;
const double min_dist_bw_corners = 5;
const int search_window_size = 80;
const int pyramid_level = 5;
Mat cur_warped;
int rows = 240;
int cols = 240;
if(i == 1)
{ //capture the prev frame,resize,grayscale and display it
for (int x = 0; x < 10;x++)
{ cap >> prev; }
resize(prev, prev,Size(240,240));
cvtColor(prev,prev_gray,CV_BGR2GRAY);
prev.copyTo(Canvass(Range::all(), Range(0,cols)));
//capture the current frame,resize and grayscale it
cap>>cur;
resize(cur,cur,Size(240,240));
cvtColor(cur,cur_gray,CV_BGR2GRAY);
i++;
}
else{
cap>>cur;
resize(cur,cur,Size(240,240));
cvtColor(cur,cur_gray,CV_BGR2GRAY);
cvtColor(prev,prev_gray,CV_BGR2GRAY);
//display the previous image in canvass
cur.copyTo(Canvass(Range::all(), Range(0,cols)));
}
///find corner points here
goodFeaturesToTrack(prev_grey, prev_corner, max_no_of_corners, quality_of_corners, min_dist_bw_corners);
//usecalcopticalflowpyrlk
calcOpticalFlowPyrLK(prev_gray, cur_gray, prev_corner, cur_corner, status, err, Size(10,10),2);
//weed out bad matches
for (int t = 0; t < status.size(); t++) {
if (int(status[t])) {
cur_corner2.push_back(cur_corner[t]);
prev_corner2.push_back(prev_corner[t]);
}
}
//estimate transform
Mat T;
T = estimateRigidTransform(prev_corner2, cur_corner2,false);
if (T.data == NULL)
{cout<<"No transform found"<<endl;
cur.copyTo(Canvass(Range::all(), Range(cols,cols * 2)));
cur.copyTo(prev);
}
else{
cout<<"transform found "<<endl;
// decompose T
dx = T.at<double>(0, 2);
dy = T.at<double>(1, 2);
da = atan2(T.at<double>(1, 0), T.at<double>(0, 0));
da = -da;
//da = 0;
TT.at<double>(0, 0) = cos(da);;
TT.at<double>(0, 1) = -sin(da);
TT.at<double>(1, 0) = sin(da);
TT.at<double>(1, 1) = cos(da);
TT.at<double>(0, 2) = -dx;// / scale;
TT.at<double>(1, 2) = -dy;// / scale;
//TT.copyTo(Transform);
//warp
warpAffine(cur, cur_warped, TT, cur.size(),INTER_NEAREST|WARP_INVERSE_MAP);
cur.copyTo(prev);
cur_warped.copyTo(Canvass(Range::all(), Range(cols,(cols * 2))));
}
imshow( "Output",Canvass);
waitKey(1);
}
}
我认为calcopopticalflowpyrlk中向量的数据类型可能存在一些问题,但我已经用文档进行了验证,仍然遇到了这个错误。我该如何摆脱它?
是否可以显示和检查prev_corner.size()
和cur_corner.size()
?根据断言,这些向量似乎是空的。如果是这种情况,只需检查您是否有足够的特征点来查找对应关系。
顺便说一下,在调用estimateRigidTransform()
之前,您还应该检查匹配的数量;如果我没有记错的话,它至少需要3个对应关系(估计6个DOF)。