基于YOLOv8与OpenCV实现指定直线下方目标检测
实现YOLOv8仅检测指定直线下方的目标
关键修改点
- 修正直线绘制的宽度:由于帧被resize至
(1280, 720),直线终点需使用resize后的宽度值,避免直线长度与帧不匹配。 - 变量名优化:将
x_line改为y_line,明确这是y轴方向的分割线坐标,避免混淆坐标轴。 - 目标筛选逻辑:遍历YOLO检测出的每个目标框,仅保留框体底部(
y2坐标)位于分割线下方的目标,过滤掉线上方的所有结果。
修改后的完整代码
import cv2 import torch import numpy as np from ultralytics import YOLO video_path = "rtsp://192.168.1.83/live/0/MAIN" cap = cv2.VideoCapture(video_path) model = YOLO('yolov8n.pt') # 分割线的y轴坐标(对应resize后720高度的帧) y_line = 600 resize_width, resize_height = 1280, 720 while cap.isOpened(): success, frame = cap.read() if success: # 调整帧尺寸 resized_frame = cv2.resize(frame, (resize_width, resize_height), interpolation=cv2.INTER_LINEAR) # 绘制分割直线 cv2.line(resized_frame, (0, y_line), (resize_width, y_line), (255, 0, 0), 10) # YOLOv8推理 results = model(resized_frame, conf=0.6, classes=0) # 筛选出直线下方的目标 filtered_boxes = [] for box in results[0].boxes: # 获取bbox的xyxy坐标:x1, y1, x2, y2(y2是框的底部y坐标) x1, y1, x2, y2 = box.xyxy[0].tolist() # 判断框的底部是否在直线下方 if y2 > y_line: filtered_boxes.append(box) # 将筛选后的框赋值回结果集,用于后续绘图 results[0].boxes = filtered_boxes # 绘制标注后的帧 annotated_frame = results[0].plot() # 显示结果 cv2.imshow("YOLOv8 Inference", annotated_frame) if cv2.waitKey(1) & 0xFF == ord("q"): break else: break cap.release() cv2.destroyAllWindows()
代码解释
- 帧尺寸与直线绘制:固定resize后的帧尺寸为
1280x720,绘制直线时使用该尺寸的宽度,确保直线贯穿整个帧。 - 目标筛选:通过
results[0].boxes获取所有检测框,每个框的xyxy属性包含左上角和右下角坐标,取右下角的y2值与y_line比较,仅保留符合条件的框。 - 结果更新:将筛选后的框重新赋值给
results[0].boxes,再调用plot()方法,即可仅绘制直线下方的目标框。
内容的提问来源于stack exchange,提问作者Arnav86
相关产品推荐
相关产品推荐

