news 2026/7/15 10:58:30

YOLO目标追踪代码示例:「进出双向人流统计」和「越界报警」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO目标追踪代码示例:「进出双向人流统计」和「越界报警」

本文博主再给你一个可直接落地的增强版脚本:在原有「区域人流统计」基础上,新增:

进出双向计数(进+1,出-1)
越界报警(非法闯入/离开触发)
轨迹方向判断(基于中心点穿越区域边界)
报警弹窗 + 日志保存

实现思路是:用 TrackZone 做区域过滤 + 自己维护每个ID的历史中心点 → 判断穿越方向


一、实现原理(先看这个,代码更好懂)

  1. TrackZone负责:

    • 只在指定多边形区域内追踪目标
    • 返回track_ids+boxes
  2. 方向判断逻辑

    • 记录每个track_id上一帧的中心点(x1, y1)
    • 当前帧中心点(x2, y2)
    • 判断线段是否穿过区域某条边
    • 根据穿越边的法向量判断是「进入」还是「离开」
  3. 越界报警

    • 进入/离开时触发
    • 画面红色高亮 + 控制台打印 + 日志文件

二、完整代码:进出双向统计 + 越界报警

✅ 依赖:ultralytics,opencv-python,numpy

fromultralyticsimportYOLO,solutionsimportcv2importnumpyasnpfromdatetimeimportdatetime# ======================# 1. 基础配置# ======================MODEL_PATH="yolo26n.pt"VIDEO_PATH="video.mp4"# 0=摄像头OUTPUT_PATH="output_people_counting.mp4"# 监控区域(多边形,顺时针)region_points=np.array([(200,200),(1000,200),(1000,600),(200,600)],dtype=np.int32)# ======================# 2. 全局状态# ======================id_history={}# track_id -> 上一帧中心点enter_count=0exit_count=0ALARM_LOG="alarm.log"# ======================# 3. 工具函数# ======================defpoint_in_polygon(pt,polygon):"""判断点是否在多边形内"""returncv2.pointPolygonTest(polygon,pt,False)>=0defsegment_intersects_polygon(p1,p2,polygon):""" 判断线段p1->p2是否穿过polygon任意边 返回 True + 边的法向量方向 """foriinrange(len(polygon)):a=tuple(polygon[i])b=tuple(polygon[(i+1)%len(polygon)])# 线段ab(边)与线段p1p2相交ifcv2.clipLine(a,b,p1,p2)[0]:edge_vec=np.array(b)-np.array(a)normal=np.array([-edge_vec[1],edge_vec[0]])# 法向量returnTrue,normalreturnFalse,Nonedeflog_alarm(event,track_id):timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S")line=f"[{timestamp}] ALARM:{event}| TrackID={track_id}\n"print(line.strip())withopen(ALARM_LOG,"a",encoding="utf-8")asf:f.write(line)# ======================# 4. 初始化 TrackZone# ======================trackzone=solutions.TrackZone(model=MODEL_PATH,region=region_points.tolist(),classes=[0],# 只统计人tracker="bytetrack.yaml",show=False,persist=True)# ======================# 5. 视频IO# ======================cap=cv2.VideoCapture(VIDEO_PATH)fps=int(cap.get(cv2.CAP_PROP_FPS))w=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))h=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))out=cv2.VideoWriter(OUTPUT_PATH,cv2.VideoWriter_fourcc(*"mp4v"),fps,(w,h))# ======================# 6. 主循环# ======================whilecap.isOpened():success,frame=cap.read()ifnotsuccess:breakresults=trackzone(frame)# TrackZone返回的boxes和idsboxes=results.boxes.xyxy.cpu().numpy()ids=results.boxes.id.cpu().numpy().astype(int)forbox,tidinzip(boxes,ids):x1,y1,x2,y2=map(int,box)cx,cy=(x1+x2)//2,(y1+y2)//2pt=(cx,cy)# 首次出现iftidnotinid_history:id_history[tid]=ptcontinueprev_pt=id_history[tid]id_history[tid]=pt# 判断是否穿越区域边界intersect,normal=segment_intersects_polygon(prev_pt,pt,region_points)ifintersectandnormalisnotNone:move_vec=np.array(pt)-np.array(prev_pt)direction=np.dot(move_vec,normal)ifdirection>0:enter_count+=1event="ENTER"else:exit_count-=1event="EXIT"log_alarm(event,tid)# 越界报警:红框高亮cv2.rectangle(frame,(x1,y1),(x2,y2),(0,0,255),3)cv2.putText(frame,f"ALARM:{event}",(x1,y1-10),cv2.FONT_HERSHEY_SIMPLEX,0.8,(0,0,255),2)else:# 正常追踪框cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)cv2.putText(frame,f"ID:{tid}",(x1,y1-10),cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,255,0),2)# 绘制区域cv2.polylines(frame,[region_points],True,(255,0,0),2)# 统计信息cv2.putText(frame,f"In:{enter_count}Out:{exit_count}Total:{enter_count+exit_count}",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1.2,(0,255,255),2)out.write(frame)cv2.imshow("People Counting & Intrusion Alarm",frame)ifcv2.waitKey(1)&0xFF==ord("q"):break# ======================# 7. 清理# ======================cap.release()out.release()cv2.destroyAllWindows()print("✅ 处理完成")print(f"进入人数:{enter_count}")print(f"离开人数:{abs(exit_count)}")print(f"当前在场人数:{enter_count+exit_count}")print(f"报警日志:{ALARM_LOG}")

