本文目录导读:

我来介绍几个使用OpenCV进行目标跟踪的Python案例。
基本目标跟踪(使用预训练跟踪器)
import cv2
import numpy as np
def basic_object_tracking():
"""
基本目标跟踪示例
"""
# 初始化视频捕获
cap = cv2.VideoCapture(0) # 0表示默认摄像头
# 读取第一帧
ret, frame = cap.read()
if not ret:
print("无法读取视频")
return
# 选择跟踪区域
bbox = cv2.selectROI("选择跟踪目标", frame, False)
cv2.destroyWindow("选择跟踪目标")
# 创建跟踪器(多种可选)
# tracker = cv2.TrackerKCF_create() # KCF跟踪器
# tracker = cv2.TrackerCSRT_create() # CSRT跟踪器
# tracker = cv2.TrackerMIL_create() # MIL跟踪器
tracker = cv2.TrackerKCF_create()
# 初始化跟踪器
tracker.init(frame, bbox)
while True:
ret, frame = cap.read()
if not ret:
break
# 更新跟踪器
success, bbox = tracker.update(frame)
# 绘制跟踪结果
if success:
x, y, w, h = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, "Tracking", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
else:
cv2.putText(frame, "Lost", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("目标跟踪", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
基于颜色的目标跟踪
import cv2
import numpy as np
def color_based_tracking():
"""
基于颜色的目标跟踪
"""
cap = cv2.VideoCapture(0)
# 读取第一帧并选择目标
ret, frame = cap.read()
if not ret:
return
# 选择ROI
bbox = cv2.selectROI("选择目标", frame, False)
roi = frame[int(bbox[1]):int(bbox[1]+bbox[3]),
int(bbox[0]):int(bbox[0]+bbox[2])]
# 计算目标颜色直方图
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0, 180])
cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# 设置追踪窗口初始位置
track_window = (int(bbox[0]), int(bbox[1]),
int(bbox[2]), int(bbox[3]))
# 设置终止条件
term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
while True:
ret, frame = cap.read()
if not ret:
break
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
# 使用MeanShift进行跟踪
ret, track_window = cv2.meanShift(dst, track_window, term_crit)
# 绘制跟踪结果
x, y, w, h = track_window
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow("颜色跟踪", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
光流法目标跟踪
import cv2
import numpy as np
def optical_flow_tracking():
"""
基于光流法的目标跟踪
"""
cap = cv2.VideoCapture(0)
# 读取第一帧
ret, old_frame = cap.read()
if not ret:
return
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 选择跟踪点
points = cv2.goodFeaturesToTrack(old_gray, maxCorners=100,
qualityLevel=0.3, minDistance=7)
# 光流参数
lk_params = dict(winSize=(15, 15),
maxLevel=2,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# 创建掩码用于绘制轨迹
mask = np.zeros_like(old_frame)
while True:
ret, frame = cap.read()
if not ret:
break
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 计算光流
new_points, status, error = cv2.calcOpticalFlowPyrLK(
old_gray, frame_gray, points, None, **lk_params)
# 选择好的点
good_new = new_points[status == 1]
good_old = points[status == 1]
# 绘制轨迹
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)),
(0, 255, 0), 2)
frame = cv2.circle(frame, (int(a), int(b)), 5, (0, 0, 255), -1)
# 合并帧和轨迹
img = cv2.add(frame, mask)
# 更新旧帧和点
old_gray = frame_gray.copy()
points = good_new.reshape(-1, 1, 2)
cv2.imshow("光流跟踪", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 如果点太少,重新检测
if len(points) < 10:
points = cv2.goodFeaturesToTrack(old_gray, maxCorners=100,
qualityLevel=0.3, minDistance=7)
cap.release()
cv2.destroyAllWindows()
多目标跟踪
import cv2
import numpy as np
def multi_object_tracking():
"""
多目标跟踪示例
"""
cap = cv2.VideoCapture(0)
# 读取第一帧
ret, frame = cap.read()
if not ret:
return
# 创建多目标跟踪器
tracker = cv2.MultiTracker_create()
# 选择多个跟踪目标(选择后按空格确认,按ESC取消)
bboxes = []
colors = [(0, 255, 0), (255, 0, 0), (0, 0, 255)] # 不同目标的颜色
while True:
# 选择ROI
bbox = cv2.selectROI("选择目标 (按空格确认, ESC结束)", frame, False)
if bbox == (0, 0, 0, 0): # 按ESC退出
break
bboxes.append(bbox)
cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])),
(int(bbox[0]+bbox[2]), int(bbox[1]+bbox[3])),
colors[len(bboxes)-1], 2)
# 使用KCF跟踪器
tracker.add(cv2.TrackerKCF_create(), frame, bbox)
print(f"已选择 {len(bboxes)} 个目标")
cv2.destroyWindow("选择目标 (按空格确认, ESC结束)")
while True:
ret, frame = cap.read()
if not ret:
break
# 更新所有跟踪器
success, boxes = tracker.update(frame)
# 绘制所有跟踪结果
for i, box in enumerate(boxes):
x, y, w, h = [int(v) for v in box]
cv2.rectangle(frame, (x, y), (x+w, y+h),
colors[i % len(colors)], 2)
cv2.putText(frame, f"Object {i+1}", (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, colors[i % len(colors)], 2)
cv2.imshow("多目标跟踪", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
移动物体检测与跟踪
import cv2
import numpy as np
def motion_detection_tracking():
"""
移动物体检测与跟踪
"""
cap = cv2.VideoCapture(0)
# 背景减法器
backSub = cv2.createBackgroundSubtractorMOG2()
# 创建KCF跟踪器用于持续跟踪
tracker = None
tracking = False
while True:
ret, frame = cap.read()
if not ret:
break
# 应用背景减法
fgMask = backSub.apply(frame)
# 查找轮廓
contours, _ = cv2.findContours(fgMask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# 处理检测到的移动物体
for contour in contours:
area = cv2.contourArea(contour)
if area > 1000: # 过滤小面积噪声
x, y, w, h = cv2.boundingRect(contour)
if not tracking:
# 开始跟踪新的物体
tracker = cv2.TrackerCSRT_create()
tracker.init(frame, (x, y, w, h))
tracking = True
print("开始跟踪")
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 如果已经在跟踪,更新跟踪器
if tracking and tracker is not None:
success, bbox = tracker.update(frame)
if success:
x, y, w, h = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 3)
cv2.putText(frame, "Tracking", (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
else:
tracking = False
print("跟踪丢失")
# 显示结果
cv2.imshow("原始帧", frame)
cv2.imshow("前景掩码", fgMask)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
使用预训练YOLO进行目标检测和跟踪
import cv2
import numpy as np
def yolo_with_tracking():
"""
YOLO检测 + 跟踪
"""
# 加载YOLO
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
# 加载类别名称
with open("coco.names", "r") as f:
classes = [line.strip() for line in f.readlines()]
# 获取输出层
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
cap = cv2.VideoCapture(0)
# 存储跟踪器
trackers = []
tracked_objects = []
while True:
ret, frame = cap.read()
if not ret:
break
height, width, channels = frame.shape
# YOLO检测(每30帧检测一次)
if cv2.waitKey(1) % 30 == 0:
# 准备输入
blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416),
(0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
# 处理检测结果
boxes = []
confidences = []
class_ids = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
# 应用非极大值抑制
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
# 为检测到的目标创建跟踪器
trackers = []
tracked_objects = []
if len(indexes) > 0:
for i in indexes.flatten():
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
# 创建跟踪器
tracker = cv2.TrackerCSRT_create()
tracker.init(frame, (x, y, w, h))
trackers.append(tracker)
tracked_objects.append(label)
# 更新所有跟踪器
for i, tracker in enumerate(trackers):
success, bbox = tracker.update(frame)
if success:
x, y, w, h = [int(v) for v in bbox]
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.putText(frame, tracked_objects[i], (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow("YOLO + 跟踪", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
常用跟踪器对比
def compare_trackers():
"""
比较不同跟踪器的性能
"""
trackers = {
'BOOSTING': cv2.TrackerBoosting_create(),
'MIL': cv2.TrackerMIL_create(),
'KCF': cv2.TrackerKCF_create(),
'TLD': cv2.TrackerTLD_create(),
'MEDIANFLOW': cv2.TrackerMedianFlow_create(),
'CSRT': cv2.TrackerCSRT_create()
}
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
# 选择跟踪目标
bbox = cv2.selectROI("选择目标", frame, False)
cv2.destroyWindow("选择目标")
# 初始化所有跟踪器
active_trackers = {}
for name, tracker in trackers.items():
tracker.init(frame, bbox)
active_trackers[name] = tracker
# 显示跟踪结果对比
while True:
ret, frame = cap.read()
if not ret:
break
results_frame = frame.copy()
for name, tracker in active_trackers.items():
success, bbox = tracker.update(frame)
if success:
x, y, w, h = [int(v) for v in bbox]
cv2.rectangle(results_frame, (x, y), (x+w, y+h),
(0, 255, 0), 2)
cv2.putText(results_frame, f"{name}: OK", (x, y-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
else:
cv2.putText(results_frame, f"{name}: Lost",
(50, 50 + list(active_trackers.keys()).index(name)*30),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("跟踪器对比", results_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
使用建议
-
选择合适的跟踪器:
- CSRT: 准确度高,适合复杂场景
- KCF: 速度快,适合实时应用
- MIL: 鲁棒性好,但速度较慢
-
性能优化:
- 降低分辨率
- 使用灰度图像
- 限制跟踪区域
-
鲁棒性提升:
- 结合多种跟踪方法
- 定期重新检测
- 使用光流法辅助
这些案例涵盖了OpenCV中常见的跟踪方法,可以根据具体需求选择和调整。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播