C++ 基于光流的OpenCV跟踪
我使用这个函数作为跟踪算法的基础C++ 基于光流的OpenCV跟踪,c++,opencv,computer-vision,tracking,C++,Opencv,Computer Vision,Tracking,我使用这个函数作为跟踪算法的基础 //1. detect the features cv::goodFeaturesToTrack(gray_prev, // the image features, // the output detected features max_count, // the maximum number of features qlevel, // quality level minDist); //
//1. detect the features
cv::goodFeaturesToTrack(gray_prev, // the image
features, // the output detected features
max_count, // the maximum number of features
qlevel, // quality level
minDist); // min distance between two features
// 2. track features
cv::calcOpticalFlowPyrLK(
gray_prev, gray, // 2 consecutive images
points_prev, // input point positions in first im
points_cur, // output point positions in the 2nd
status, // tracking success
err); // tracking error
cv::calcOpticalFlowPyrLK
将上一幅图像中的点向量作为输入,并在下一幅图像上返回适当的点。假设我在上一张图像上有随机像素(x,y),我如何使用OpenCV光流函数计算下一张图像上该像素的位置?在您编写时,cv::goodFeaturesToTrack
将图像作为输入,并生成它认为“适合跟踪”的点向量。这些是根据他们从周围环境中脱颖而出的能力选择的,并且是基于图像中的哈里斯角点。跟踪器通常通过将第一张图像传递给goodFeaturesToTrack并获得一组要跟踪的特征来初始化。然后,这些特征可以作为上一个点和序列中的下一个图像一起传递给cv::calcOpticalFlowPyrLK
,它将生成下一个点作为输出,然后在下一次迭代中成为输入点
如果您想尝试跟踪一组不同的像素(而不是由cv::goodFeaturesToTrack
或类似函数生成的特征),只需将它们与下一幅图像一起提供给cv::calcOpticalFlowPyrLK
非常简单,在代码中:
// Obtain first image and set up two feature vectors
cv::Mat image_prev, image_next;
std::vector<cv::Point> features_prev, features_next;
image_next = getImage();
// Obtain initial set of features
cv::goodFeaturesToTrack(image_next, // the image
features_next, // the output detected features
max_count, // the maximum number of features
qlevel, // quality level
minDist // min distance between two features
);
// Tracker is initialised and initial features are stored in features_next
// Now iterate through rest of images
for(;;)
{
image_prev = image_next.clone();
feature_prev = features_next;
image_next = getImage(); // Get next image
// Find position of feature in new image
cv::calcOpticalFlowPyrLK(
image_prev, image_next, // 2 consecutive images
points_prev, // input point positions in first im
points_next, // output point positions in the 2nd
status, // tracking success
err // tracking error
);
if ( stopTracking() ) break;
}
//获取第一幅图像并设置两个特征向量
cv::Mat image_prev,image_next;
std::向量特征上一个,特征下一个;
image_next=getImage();
//获取初始特征集
cv::goodFeaturesToTrack(图像\下一步,//图像
features\u next,//输出检测到的特征
max\u count,//功能的最大数量
qlevel,//质量级别
minDist//两个特征之间的最小距离
);
//跟踪器已初始化,初始特征存储在特征库中
//现在遍历其余的图像
对于(;;)
{
image_prev=image_next.clone();
特征\上一个=特征\下一个;
image_next=getImage();//获取下一幅图像
//在新图像中查找特征的位置
cv::CalCopticalFlowPyrk(
image\u prev,image\u next,//2个连续图像
points\u prev,//在第一个im中输入点位置
点\下一步,//输出第二个点的位置
状态,//跟踪成功
错误//跟踪错误
);
如果(stopTracking())中断;
}
cv::calcOpticalFlowPyrLK(..)函数使用参数:
cv::calcOpticalFlowPyrLK(上一个灰色、当前灰色、特征上一个、特征下一个、状态、错误)
如果成功找到像素
状态[0]==1
和特征_next[0]
将显示下一帧中像素的坐标。在本例中可以找到值信息:OpenCV/samples/cpp/lkdemo.cpp
我注意到您只进行了一次功能检测。我已经测试了这段代码。我发现只有在第一张图像上检测到的特征才能被跟踪。如果所有这些特征都超出了图像的范围,那么就没有可跟踪的特征。我需要使用光流进行3D构建。那么,我们如何在不断跟踪旧特征的同时添加新的图像特征呢?谢谢。是的,您只检测到具有goodFeaturesToTrack
的功能,然后光流方法只跟踪它们。如果要在每个帧中保留一定数量的特征,则必须检测成功跟踪到当前帧的特征数量,然后尝试检测要跟踪到下一帧的其他特征。另一种方法是检测每一帧中的特征,然后计算描述符并使用上的函数匹配这些描述符。如果需要更多详细信息,最好问一个新问题。因为我处理视频序列,所以我更喜欢使用光流进行特征匹配。如果我在每一帧中检测到特征,这些特征将不会被稳定地跟踪,因为这次检测到的特征下次可能不会被检测到。谢谢你的回复。但我不明白如何“检测更多的”?例如,如果我在第一帧中检测到100个特征,现在在视野中仅检测到50个,那么我如何在保持旧的50个特征的同时检测额外的50个特征?我认为唯一的解决方案是运行goodFeaturesToTrack来检测一组新的100个功能,对吗?我发布了一个关于这方面的新问题:
cv::Mat prev_gray, curr_gray;
std::vector<cv::Point2f> features_prev, features_next;
std::vector<uchar> status;
std::vector<float> err;
features_prev.push_back(cv::Point(4, 5));
cv::calcOpticalFlowPyrLK(prev_gray, curr_gray, features_prev, features_next, status, err);