三、运行效果说明

功能表现
进入区域绿色框 +In +1
离开区域绿色框 +Out -1
越界瞬间红色高亮框 + ALARM提示
日志alarm.log自动记录
输出视频带统计面板 + 报警标记

四、常见优化建议

场景优化
斜向进出误判改用射线法 + 方向角度阈值
多人密集提高track_buffer,降低match_thresh
夜间误报加亮度判断 / 红外摄像头
只想统计“进入”删除 EXIT 分支即可
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 10:57:39

数字电路设计:从锁存器到触发器的避坑指南

1. 锁存器与触发器的本质区别 刚入行数字电路设计时,我最常犯的错误就是分不清锁存器(Latch)和触发器(Flip-Flop)。直到某次项目出现诡异的时序问题,调试三天才发现是代码里意外生成的锁存器在作祟。这两种…

作者头像 李华
网站建设 2026/7/15 10:57:08

从帧结构到应用场景:深入解析CAN FD如何重塑车载网络通信

1. CAN FD帧结构的革新设计CAN FD作为传统CAN协议的升级版,在帧结构上做了多项关键改进。这些改进不是简单的修修补补,而是针对车载网络日益增长的数据需求所做的系统性优化。我们先来看最核心的四个技术亮点:BRS(Bit Rate Switch…

作者头像 李华
网站建设 2026/7/15 10:56:58

终极免费方案:RDP Wrapper 解锁 Windows 家庭版远程桌面完整指南

终极免费方案:RDP Wrapper 解锁 Windows 家庭版远程桌面完整指南 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 你是否因 Windows 家庭版无法使用远程桌面而烦恼?RDP Wrapper Library 提供…

作者头像 李华
网站建设 2026/7/15 10:54:16

OBS多平台直播插件:一键实现多平台同步直播的完整指南

OBS多平台直播插件:一键实现多平台同步直播的完整指南 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 你是否曾经为了在不同直播平台同步开播而感到手忙脚乱?每次…

作者头像 李华
网站建设 2026/7/15 10:53:08

C++实现自动驾驶优化算法:从梯度下降到LM法的工程实践

1. 项目概述:从理论到代码的求解器实现 在自动驾驶的感知、定位、规划与控制等核心模块中,最优化问题无处不在。无论是通过传感器数据拟合车辆的运动轨迹,还是规划一条平滑、安全、高效的行驶路径,其背后往往都归结为一个数学上的…

作者头像 李华