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

求助:为YOLOv8球面图像目标检测实现滑动窗口方案

球面图像YOLOv8目标检测的滑动窗口优化方案

以下是针对球面图像优化后的滑动窗口目标检测代码,解决了原代码中坐标映射错误、边缘区域未覆盖、重复保存等问题:

import cv2
import numpy as np
from ultralytics import YOLO
import matplotlib.pyplot as plt

# 加载自定义YOLOv8模型
custom_yolo_model = YOLO('D:/yolo_objectdetection/runs/detect/train26/weights/best.pt')

# 定义滑动窗口尺寸(根据目标大小调整)
window_size = (1000, 1000)
# 定义窗口步长(控制窗口重叠程度,重叠率越高漏检率越低,但计算量越大)
stride = (500, 500)

# 加载球面输入图像
image = cv2.imread('D:/yolo_objectdetection/newdata/images/train/Track_C-Sphere-66.jpg')
# 转换图像色彩空间(OpenCV默认BGR,Matplotlib用RGB)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
height, width, _ = image.shape

# 存储所有检测结果(原图坐标系下的框)
detected_boxes = []

# 滑动窗口遍历图像:处理完整窗口区域
for y in range(0, height - window_size[1] + 1, stride[1]):
    for x in range(0, width - window_size[0] + 1, stride[0]):
        # 提取当前窗口
        window = image[y:y + window_size[1], x:x + window_size[0]]
        # 运行检测,关闭自动保存,后续统一处理
        results = custom_yolo_model.predict(window, show=False, save=False, conf=0.7, iou=0.9)
        
        # 转换窗口内的检测坐标到原图坐标系
        for box in results[0].boxes:
            class_id = results[0].names[box.cls[0].item()]
            # 窗口内的坐标:x1,y1,x2,y2
            win_cords = box.xyxy[0].tolist()
            # 映射到原图坐标
            original_cords = [
                win_cords[0] + x,
                win_cords[1] + y,
                win_cords[2] + x,
                win_cords[3] + y
            ]
            original_cords = [round(coord) for coord in original_cords]
            conf = round(box.conf[0].item(), 2)
            
            detected_boxes.append({
                'class': class_id,
                'coords': original_cords,
                'confidence': conf
            })

# 处理右侧剩余边缘区域
remaining_width = width % stride[0]
if remaining_width > 0:
    x = width - window_size[0]
    for y in range(0, height - window_size[1] + 1, stride[1]):
        window = image[y:y + window_size[1], x:x + window_size[0]]
        results = custom_yolo_model.predict(window, show=False, save=False, conf=0.7, iou=0.9)
        for box in results[0].boxes:
            class_id = results[0].names[box.cls[0].item()]
            win_cords = box.xyxy[0].tolist()
            original_cords = [win_cords[0]+x, win_cords[1]+y, win_cords[2]+x, win_cords[3]+y]
            original_cords = [round(coord) for coord in original_cords]
            conf = round(box.conf[0].item(), 2)
            detected_boxes.append({'class': class_id, 'coords': original_cords, 'confidence': conf})

# 处理底部剩余边缘区域
remaining_height = height % stride[1]
if remaining_height > 0:
    y = height - window_size[1]
    for x in range(0, width - window_size[0] + 1, stride[0]):
        window = image[y:y + window_size[1], x:x + window_size[0]]
        results = custom_yolo_model.predict(window, show=False, save=False, conf=0.7, iou=0.9)
        for box in results[0].boxes:
            class_id = results[0].names[box.cls[0].item()]
            win_cords = box.xyxy[0].tolist()
            original_cords = [win_cords[0]+x, win_cords[1]+y, win_cords[2]+x, win_cords[3]+y]
            original_cords = [round(coord) for coord in original_cords]
            conf = round(box.conf[0].item(), 2)
            detected_boxes.append({'class': class_id, 'coords': original_cords, 'confidence': conf})

# 处理右下角剩余区域
if remaining_width > 0 and remaining_height > 0:
    x = width - window_size[0]
    y = height - window_size[1]
    window = image[y:y + window_size[1], x:x + window_size[0]]
    results = custom_yolo_model.predict(window, show=False, save=False, conf=0.7, iou=0.9)
    for box in results[0].boxes:
        class_id = results[0].names[box.cls[0].item()]
        win_cords = box.xyxy[0].tolist()
        original_cords = [win_cords[0]+x, win_cords[1]+y, win_cords[2]+x, win_cords[3]+y]
        original_cords = [round(coord) for coord in original_cords]
        conf = round(box.conf[0].item(), 2)
        detected_boxes.append({'class': class_id, 'coords': original_cords, 'confidence': conf})

# 绘制所有检测框到原图
for obj in detected_boxes:
    cords = obj['coords']
    class_id = obj['class']
    conf = obj['confidence']
    # 画矩形框
    cv2.rectangle(image_rgb, (cords[0], cords[1]), (cords[2], cords[3]), color=(255, 0, 255), thickness=2)
    # 写类别和置信度
    text = f"{class_id}: {conf}"
    cv2.putText(image_rgb, text, (cords[0], cords[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 255), 1, cv2.LINE_AA)
    print(f"类别: {class_id}, 坐标: {cords}, 置信度: {conf}")

# 显示结果图像
plt.figure(figsize=(12,8))
plt.imshow(image_rgb)
plt.axis('off')
plt.show()

# 可选:保存结果图像
cv2.imwrite('D:/yolo_objectdetection/sphere_detection_result.jpg', cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR))

关键改进说明

  • 坐标映射修正:将窗口内检测到的目标坐标转换为原图坐标系,避免检测框位置偏移
  • 边缘区域覆盖:补充处理图像右侧、底部及右下角的剩余区域,避免漏检边缘目标
  • 结果统一处理:关闭每个窗口的自动保存,改为最后统一绘制和保存结果,避免生成大量冗余文件
  • 色彩空间适配:统一处理OpenCV与Matplotlib的色彩空间差异,保证显示结果正确
  • 球面图像适配提示:如果球面图像存在畸变,可在提取窗口前先对图像进行畸变校正(如使用OpenCV的undistort函数),再进行滑动窗口检测,能进一步提升检测精度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:35:56