0x00. 光流

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

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

简单的实现流程:

  1. 加载一段视频。

  2. 调用GoodFeaturesToTrack函数寻找兴趣点。

  3. 调用CalcOpticalFlowPyrLK函数计算出两帧图像中兴趣点的移动情况。

  4. 删除未移动的兴趣点。

  5. 在两次移动的点之间绘制一条线段。

代码示例:

import cv2.cv as cvcapture = 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-1
gray = cv.CreateImage((width,height), 8, 1) # Will hold the current frameprevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) #Will hold the pyr frame at t-1
currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) # idem at tmax_count = 500
qLevel= 0.01
minDist = 10
prev_points = [] #Points at t-1
curr_points = [] #Points at t
lines=[] #To keep all the lines overtimefor f in xrange( nbFrames ):frame = cv.QueryFrame(capture) #Take a frame of the videocv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to grayoutput = 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 pointscurr_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 pointk = 0for 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 += 1prev_points = prev_points[:k]curr_points = curr_points[:k]#At the end only interesting points are kept#Draw all the previously kept lines otherwise they would be lost the next framefor (pt1, pt2) in lines:cv.Line(frame, pt1, pt2, (255,255,255))#Draw the lines between each points at t-1 and tfor prevpoint, point in zip(prev_points,curr_points):prevpoint = (int(prevpoint[0]),int(prevpoint[1]))cv.Circle(frame, prevpoint, 15, 0)point = (int(point[0]),int(point[1]))cv.Circle(frame, point, 3, 255)cv.Line(frame, prevpoint, point, (255,255,255))lines.append((prevpoint,point)) #Append current lines to the lines listcv.Copy(gray, prev_gray) #Put the current frame prev_grayprev_points = curr_pointscv.ShowImage("The Video", frame)#cv.WriteFrame(writer, frame)cv.WaitKey(wait)

直接调用摄像头使用该方法:

import cv2.cv as cvcapture = cv.CaptureFromCAM(0)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)
gray = cv.CreateImage((width,height), 8, 1)prevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) #Will hold the pyr frame at t-1
currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1) # idem at tmax_count = 500
qLevel= 0.01
minDist = 10
prev_points = [] #Points at t-1
curr_points = [] #Points at t
lines=[] #To keep all the lines overtimewhile True:frame = cv.QueryFrame(capture)cv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to grayoutput = cv.CloneImage(frame)prev_points = cv.GoodFeaturesToTrack(gray, None, None, max_count, qLevel, minDist)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 pointk = 0for 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 += 1prev_points = prev_points[:k]curr_points = curr_points[:k]#At the end only interesting points are kept#Draw all the previously kept lines otherwise they would be lost the next framefor (pt1, pt2) in lines:cv.Line(frame, pt1, pt2, (255,255,255))#Draw the lines between each points at t-1 and tfor prevpoint, point in zip(prev_points,curr_points):prevpoint = (int(prevpoint[0]),int(prevpoint[1]))cv.Circle(frame, prevpoint, 15, 0)point = (int(point[0]),int(point[1]))cv.Circle(frame, point, 3, 255)cv.Line(frame, prevpoint, point, (255,255,255))lines.append((prevpoint,point)) #Append current lines to the lines listcv.Copy(gray, prev_gray) #Put the current frame prev_grayprev_points = curr_pointscv.ShowImage("The Video", frame)#cv.WriteFrame(writer, frame)c = cv.WaitKey(1)if c == 27: #Esc on Windowsbreak

0x01. 寻找最大特征值的角点

cv.GoodFeaturesToTrack 函数可以检测出图像中最大特征值的角点,使用这个函数可以对图像中的特征点进行跟踪,从而绘制出运动轨迹。

直接加载视频:

