基于光流方法实时跟踪目标在图像中的运动轨迹(python和C++实现)

这篇具有很好参考价值的文章主要介绍了基于光流方法实时跟踪目标在图像中的运动轨迹(python和C++实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

光流方法是通过跟踪图像中的特征点(角点,边缘点等),分析这些点在帧与帧之间的运动,来计算物体运动轨迹和速度。具体实现目标如下:
1、选取图像中的易被识别的特征点,如Harris角点,FAST角点。
2、为每个特征点选取一个领域窗口,跟踪该窗口在连续视频帧中的变化。
3、计算窗口中每个像素在两帧之间的光流,也就是像素位移量,常用的光流计算方法有Lucas-Kanada法、Gunner Farneback法等。
4、根据窗口中的光流情况判断该特征点的位移量。可以采取投票机制或窗口内光流的中值作为该点的移动量。
5、 根据特征点的移动向量就可以计算出物体运动的速度和方向。 通过跟踪多个特征点并做平均可以得到更精确的运动速度估计。
6、结合物体在三维空间的位置信息,可以将二维图像平面上的特征点轨迹还原出三维空间中的运动路径。
7、当特征点消失或运动过快时,需要选取图像中新的特征点进行跟踪,确保在每一帧中有足够的特征点对物体进行跟踪。
8、根据目标的运动趋势,可以预测其未来的移动位置和速度。为了实现精确定位,预测结果需要与实时检测结果进行融合。
以上是使用光流方法实现目标跟踪的基本思路和技术步骤。通过选取图像中的特征点,分析其在连续视频帧之间的运动变化,实现对目标运动的检测、跟踪和预测。在实际实现中存在光流计算的准确性与速度问题,这需要选择适合的算法与优化方法。

python版domo
这个Demo通过Opencv的calcOpticalFlowFarneback()方法计算两帧图像之间的光流。然后绘制光流向量和场,实现了基本的目标运动跟踪和显示。
在实际项目中,可以根据光流分析得到的目标移动信息,预测其未来位置,并结合三维位置实现精确跟踪。如果光流无法准确跟踪,还需要选取新的特征点进行跟踪。
这只是一个基本Demo,实际项目实现会更加复杂。但基本思路与步骤仍然适用。请根据具体需求对代码进行完善和优化。

import cv2
import numpy as np

cap = cv2.VideoCapture('input.mp4')  # 读取视频文件
ret, frame1 = cap.read()  # 读取第一帧
prvs = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY) # 转换为灰度图像

while(1):
    ret, frame2 = cap.read()  # 读取后续帧
    next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY) # 转化为灰度图像

    # 计算光流
    flow = cv2.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)

    # 计算光流的角度和幅值
    h, w = next.shape[:2]
    y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
    fx, fy = flow[y,x].T
    
    # 绘制光流场和向量
    lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
    lines = np.int32(lines + 0.5)
    vis = cv2.cvtColor(next, cv2.COLOR_GRAY2BGR)
    for (x1, y1), (x2, y2) in lines:
        cv2.line(vis, (x1, y1), (x2, y2), (0, 255, 0), 1)
        cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
    #显示图像
    cv2.imshow('frame2', vis)
    prvs = next # 更新前一帧
    
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

C++版demo
该代码完成了视频中目标的光流跟踪。主要步骤为:文章来源地址https://www.toymoban.com/news/detail-423890.html

  1. 对第一帧图像检测Harris角点作为特征点。
  2. 读取第二帧图像,同样检测特征点。
  3. 利用calcOpticalFlowPyrLK函数计算第一帧和第二帧特征点之间的光流,获得新的特征点位置。
  4. 在图像上绘制光流跟踪结果,并更新特征点用于下一帧跟踪。
  5. 不断读取新帧并重复以上步骤,实现对目标运动的连续跟踪。
    该实现较为简单,主要目的在于演示光流方法的基本思想和步骤。实际项目中会根据具体应用对算法进行优化和改进。
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() 
{
    // 读取视频文件
    VideoCapture cap("input.avi"); 
    // 获取第一帧
    Mat frame1, frame2;
    cap >> frame1;

    // 对第一帧检测Harris角点 
    vector<Point2f> points1;
    cornerHarris(frame1, points1, 2, 3, 0.04, 3, 0);

    while (cap.read(frame2)) {
        // 对第二帧进行角点检测
        vector<Point2f> points2;
        cornerHarris(frame2, points2, 2, 3, 0.04, 3, 0);
       
        // 光流跟踪
        vector<Point2f> newPoints; 
        calcOpticalFlowPyrLK(frame1, frame2, points1, newPoints);
       
        // 显示跟踪结果 
        for (int i = 0; i < points1.size(); i++) 
        {  
            line(frame1, points1[i], newPoints[i], Scalar(0,255,0), 1.5);  
            circle(frame1, newPoints[i], 3, Scalar(0,0,255), -1); 
        }
       
        // 更新帧和跟踪角点 
        points1 = newPoints; 
        frame1 = frame2.clone();
       
        // 显示视频 
        imshow("Tracking", frame1);
       
        if (waitKey(30) == 27) break; 
    }
}

到了这里,关于基于光流方法实时跟踪目标在图像中的运动轨迹(python和C++实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包