在计算机视觉的众多应用场景中,对特定区域的目标进行检测、跟踪与计数是一个常见且重要的需求。无论是在智慧交通中统计通过特定路口的车辆数量,还是在零售分析中追踪进入特定区域的顾客行为,这一功能都发挥着不可或缺的作用。
随着深度学习技术的发展,目标检测算法不断迭代升级。YOLO(You Only Look Once)系列作为目标检测领域的翘楚,以其高效、实时的特性受到广泛关注和应用。YOLOv11(Ultralytics)在检测性能和易用性方面再一次取得了显著提升。本文将给出基础教程,读者可自选区域并读取视频进行测试,本教程同样Ultralytics / YOLOv11 / YOLOv8通用,视频及摄像头均可使用。
主要使用ultralytics的solutions.ObjectCounter中count方法(不同版本函数名称不一样,但是YOLOv11往后都是count函数),具体代码如下,本文代码需搭配ultralytics8.3.20版本 下载 。
import cv2
from ultralytics import YOLO, solutions
cap = cv2.VideoCapture("dog.mp4")
assert cap.isOpened(), "读取视频异常"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
region_points = [(20, 400), (700, 400), (700, 360), (20, 360)]
video_writer = cv2.VideoWriter("output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
counter = solutions.ObjectCounter(
model = "yolo11n.pt",
region=region_points,
show_in=True,
show_out=True
)
while cap.isOpened():
success, im0 = cap.read()
if not success:
print("视频处理完成")
break
cv2.putText(im0, f"Total:{counter.in_count + counter.out_count}", (80, 80), cv2.FONT_HERSHEY_SIMPLEX, 1,
(255, 0, 0), 2)
im0 = counter.count(im0)
video_writer.write(im0)
cap.release()
video_writer.release()
cv2.destroyAllWindows()
使用时需要修改region_point为自选区域,可以多个点组合成多边形,也可以两个点连成一条直线,系统会自动识别。实测ultralytics8.2.0版本多边形效果最好,可以实现检测时修改自选框位置,需要代码可以 下载 ,相应的函数也需要对应修改。
import cv2
from ultralytics import YOLO, solutions
model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("dog.mp4")
assert cap.isOpened(), "读取视频异常"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
region_points = [(20, 400), (700, 400), (700, 360), (20, 360)]
video_writer = cv2.VideoWriter("output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
counter = solutions.ObjectCounter(
view_img=True,
reg_pts=region_points,
names=model.names,
draw_tracks=True,
line_thickness=2,
view_in_counts=True,
view_out_counts=True,
)
while cap.isOpened():
success, im0 = cap.read()
if not success:
print("视频处理完成")
break
tracks = model.track(im0, persist=True, show=False)
cv2.putText(im0, f"Total:{counter.in_counts + counter.out_counts}", (80, 80), cv2.FONT_HERSHEY_SIMPLEX, 1,
(255, 0, 0), 2)
im0 = counter.start_counting(im0, tracks)
video_writer.write(im0)
cap.release()
video_writer.release()
cv2.destroyAllWindows()
效果展示如下,目标经过自选框则计入in,离开自选框则计入out,总数在左侧显示,跟踪轨迹显示为线条(默认YOLOv11n效果一般,自训练模型效果较好)。
运行完代码后检测结果会保存为视频,本文给出代码为默认的opencv代码,如需较为完整的使用pyqt5界面写出的视频或摄像头检测代码,可私聊获取,有其它需求欢迎私聊定制,如有大佬有好的想法也欢迎一起讨论。