import cv2.cv as cvcapture = cv.CaptureFromFile('img/myvideo.avi')#-- Informations about the video --
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))
#For recording
#codec = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FOURCC)
#writer=cv.CreateVideoWriter("img/output.avi", int(codec), int(fps), (width,height), 1) #Create writer with same parameters
#----------------------------------prev_gray = cv.CreateImage((width,height), 8, 1) #Will hold the frame at t-1
gray = cv.CreateImage((width,height), 8, 1) # Will hold the current frameoutput = cv.CreateImage((width,height), 8, 3)prevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1)
currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1)max_count = 500
qLevel= 0.01
minDist = 10begin = Trueinitial = []
features = []
prev_points = []
curr_points = []for f in xrange( nbFrames ):frame = cv.QueryFrame(capture)cv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to graycv.Copy(frame, output)if (len(prev_points) <= 10): #Try to get more points#Detect points on the imagefeatures = cv.GoodFeaturesToTrack(gray, None, None, max_count, qLevel, minDist)prev_points.extend(features) #Add the new points to listinitial.extend(features) #Idemif begin:cv.Copy(gray, prev_gray) #Now we have two frames to comparebegin = False#Compute movementcurr_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 pointk = 0for 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 :initial[k] = initial[i]curr_points[k] = curr_points[i]k += 1curr_points = curr_points[:k]initial = initial[:k]#At the end only interesting points are kept#Draw the line between the first position of a point and the#last recorded position of the same pointfor i in range(len(curr_points)):cv.Line(output, (int(initial[i][0]),int(initial[i][1])), (int(curr_points[i][0]),int(curr_points[i][1])), (255,255,255))cv.Circle(output, (int(curr_points[i][0]),int(curr_points[i][1])), 3, (255,255,255))cv.Copy(gray, prev_gray)prev_points = curr_pointscv.ShowImage("The Video",  output)cv.WriteFrame(writer, output)cv.WaitKey(wait)

调用摄像头绘制:

import cv2.cv as cvcapture = cv.CaptureFromCAM(0)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-1
gray = cv.CreateImage((width,height), 8, 1) # Will hold the current frameoutput = cv.CreateImage((width,height), 8, 3)prevPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1)
currPyr = cv.CreateImage((height / 3, width + 8), 8, cv.CV_8UC1)max_count = 500
qLevel= 0.01
minDist = 10begin = Trueinitial = []
features = []
prev_points = []
curr_points = []while True:frame = cv.QueryFrame(capture)cv.CvtColor(frame, gray, cv.CV_BGR2GRAY) #Convert to graycv.Copy(frame, output)if (len(prev_points) <= 10): #Try to get more points#Detect points on the imagefeatures = cv.GoodFeaturesToTrack(gray, None, None, max_count, qLevel, minDist)prev_points.extend(features) #Add the new points to listinitial.extend(features) #Idemif begin:cv.Copy(gray, prev_gray) #Now we have two frames to comparebegin = False#Compute movementcurr_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 pointk = 0for 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 :initial[k] = initial[i]curr_points[k] = curr_points[i]k += 1curr_points = curr_points[:k]initial = initial[:k]for i in range(len(curr_points)):cv.Line(output, (int(initial[i][0]),int(initial[i][1])), (int(curr_points[i][0]),int(curr_points[i][1])), (255,255,255))cv.Circle(output, (int(curr_points[i][0]),int(curr_points[i][1])), 3, (255,255,255))cv.Copy(gray, prev_gray)prev_points = curr_pointscv.ShowImage("The Video", output)c = cv.WaitKey(1)if c == 27: #Esc on Windowsbreak

