Python-OpenCV 处理视频(三): 标记运动轨迹
0x00. 光流
光流是进行视频中运动对象轨迹标记的一种很常用的方法,在OpenCV中实现光流也很容易。
CalcOpticalFlowPyrLK
函数计算一个稀疏特征集的光流,使用金字塔中的迭代 Lucas-Kanade 方法。
简单的实现流程:
加载一段视频。
调用
GoodFeaturesToTrack
函数寻找兴趣点。调用
CalcOpticalFlowPyrLK
函数计算出两帧图像中兴趣点的移动情况。删除未移动的兴趣点。
在两次移动的点之间绘制一条线段。
代码示例:
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 处理视频(三): 标记运动轨迹相关推荐
- 解决Python OpenCV 读取视频并抽帧出现error while decoding的问题
解决Python OpenCV 读取视频抽帧出现error while decoding的问题 1. 问题 2. 解决 3. 源代码 参考 1. 问题 读取H264视频,抽帧视频并保存,报错如下: [ ...
- 使用Python,OpenCV在视频中进行实时条形码检测
使用Python,OpenCV在视频中进行实时条形码检测 1. 步骤 2. 适用场景及优化 3. 总结 4. 源码 参考 上一篇博客介绍了如何检测和查找图像中的条形码.这篇博客将进行一些优化以检测实时 ...
- python图片转视频加特效_使用Python opencv实现视频与图片的相互转换
因为最近要经常转换数据集进行实验,因此记录一下. 1.视频转图片 即为将视频解析为一帧一帧的图片: import cv2 vc=cv2.VideoCapture("/home/hqd/Pyc ...
- python opencv 图片/视频 拼接
python opencv 图片/视频 拼接 # coding: utf-8 # 像写诗一样写代码 import numpy as np import cv2img_A_path = "C: ...
- python opencv写视频——cv2.VideoWriter()
python opencv写视频--cv2.VideoWriter() 函数原型 cv2.VideoWriter() VideoWriter(filename, fourcc, fps, frameS ...
- python opencv PIL 视频分割成图片 图片合成为视频 修改图片大小(抗锯齿)
Python代码将原有的视频分割成图片,我的例子是一帧一帧的分割 用python+opencv完成视频的分割 import cv2 #导入opencv模块 print(2) #测试是否运行 vc=cv ...
- python opencv 录制视频_如何使用OpenCV、Python和深度学习在图像和视频中实现面部识别?...
Face ID 的兴起带动了一波面部识别技术热潮.本文将介绍如何使用 OpenCV.Python 和深度学习在图像和视频中实现面部识别,以基于深度识别的面部嵌入,实时执行且达到高准确度. 以下内容由 ...
- 利用Python+opencv进行视频文件的读取和保存,打开笔记本摄像头拍照保存、图像在窗口显示等操作
版权声明:本文为博主原创文章,转载请附源链接 一.视频文件的读取和保存 Opencv中视频的读入是用VideoCapture函数,保存用的是VideoWriter函数.这两个函数支持的视频格式因电脑系 ...
- python opencv读取视频没声音_python + opencv: 解决不能读取视频的问题
博主一开始使用python2.7和Opencv2.4.10来获取摄像头图像,程序如下: cap = cv2.VideoCapture(0) ret, frame = cap.read() 使用这个程序 ...
- python+opencv横向拼接视频
如果想利用python+opencv把两段视频拼接在一起,可以有两种想法: 1. 第二个视频直接接在第一个视频后边,延长帧.这种我称为"纵向拼接": 2. 第一个视频和第二个视频每 ...
最新文章
- 解决:此错误(HTTP 500 内部服务器错误)意味着您正在访问的网站出现了服务器问题,此问题阻止了该网页的显示...
- ssm项目快速搭建(注解)-依赖
- 前端学习(537):多列布局4横跨多列
- PHP 表单文件上传的原理,php多文件上传功能实现原理及代码
- django 1.8 官方文档翻译: 3-6-2 内建的中间件
- vue中怎么点击修改文字_杭州展馆设计中说明牌和说明文字怎么样才能使用最大化?...
- centos时间同步
- Android MVP 实例
- python获取当前时间的源代码_python怎么获取当前系统时间
- 西门子1200 PLC程序 通讯对象:PLC、CNC、机械手、RFID标签读写器、打标机、分布式远程IO模块、MES中控系统、AGV光通讯
- HP惠普笔记本电脑暗影精灵5 OMEN by HP 15-dh0153tx原装出厂Win10系统恢复原厂OEM系统
- jdbc mysql 5.05_JDBC 连接 MySQL 时碰到的小坑
- linkerd 本地环境安装
- SDU信息门户(8)组队和文件系统分析
- 求1+2!+3!+...+N!的和
- 关于谷歌浏览器无法正常上传图片的问题
- Compound word transformer代码详解(一)数据预处理
- QDUOJ 点击此处签到(并查集)
- 宝鸡机电学院计算机中心电话,机电工程学院
- 《电路基础》反相运算放大器
热门文章
- 记一次redis规模化运维讨论会
- Spring Enable annotation – writing a custom Enable annotation
- spring mvc使用的一些注意事项
- SonarQube代码质量管理平台安装与使用--转载
- Bash For Loop Examples for Your Linux Shell Scripting--ref
- nginx 学习笔记(6) nginx配置文件中的度量单位
- IOS审核的各个状态的时间
- 【采用】机器学习在金融大数据风险建模中的应用
- 基于正则化的特征选择
- 百分点认知智能实验室:NLP模型开发平台在舆情分析中的设计和实践(下)