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

YOLOv8+OpenCV黄红区域目标检测判断逻辑异常问题排查

问题排查与解决方案

核心问题分析

  • 坐标偏移错误:你对帧做了裁剪cropped_frame = resized_frame[x_line1:, y_line:],YOLO返回的检测框坐标是基于这个裁剪后图像的局部坐标系,而非原resized_frame的全局坐标系。直接用box[1](裁剪图的y坐标)和原图像的x_line2(全局y坐标)比较,数值永远不匹配——裁剪图的y=0对应原图的y=x_line1=200,所以实际全局y坐标应该是box[1] + x_line1。
  • 变量命名混淆:x_line1、x_line2实际是水平线的y轴坐标(OpenCV中水平线的y值固定),命名错误容易导致逻辑判断时的坐标混淆。

修正后的代码

import cv2
import torch
import numpy as np
from ultralytics import YOLO


if torch.cuda.is_available():
    device = torch.device('cuda')
    print('Using device:', torch.cuda.get_device_name(torch.cuda.current_device()))
else:
    device = torch.device('cpu')
    print('Using device:', device)

video_path ="rtsp://192.168.1.83/live/0/MAIN"

cap = cv2.VideoCapture(video_path)

model = YOLO('yolov8n.pt')

# 修正变量命名:明确水平线对应y轴坐标,竖直线对应x轴坐标
y_line1 = 200  # 第一条水平线(黄区上边界)
y_line2 = 500  # 第二条水平线(红区上边界)
x_vertical_line = 350  # 竖直线的x坐标
frame_count = 0

while cap.isOpened():
    success, frame = cap.read()
    width = int(cap.get(3))
    height = int(cap.get(4))

    if success:
        resized_frame = cv2.resize(frame, (1280, 720), interpolation=cv2.INTER_LINEAR)
        # 绘制线条,使用修正后的变量名
        cv2.line(resized_frame, (0, y_line1), (1280, y_line1), (255, 0, 0), 10)
        cv2.line(resized_frame, (0, y_line2), (1280, y_line2), (255, 0, 0), 10)
        cv2.line(resized_frame, (x_vertical_line, 0), (x_vertical_line, 720), (255, 0, 0), 10)

        # 裁剪帧:y_line1以下,x_vertical_line右侧的区域
        cropped_frame = resized_frame[y_line1:, x_vertical_line:]

        results = model(cropped_frame, conf=0.1)

        annotated_cropped_frame = results[0].plot()
        annotated_frame = resized_frame.copy()
        annotated_frame[y_line1:, x_vertical_line:] = annotated_cropped_frame

        cv2.imshow("YOLOv8 Inference", annotated_frame)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break
        
        num_objects = len(results[0].boxes)
        if num_objects >= 9:
            cv2.imwrite("frame_{}.jpg".format(frame_count), annotated_frame)
            print(f"There are {num_objects} people in the frame")
        
        boxes = results[0].boxes.data
        for box in boxes:
            # 计算目标在原resized_frame中的全局y坐标:裁剪图的y坐标 + 裁剪偏移量y_line1
            global_y = box[1] + y_line1
            if global_y > y_line2:
                print("Object is in red zone")
            elif global_y > y_line1:
                print("Object is in yellow zone")
            else:
                # 可选:处理目标在第一条线以上的情况
                print("Object is in zone above first line")

        frame_count += 1
    else:
        break

cap.release()
cv2.destroyAllWindows()

关键修正点

  1. 变量命名优化:将x_line1/x_line2改为y_line1/y_line2,y_line改为x_vertical_line,明确坐标含义,避免混淆。
  2. 坐标偏移修正:计算目标在全局坐标系中的y坐标global_y = box[1] + y_line1,确保和绘制的水平线坐标在同一系统下比较。
  3. 完善判断逻辑:补充了目标在第一条线以上的情况,让逻辑更完整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:44:59