求助:为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
相关产品推荐
相关产品推荐

