Python-OpenCV 处理视频(三): 标记运动轨迹
admin
2023-07-31 00:44:44
0

0x00. 光流

光流是进行视频中运动对象轨迹标记的一种很常用的方法,在OpenCV中实现光流也很容易。

CalcOpticalFlowPyrLK 函数计算一个稀疏特征集的光流,使用金字塔中的迭代 Lucas-Kanade 方法。

简单的实现流程:

  1. 加载一段视频。
  2. 调用GoodFeaturesToTrack函数寻找兴趣点。
  3. 调用CalcOpticalFlowPyrLK函数计算出两帧图像中兴趣点的移动情况。
  4. 删除未移动的兴趣点。
  5. 在两次移动的点之间绘制一条线段。

代码示例:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 import cv2.cv as cv capture = cv.CaptureFromFile(\’img/myvideo.avi\’) nbFrames = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_COUNT))fps = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FPS)wait = int(1/fps * 1000/1)width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH))height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT)) prev_gray = cv.CreateImage((width,height), 8, 1) #Will hold the frame at t-1gray = cv.CreateImage((width,height), 8, 1) # Will hold the current frame prevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) #Will hold the pyr frame at t-1currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) # idem at t max_count = 500qLevel= 0.01minDist = 10prev_points = [] #Points at t-1curr_points = [] #Points at tlines=[] #To keep all the lines overtime for f in xrange( nbFrames ):     frame = cv.QueryFrame(capture) #Take a frame of the video     cv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to gray    output = cv.CloneImage(frame)     prev_points = cv.GoodFeaturesToTrack(gray, None, None, max_count, qLevel, minDist) #Find points on the image     #Calculate the movement using the previous and the current frame using the previous points    curr_points, status, err = cv.CalcOpticalFlowPyrLK(prev_gray, gray, prevPyr, currPyr, prev_points, (10, 10), 3, (cv.CV_TERMCRIT_ITER|cv.CV_TERMCRIT_EPS,20, 0.03), 0)      #If points status are ok and distance not negligible keep the point    k = 0    for i in range(len(curr_points)):        nb =  abs( int(prev_points[i][0])int(curr_points[i][0]) ) + abs( int(prev_points[i][1])int(curr_points[i][1]) )        if status[i] and  nb > 2 :            prev_points[k] = prev_points[i]            curr_points[k] = curr_points[i]            k += 1     prev_points = n class=\”crayon-o\”>+= 1     prev_points = li>加载一段视频。

  • 调用GoodFeaturesToTrack函数寻找兴趣点。
  • 调用CalcOpticalFlowPyrLK函数计算出两帧图像中兴趣点的移动情况。
  • 删除未移动的兴趣点。
  • 在两次移动的点之间绘制一条线段。
  • 代码示例:

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 import cv2.cv as cv capture = cv.CaptureFromFile(\’img/myvideo.avi\’) nbFrames = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_COUNT))fps = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FPS)wait = int(1/fps * 1000/1)width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH))height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT)) prev_gray = cv.CreateImage((width,height), 8, 1) #Will hold the frame at t-1gray = cv.CreateImage((width,height), 8, 1) # Will hold the current frame prevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) #Will hold the pyr frame at t-1currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) # idem at t max_count = 500qLevel= 0.01minDist = 10prev_points = [] #Points at t-1curr_points = [] #Points at tlines=[] #To keep all the lines overtime for f in xrange( nbFrames ):     frame = cv.QueryFrame(capture) #Take a frame of the video     cv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to gray    output = cv.CloneImage(frame)     prev_points = cv.GoodFeaturesToTrack(gray, None, None, max_count, qLevel, minDist) #Find points on the image     #Calculate the movement using the previous and the current frame using the previous points    curr_points, status, err = cv.CalcOpticalFlowPyrLK(prev_gray, gray, prevPyr, currPyr, prev_points, (10, 10), 3, (cv.CV_TERMCRIT_ITER|cv.CV_TERMCRIT_EPS,20, 0.03), 0)      #If points status are ok and distance not negligible keep the point    k = 0    for i in range(len(curr_points)):        nb =  abs( int(prev_points[i][0])int(curr_points[i][0]) ) + abs( int(prev_points[i][1])int(curr_points[i][1]) )        if status[i] and  nb > 2 :            prev_points[k] = prev_points[i]            curr_points[k] = curr_points[i]            k += 1     

    相关内容

    热门资讯

    Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
    定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
    scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
    500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
    小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
    pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
    微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
    65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
    Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
    项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...