OpenCV视觉分析之目标跟踪(3)实现基于金字塔的 Lucas-Kanade 算法来进行稀疏光流计算的类SparsePyrLKOpticalFlow的使用
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
用于计算稀疏光流的类。
该类可以使用带有金字塔的迭代 Lucas-Kanade 方法来计算稀疏特征集的光流
cv::SparsePyrLKOpticalFlow 类是 OpenCV 库中的一个类,用于实现基于金字塔的 Lucas-Kanade 算法来进行稀疏光流计算。这个类特别适合用来跟踪图像序列中的特征点,比如在视频中跟踪物体的关键点。
主要特点
- 稀疏光流:只计算选定特征点的运动。
- 金字塔结构:通过多尺度金字塔来提高跟踪的鲁棒性和准确性。
- Lucas-Kanade 算法:使用 Lucas-Kanade 方法来计算特征点的位移。
成员函数
- 构造函数:创建 cv::SparsePyrLKOpticalFlow 对象。
- setMaxLevel(int maxLevel):设置金字塔的最大层数。
- setWinSize(cv::Size winSize):设置用于计算光流的窗口大小。
- calc(const cv::Mat &prevImg, const cv::Mat &nextImg, const cv::InputArray &prevPts, cv::OutputArray &nextPts, cv::OutputArray &status, cv::OutputArray &err):计算光流并返回新的特征点位置以及状态和误差。
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
// 加载两个图像帧
cv::Mat prevImg = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg", cv::IMREAD_GRAYSCALE );
cv::Mat nextImg = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg", cv::IMREAD_GRAYSCALE );
if ( !prevImg.data || !nextImg.data )
{
std::cout << "Error loading images" << std::endl;
return -1;
}
// 检测特征点
std::vector< cv::Point2f > prevPts;
std::vector< cv::Point2f > nextPts;
std::vector< uchar > status;
std::vector< float > err;
// 检测特征点(例如使用 Shi-Tomasi 角点检测)
std::vector< cv::Point2f > corners;
cv::goodFeaturesToTrack( prevImg, corners, 100, 0.01, 10, cv::Mat() );
// 创建 SparsePyrLKOpticalFlow 对象
cv::Ptr< cv::SparsePyrLKOpticalFlow > lk = cv::SparsePyrLKOpticalFlow::create();
// 设置参数
lk->setMaxLevel( 2 );
lk->setWinSize( cv::Size( 15, 15 ) );
// 计算光流
lk->calc( prevImg, nextImg, corners, nextPts, status, err );
// 可视化结果
cv::Mat outImg = cv::Mat::zeros( prevImg.size(), CV_8UC3 );
for ( size_t i = 0; i < corners.size(); i++ )
{
if ( status[ i ] )
{
cv::circle( outImg, corners[ i ], 5, cv::Scalar( 0, 255, 0 ), -1 );
cv::line( outImg, corners[ i ], nextPts[ i ], cv::Scalar( 0, 0, 255 ), 2 );
}
}
// 显示结果
cv::imshow( "Sparse Optical Flow", outImg );
cv::waitKey( 0 );
return 0;
}