我编写了一个程序,它使用goodFeaturesToTrack和calcOpticalFlowPyrLK来逐帧跟踪功能。该程序可靠地工作,并且可以从前一帧估计Android相机上的预览图像中的光流。以下是描述一般过程的一些片段:
goodFeaturesToTrack(grayFrame, corners, MAX_CORNERS, quality_level,
min_distance, cv::noArray(), eig_block_size, use_harris, 0.06);
...
if (first_time == true) {
first_time = false;
old_corners = corners;
safe_corners = corners;
mLastImage = grayFrame;
} else {
if (old_corners.size() > 0 && corners.size() > 0) {
safe_corners = corners;
calcOpticalFlowPyrLK(mLastImage, grayFrame, old_corners, corners,
status, error, Size(21, 21), 5,
TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30,
0.01));
} else {
//no features found, so let's start over.
first_time = true;
}
}
上面的代码在一个循环中反复运行,在每次迭代中抓取一个新的预览框架。 Safe_corners,old_corners和corner都是类向量的数组< Point2f> 。上面的代码效果很好。
现在,对于我已经确定的每个功能,我希望能够分配一些有关该功能的信息...找到的次数,可能是该功能的描述符,谁知道...我的第一个这样做的方法是:
class Feature: public Point2f {
private:
//things about a feature that I want to track
public:
//getters and fetchers and of course:
Feature() {
Point2f();
}
Feature(float a, float b) {
Point2f(a,b);
}
}
接下来,我的所有outputArrays都从vector< Point2f>矢量<特征>在我自己扭曲的世界中应该有效,因为Feature被定义为Point2f的后代类。多态性应用,我无法想象为什么这应该呕吐我,除非我做了其他可怕的错误。
以下是我收到的错误消息。
OpenCV错误:断言失败(func!= 0)在void cv :: Mat :: convertTo(cv :: OutputArray,int,double,double)const,file / home / reports / ci / slave50-SDK / opencv /modules/core/src/convert.cpp,第1095行
所以,我对论坛的问题是OpenCV函数是否真的需要Point2f向量,或者Point2f的后代类是否也能正常工作?下一步是让gdb在Android手机上使用移动代码并更准确地查看它崩溃的位置,但是如果我的方法存在根本缺陷,我不想走这条路。
或者,如果使用上述方法跨多个帧跟踪某个要素,每个点的内存地址是否会发生变化?
提前致谢。
答案 0 :(得分:0)
简短回答是是,OpenCV函数确实需要std::vector<cv::Point2f>
作为参数。
请注意,向量本身包含cv::Point2f
个对象,而不是指针到cv::Point2f
,因此没有多态行为。
此外,让Feature
继承cv::Point2f
可能不是理想的解决方案。在这种情况下使用合成会更简单,更不用说建立正确的关系(Feature
has -a cv::Point2f
)。
依赖对象在内存中的位置也可能不是一个好主意。相反,请阅读您选择的数据结构。
答案 1 :(得分:0)
我自己刚刚进入OpenCV,所以无法解决代码的这个方面,但是你的问题可能是你的代码中的一个错误导致了一个未初始化的基类(至少没有像你期望的那样初始化)。您的代码应如下所示:
Feature()
: Point2f()
{
}
Feature(float a, float b)
: Point2f(a,b)
{
}
您的实现在构造函数中创建了两个临时的Point2f对象。这些临时对象不初始化Feature对象的Point2f基类,并且这些临时对象在构造函数的末尾被销毁。