Python-OpenCV 处理视频(三): 标记运动轨迹相关推荐

  1. 解决Python OpenCV 读取视频并抽帧出现error while decoding的问题

    解决Python OpenCV 读取视频抽帧出现error while decoding的问题 1. 问题 2. 解决 3. 源代码 参考 1. 问题 读取H264视频,抽帧视频并保存,报错如下: [ ...

  2. 使用Python,OpenCV在视频中进行实时条形码检测

    使用Python,OpenCV在视频中进行实时条形码检测 1. 步骤 2. 适用场景及优化 3. 总结 4. 源码 参考 上一篇博客介绍了如何检测和查找图像中的条形码.这篇博客将进行一些优化以检测实时 ...

  3. python图片转视频加特效_使用Python opencv实现视频与图片的相互转换

    因为最近要经常转换数据集进行实验,因此记录一下. 1.视频转图片 即为将视频解析为一帧一帧的图片: import cv2 vc=cv2.VideoCapture("/home/hqd/Pyc ...

  4. python opencv 图片/视频 拼接

    python opencv 图片/视频 拼接 # coding: utf-8 # 像写诗一样写代码 import numpy as np import cv2img_A_path = "C: ...

  5. python opencv写视频——cv2.VideoWriter()

    python opencv写视频--cv2.VideoWriter() 函数原型 cv2.VideoWriter() VideoWriter(filename, fourcc, fps, frameS ...

  6. python opencv PIL 视频分割成图片 图片合成为视频 修改图片大小(抗锯齿)

    Python代码将原有的视频分割成图片,我的例子是一帧一帧的分割 用python+opencv完成视频的分割 import cv2 #导入opencv模块 print(2) #测试是否运行 vc=cv ...

  7. python opencv 录制视频_如何使用OpenCV、Python和深度学习在图像和视频中实现面部识别?...

    Face ID 的兴起带动了一波面部识别技术热潮.本文将介绍如何使用 OpenCV.Python 和深度学习在图像和视频中实现面部识别,以基于深度识别的面部嵌入,实时执行且达到高准确度. 以下内容由 ...

  8. 利用Python+opencv进行视频文件的读取和保存,打开笔记本摄像头拍照保存、图像在窗口显示等操作

    版权声明:本文为博主原创文章,转载请附源链接 一.视频文件的读取和保存 Opencv中视频的读入是用VideoCapture函数,保存用的是VideoWriter函数.这两个函数支持的视频格式因电脑系 ...

  9. python opencv读取视频没声音_python + opencv: 解决不能读取视频的问题

    博主一开始使用python2.7和Opencv2.4.10来获取摄像头图像,程序如下: cap = cv2.VideoCapture(0) ret, frame = cap.read() 使用这个程序 ...

  10. python+opencv横向拼接视频

    如果想利用python+opencv把两段视频拼接在一起,可以有两种想法: 1. 第二个视频直接接在第一个视频后边,延长帧.这种我称为"纵向拼接": 2. 第一个视频和第二个视频每 ...

最新文章

  1. 解决:此错误(HTTP 500 内部服务器错误)意味着您正在访问的网站出现了服务器问题,此问题阻止了该网页的显示...
  2. ssm项目快速搭建(注解)-依赖
  3. 前端学习(537):多列布局4横跨多列
  4. PHP 表单文件上传的原理,php多文件上传功能实现原理及代码
  5. django 1.8 官方文档翻译: 3-6-2 内建的中间件
  6. vue中怎么点击修改文字_杭州展馆设计中说明牌和说明文字怎么样才能使用最大化?...
  7. centos时间同步
  8. Android MVP 实例
  9. python获取当前时间的源代码_python怎么获取当前系统时间
  10. 西门子1200 PLC程序 通讯对象:PLC、CNC、机械手、RFID标签读写器、打标机、分布式远程IO模块、MES中控系统、AGV光通讯
  11. HP惠普笔记本电脑暗影精灵5 OMEN by HP 15-dh0153tx原装出厂Win10系统恢复原厂OEM系统
  12. jdbc mysql 5.05_JDBC 连接 MySQL 时碰到的小坑
  13. linkerd 本地环境安装
  14. SDU信息门户(8)组队和文件系统分析
  15. 求1+2!+3!+...+N!的和
  16. 关于谷歌浏览器无法正常上传图片的问题
  17. Compound word transformer代码详解(一)数据预处理
  18. QDUOJ 点击此处签到(并查集)
  19. 宝鸡机电学院计算机中心电话,机电工程学院
  20. 《电路基础》反相运算放大器

热门文章

  1. 记一次redis规模化运维讨论会
  2. Spring Enable annotation – writing a custom Enable annotation
  3. spring mvc使用的一些注意事项
  4. SonarQube代码质量管理平台安装与使用--转载
  5. Bash For Loop Examples for Your Linux Shell Scripting--ref
  6. nginx 学习笔记(6) nginx配置文件中的度量单位
  7. IOS审核的各个状态的时间
  8. 【采用】机器学习在金融大数据风险建模中的应用
  9. 基于正则化的特征选择
  10. 百分点认知智能实验室:NLP模型开发平台在舆情分析中的设计和实践(下)