11- OpenCV进行目标追踪 (OpenCV系列) (机器视觉)
知识要点
1. OpenCV目标跟踪算法的使用大概可以分为以下几个步骤:
创建MultiTracker对象: trackers = cv2.legacy.MultiTracker_create()
读取视频或摄像头数据: cap = cv2.VideoCapture('./videos/soccer_02.mp4')
框选ROI区域: roi = cv2.selectROI('frame', frame, showCrosshair = True)
添加实际的追踪算法. tracker = OPENCV_OBJECT_TRACKERS['boosting'](), trackers.add(tracker, frame, roi)
对每一帧进行进行目标追踪: success, boxes = trackers.update(frame)
2. 光流估计:(稀疏光流估计算法为Lucas-Kanade算法, 比较经典)
- p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, gray, p0, None,winSize=(15,15),maxLevel=2) # p1为更新的点, st是状态
- cv2.calcOpticalFlowPyrLK() # 稀疏光流
- cv2.calcOpticalFlowFarneback() # 稠密光流
随机颜色 数组生成:
- color = np.random.randint(0, 255, (100, 3))
参考资料: 目标追踪综述 - 知乎
12 目标追踪
12.1 OpenCV目标追踪算法介绍
OpenCV上有八种不同的目标追踪算法:
- BOOSTING Tracker:和Haar cascades(AdaBoost)背后所用的机器学习算法相同,但是距其诞生已有十多年了。这一追踪器速度较慢,并且表现不好。(最低支持OpenCV 3.0.0)
- MIL Tracker:比上一个追踪器更精确,但是失败率比较高。(最低支持OpenCV 3.0.0)
- KCF Tracker:比BOOSTING和MIL都快,但是在有遮挡的情况下表现不佳。(最低支持OpenCV 3.1.0)
- CSRT Tracker:比KCF稍精确,但速度不如后者。(最低支持OpenCV 3.4.2)
- MedianFlow Tracker:出色的跟踪故障报告。当运动是可预测的并且没有遮挡时,效果非常好,但是对于快速跳动或快速移动的物体,模型会失效。(最低支持OpenCV 3.0.0)
- TLD Tracker:在多帧遮挡下效果最好。但是TLD的误报非常多,所以不推荐。(最低支持OpenCV 3.0.0)
- MOSSE Tracker:速度真心快,但是不如CSRT和KCF的准确率那么高,如果追求速度选它准没错。(最低支持OpenCV 3.4.1)
- GOTURN Tracker:这是OpenCV中唯一一深度学习为基础的目标检测器。它需要额外的模型才能运行。(最低支持OpenCV 3.2.0)
12.2 目标跟踪算法的使用
OpenCV目标跟踪算法的使用大概可以分为以下几个步骤:
创建MultiTracker对象.
读取视频或摄像头数据.
框选ROI区域
给MultiTracker对象添加实际的追踪算法.
对每一帧进行进行目标追踪.
下面是一个使用例子:
import cv2
import numpy as npcap = cv2.VideoCapture('./videos/los_angeles.mp4') # 读取视频
# 定义OpenCV的七种追踪算法
OPENCV_OBJECT_TRACKERS = {'boosting' : cv2.legacy.TrackerBoosting_create,'csrt' : cv2.legacy.TrackerCSRT_create,'kcf' : cv2.legacy.TrackerKCF_create,'mil' : cv2.legacy.TrackerMIL_create,'tld' : cv2.legacy.TrackerTLD_create,'medianflow' : cv2.legacy.TrackerMedianFlow_create,'mosse' :cv2.legacy.TrackerMOSSE_create}
trackers = cv2.legacy.MultiTracker_create() # 创建追踪器while True:flag, frame = cap.read()if frame is None:breakgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 变为黑白的# 目标追踪, # 第一帧追踪时为空,跳过success, boxes = trackers.update(frame)# print(boxes) # [[685. 433. 106. 84.]] 矩形位置会有调整# 绘制追踪到的矩形区域for box in boxes:# box是float的数据类型(x, y, w, h) = [int(v) for v in box]cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)cv2.imshow('frame', frame)key = cv2.waitKey(1)if key == ord('s'):# 框选ROI区域, 后两个参数的含义,是否包含中间十字和从中心点开始画roi = cv2.selectROI('frame',frame, showCrosshair = True, fromCenter = False)print(roi) # (1075, 326, 46, 70)# 创建实际的追踪器tracker = OPENCV_OBJECT_TRACKERS['boosting']()trackers.add(tracker, frame, roi)elif key == ord('q'):breakcap.release()
cv2.destroyAllWindows()
12.3 opencv 和深度学习结合 做目标识别
目标识别?
把图片变成tensor: blob = cv2.dnn.blobFromImage(img)
把图片给到网络预测: net.setInput(blob)
预测: net.forward()
import cv2
import numpy as npimg = cv2.imread('./smallcat.jpeg') # 读图片
# opencv 和深度学习结合
config = './bvlc_googlenet.prototxt' # 分类文件
model = './bvlc_googlenet.caffemodel' # 模型
net = cv2.dnn.readNetFromCaffe(config, model)# 图片转化为tensor
blob = cv2.dnn.blobFromImage(img, 1.0, (224, 224), (104, 117, 223))
net.setInput(blob)
r = net.forward()
print(r.shape) # (1, 1000) 1000类
# 读类别 # 看下比较明显的特征
classes = []
with open('./synset_words.txt', 'r') as fp:# find 函数返回字符串的索引 # strip 去掉结尾换行符号classes = [x[x.find(' ') + 1:].strip() for x in fp]
# 对得到的结果排序
order = sorted(r[0], reverse = True) # 1000类z = list(range(3)) # [0, 1, 2] # 只要前三的概率
for i in range(3):# 返回满足条件的索引z[i] = np.where(r[0] == order[i])[0][0]print(f'第{i + 1}项匹配:', classes[z[i]], end = '')print(' 类所在行:', z[i] + 1, ' ', '可能性:', order[i])cv2.imshow('img', img)
cv2.waitKey(50000)
cv2.destroyAllWindows()
第1项匹配: tabby, tabby cat 类所在行: 282 可能性: 0.2946576 第2项匹配: Egyptian cat 类所在行: 286 可能性: 0.2306798 第3项匹配: carton 类所在行: 479 可能性: 0.061365135
13 光流估计
光流,顾名思义,光的流动。比如人眼感受到的夜空中划过的流星。在计算机视觉中,定义图像中对象的移动,这个移动可以是相机移动或者物体移动引起的。具体是指,视频图像的一帧中的代表同一对象(物体)像素点移动到下一帧的移动量,使用二维向量表示.
根据是否选取图像稀疏点进行光流估计,可以将光流估计分为稀疏光流和稠密光流.
OpenCV中提供了光流估计的接口,包括 稀疏光流估计算法 cv2.calcOpticalFlowPyrLK(),和 稠密光流估计 cv2.calcOpticalFlowFarneback()。其中稀疏光流估计算法为Lucas-Kanade算法,该算法为1981年由Lucas和Kanade两位科学家提出的,最为经典也较容易理解的算法.
13.1 传统算法 Lucas-Kanade
为了将光流估计进行建模,Lucas-Kanade做了三个重要的假设:
亮度恒定:同一点随着时间的变化,其亮度不会发生改变。
小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。
空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解。
cv2.calcOpticalFlowPyrLK(): 参数:
prevImage 前一帧图像
nextImage 当前帧图像
prevPts 待跟踪的特征点向量
winSize 搜索窗口的大小
maxLevel 最大的金字塔层数
返回值:
nextPts 输出跟踪特征点向量
status 特征点是否找到,找到的状态为1,未找到的状态为0
import numpy as np
import cv2cap = cv2.VideoCapture('./test.avi') # 读取视频
ret, old_frame = cap.read() # 获取第一帧的图片
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY) # 变成黑白图# 检测角点
feature_params = dict(maxCorners = 100,qualityLevel = 0.3,minDistance = 7)
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)# 创建mask
mask = np.zeros_like(old_frame)
# 随机颜色
color = np.random.randint(0, 255, (100, 3))
while True:ret, frame = cap.read()if frame is None:breakgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 光流估计, p1为更新的点, st是状态p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, gray, p0, None,winSize = (15, 15), maxLevel = 2) # print(p1.shape, '==', st.shape) # (31, 1, 2) == (31, 1)# 哪些点找到了哪些没找到good_new = p1[st == 1]good_old = p0[st == 1]# print(good_new.shape, good_old.shape) # (38, 2) (38, 2)# 绘制轨迹for i, (new, old) in enumerate(zip(good_new, good_old)):a, b = new.ravel()c, d = old.ravel()mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)),color[i].tolist(), 2) # 画线,随机颜色frame = cv2.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)img = cv2.add(frame, mask)cv2.imshow('frame', img)key = cv2.waitKey(10)if key == ord('q'):break# 更新每一帧old_gray = gray.copy()p0 = good_new.reshape(-1, 1, 2)# print('p0de', p0.shape) # p0de (38, 1, 2)
cap.release()
cv2.destroyAllWindows()
11- OpenCV进行目标追踪 (OpenCV系列) (机器视觉)相关推荐
- opencv多目标追踪容器
opencv多目标追踪容器 之前做过一个多目标追踪的项目,尝试了一下opencv提供的追踪容器,个人感觉效果一般. # coding:utf-8 # @Time : 14/12/2018 17:07 ...
- 如何使用opencv进行目标追踪
日常@尊师: © Fu Xianjun. All Rights Reserved. 使用opencv目标追踪之前先要在CDM中 安装pytesseract 代码是:pip install pytess ...
- OpenCV图像处理——目标追踪
总目录 图像处理总目录←点击这里 二十四.目标追踪 24.1.多目标(手动检测)追踪 24.1.1.原理 目标检测:运行之后按下s,通过鼠标对某个目标进行检测,然后点击空格或者回车 目标追踪:open ...
- OpenCV camshift目标追踪
camshift算法是对meanshift算法的改进,首先应用meanshift,一旦meanshift收敛,它就会更新窗口的大小,还计算最佳拟合椭圆的方向,从而根据目标的位置和大小更新搜索窗口. c ...
- OpenCV meanshift目标追踪
meanshift原理:一个迭代的步骤,即先算出当前点的偏移均值,移动该点到其偏移均值,然后以此为新的起始点,继续移动,直到满足一定的条件结束. Meanshift算法:简单,迭代次数少,但无法解决目 ...
- 【Opencv】目标追踪——高斯混合模型分离算法(MOG)
文章目录 1 环境 2 效果 3 原理 4 代码 1 环境 Python 3.8.8 PyCharm 2021 opencv-python 2 效果 3 原理 视频图像中的目标检测与跟踪,是计算机 ...
- python—opencv 实时视频目标追踪
功能: 1.获取摄像头,实时显示 2.鼠标获取第一帧中的目标roi区域 3.在视频中实时对目标进行追踪. 4.两种目标追踪的方式:'meanshift','camshift' 5.保存视频 impor ...
- 用opencv实现目标追踪的学习笔记——camshift
小白的学习笔记--opencv camshift -基础:零c++基础,零opencv基础,简单C语言基础,略知数字图像处理知识 -工具:VS2015+opencv 2.4.13 -sample: E ...
- python机器识别追踪_多目标追踪器:用OpenCV实现多目标追踪(C++/Python)
原标题:多目标追踪器:用OpenCV实现多目标追踪(C++/Python) MultiTracker : Multiple Object Tracking using OpenCV (C++/Pyth ...
最新文章
- bnu 34986 Football on Table(数学+暴力)
- IPv6的利与弊—Vecloud微云
- CTFshow 信息收集 web5
- java 文件字节流_Java:文件字符流和字节流的输入和输出
- 手撕 MySQL 事务,发生了什么?
- 网页调用摄像头_【WebAR】虚拟现实来到网页——WebXR Device API第二部分
- c# automapper 使用
- MySQL日期处理-查询间隔数据
- 集成电路的设计 —— 引脚
- Kano模型在用户调研中的应用——CRM工具调研实例
- Sp_15_极限定理
- Linux 终端快捷键
- 我学炒外汇 第十三篇影响瑞士法郎的因素
- 计算机毕业设计JavaVue框架电商后台管理系统(源码+系统+mysql数据库+lw文档)
- Java学习者的25个目标
- 购买亚马逊保险前,卖家须注意的问题值得你收藏!
- C++课程实训——银行系统
- 聚合支付行业术语,你get到了吗?
- 未雨绸缪,数据分析对于企业应对经营危机非常重要
- 怎样做研究(二) 刘挺