You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用YOLOv5检测网络摄像头特定区域内的目标

完全可以基于YOLOv5实现你要的「网络摄像头画面下,以model1输出边界框为model2专属检测区域」的两级检测逻辑,不需要改动模型本身结构,仅需在帧推理流程中增加区域裁剪、坐标映射环节即可。

核心实现逻辑
  • 逐帧读取网络摄像头画面,先将完整帧输入model1推理,拿到原帧尺度下model1输出的所有检测框坐标(x1,y1,x2,y2,左上角+右下角绝对像素值)、置信度、类别信息。
  • 遍历model1输出的符合筛选要求的边界框,按坐标从原帧中裁剪出对应ROI(感兴趣区域)子图,裁剪前要做坐标边界截断,避免坐标超出画面宽高引发报错。
  • 将裁剪得到的ROI子图输入model2推理,此时model2输出的检测框坐标是相对于ROI子图左上角的相对值,需要做坐标偏移转换:所有检测框的x坐标累加对应ROI的左上角x1值、y坐标累加对应ROI的左上角y1值,即可得到原帧尺度下的绝对坐标。
  • 将model1的检测结果、坐标转换后的model2检测结果统一绘制到原帧上,可用不同颜色区分两个模型的检测框,最终输出到显示窗口即可。
可直接参考的实现代码
import torch
import cv2

# 加载本地训练好的两个YOLOv5模型
model1 = torch.hub.load('ultralytics/yolov5', 'custom', path='model1.pt')
model2 = torch.hub.load('ultralytics/yolov5', 'custom', path='model2.pt')
# 按需设置两个模型的置信度阈值
model1.conf = 0.5
model2.conf = 0.4

# 接入视频流,0为本地默认摄像头,替换为rtsp地址即可接入网络摄像头
cap = cv2.VideoCapture(0)
frame_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # 第一级:model1检测全帧
    res1 = model1(frame)
    dets1 = res1.xyxy[0].cpu().numpy()

    dets2 = []
    # 遍历model1检测框,裁剪ROI送入model2
    for det in dets1:
        x1, y1, x2, y2, conf1, cls1 = det
        # 坐标越界截断
        x1, y1 = max(0, int(x1)), max(0, int(y1))
        x2, y2 = min(frame_w, int(x2)), min(frame_h, int(y2))
        # 裁剪ROI区域
        roi = frame[y1:y2, x1:x2]
        if roi.size == 0:
            continue
        # 第二级:model2检测ROI区域
        res2 = model2(roi)
        roi_dets = res2.xyxy[0].cpu().numpy()
        # 坐标转换:将ROI内相对坐标映射回原帧绝对坐标
        for r_det in roi_dets:
            rx1, ry1, rx2, ry2, conf2, cls2 = r_det
            dets2.append([
                x1 + rx1, y1 + ry1,
                x1 + rx2, y1 + ry2,
                conf2, cls2
            ])

    # 绘制结果:model1检测框用蓝色,model2检测框用红色
    for det in dets1:
        x1, y1, x2, y2, conf, cls = det
        x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
        cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2)
        cv2.putText(frame, f"{model1.names[int(cls)]} {conf:.2f}", (x1, y1-10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2)
    
    for det in dets2:
        x1, y1, x2, y2, conf, cls = det
        x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
        cv2.putText(frame, f"{model2.names[int(cls)]} {conf:.2f}", (x1, y1-10),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

    cv2.imshow('two-stage detection', frame)
    # 按q键退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
优化提示
  • 如果model2仅需要处理model1输出的特定类别目标,可以在遍历model1检测结果时增加类别判断,仅裁剪符合类别要求的框区域,减少无效计算。
  • 如果对推理速度要求高,可以把同帧下所有裁剪出的ROI攒成一个batch输入model2做批量推理,相比逐个ROI推理能明显降低延迟。
  • 坐标转换时不要遗漏ROI左上角的偏移值,否则model2的检测框会错位到画面左上角。

效果参考图

内容的提问来源于stack exchange,提问作者andy wong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:45:35