赞
踩
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算法, 比较经典)
随机颜色 数组生成:
参考资料: 目标追踪综述 - 知乎
OpenCV上有八种不同的目标追踪算法:
OpenCV目标跟踪算法的使用大概可以分为以下几个步骤:
创建MultiTracker对象.
读取视频或摄像头数据.
框选ROI区域
给MultiTracker对象添加实际的追踪算法.
对每一帧进行进行目标追踪.
下面是一个使用例子:
- import cv2
- import numpy as np
-
- cap = 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:
- break
- gray = 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'):
- break
-
- cap.release()
- cv2.destroyAllWindows()

目标识别?
把图片变成tensor: blob = cv2.dnn.blobFromImage(img)
把图片给到网络预测: net.setInput(blob)
预测: net.forward()
- import cv2
- import numpy as np
-
- img = 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
光流,顾名思义,光的流动。比如人眼感受到的夜空中划过的流星。在计算机视觉中,定义图像中对象的移动,这个移动可以是相机移动或者物体移动引起的。具体是指,视频图像的一帧中的代表同一对象(物体)像素点移动到下一帧的移动量,使用二维向量表示.
根据是否选取图像稀疏点进行光流估计,可以将光流估计分为稀疏光流和稠密光流.
OpenCV中提供了光流估计的接口,包括 稀疏光流估计算法 cv2.calcOpticalFlowPyrLK(),和 稠密光流估计 cv2.calcOpticalFlowFarneback()。其中稀疏光流估计算法为Lucas-Kanade算法,该算法为1981年由Lucas和Kanade两位科学家提出的,最为经典也较容易理解的算法.
为了将光流估计进行建模,Lucas-Kanade做了三个重要的假设:
亮度恒定:同一点随着时间的变化,其亮度不会发生改变。
小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。
空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解。
cv2.calcOpticalFlowPyrLK(): 参数:
prevImage 前一帧图像
nextImage 当前帧图像
prevPts 待跟踪的特征点向量
winSize 搜索窗口的大小
maxLevel 最大的金字塔层数
返回值:
nextPts 输出跟踪特征点向量
status 特征点是否找到,找到的状态为1,未找到的状态为0
- import numpy as np
- import cv2
-
- cap = 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:
- break
- gray = 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()

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。