尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

如何用 supervision 的 InferenceSlicer 检测高分辨率图片中的小目标

如何用 supervision 的 InferenceSlicer 检测高分辨率图片中的小目标 如何用 supervision 的 InferenceSlicer 检测高分辨率图片中的小目标【免费下载链接】supervisionWe write your reusable computer vision tools. 项目地址: https://gitcode.com/GitHub_Trending/su/supervision高分辨率图片里的小目标像素占比很小把整图直接丢给检测模型时经常被漏掉。supervision 的sv.InferenceSlicer用切片推理解决这个问题把图片切成带重叠的小块通过你提供的 callback 逐块跑模型再把各块结果平移回整图坐标系并按 NMS 合并。本文按基线对比 → 切片推理 → 结果验证的顺序走一遍完整流程适用前提Python 3.10 环境检测模型可以是 RF-DETR、Inference、Ultralytics 或 Transformers官方指南对四种后端各给出了示例下文以 RF-DETR 作为主路径。准备条件安装 supervision 本体与主路径用到的模型依赖pip install supervision pip install pillow rfdetrsupervision 要求 Python 3.10见 README。示例代码用 OpenCV 读图如果环境里没有按 FAQ 的说明安装pip install opencv-python # 或无显示环境时 pip install opencv-python-headless准备一张包含小目标的高分辨率图片。下文代码中的SOURCE_IMAGE_PATH是源文档示例使用的占位符替换成你的图片本地路径即可后面的代码块用法相同。先跑一遍整图基线切片推理的价值需要用基线来对照。先把整图直接过一遍模型把结果转成sv.Detections并标注出来——这一步能直观暴露模型在原始分辨率下漏掉了多少小目标RF-DETR 版本取自 detect_small_objects 指南import cv2 import supervision as sv from rfdetr import RFDETRMedium model RFDETRMedium() image cv2.imread(SOURCE_IMAGE_PATH) detections model.predict(image[:, :, ::-1]) box_annotator sv.BoxAnnotator() label_annotator sv.LabelAnnotator() annotated_image box_annotator.annotate( sceneimage, detectionsdetections, ) annotated_image label_annotator.annotate( sceneannotated_image, detectionsdetections, )annotated_image就是基线结果。保存它稍后和切片推理的标注图放在一起对比。如果用的是 UltralyticsYOLOsv.Detections.from_ultralytics或 Inferenceget_modelsv.Detections.from_inference等后端指南中对应 Tab 的代码结构完全一致只是模型加载和结果转换部分不同。用 InferenceSlicer 做切片推理InferenceSlicer的接入方式是一个 callback 函数它接收单个切片NumPy 数组返回sv.Detections。slicer 负责切图、调用 callback、把切片内坐标平移到整图坐标最后合并所有结果并做重叠过滤。因此任何能产出sv.Detections的模型都能接入import cv2 import numpy as np import supervision as sv from rfdetr import RFDETRMedium model RFDETRMedium() image cv2.imread(SOURCE_IMAGE_PATH) def callback(image_slice: np.ndarray) - sv.Detections: return model.predict(image_slice[:, :, ::-1]) slicer sv.InferenceSlicer(callbackcallback) detections slicer(image) box_annotator sv.BoxAnnotator() label_annotator sv.LabelAnnotator() annotated_image box_annotator.annotate( sceneimage, detectionsdetections) annotated_image label_annotator.annotate( sceneannotated_image, detectionsdetections)callback内部必须只对传入的image_slice做推理不要用闭包里的整图image这一点在下文常见问题里再强调。影响切片行为的参数以下参数均定义在sv.InferenceSlicer上API 文档与源码参数默认值用途callback必填对每个切片执行推理的函数slice_wh640每个切片的(宽, 高)int 时宽高相同overlap_wh100切片之间的重叠量单位是像素不是百分比overlap_filterNON_MAX_SUPPRESSION合并重叠检测的策略可选NON_MAX_MERGE或NONEiou_threshold0.5重叠过滤NMS/NMM使用的 IOU 阈值overlap_metricIOU计算重叠的度量可选IOSthread_workers1并发推理切片的线程数batch_size1每次 callback 传入的切片数compact_masksFalse分割场景下把稠密掩码转为 RLE 紧凑格式降低高分辨率图多目标时的内存占用overlap_wh的取舍在指南 FAQ 里有明确说明默认100像素当目标大小接近切片尺寸、或经常出现在切片边界上时调大把速度看得更重时调小。约束条件是overlap_wh两个维度都必须小于slice_wh否则构造时抛ValueError。关于并行文档给出两条明确规则GPU 模型建议batch_size 1且thread_workers1——单个批量前向比多线程抢占同一 CUDA 设备更快也避免峰值显存被thread_workers * batch_size放大。注意batch_size 1时 callback 契约变为list[np.ndarray] - list[Detections]返回列表长度必须与传入切片数一致否则抛ValueError两种契约不可互换。如果首个切片返回的是旋转框OBB剩余切片会自动退回串行处理并打印SupervisionWarnings警告因为许多 OBB 推理后端不是线程安全的。验证结果文档给出的验证方式是视觉对比加数量检查运行print(len(detections))得到切片推理的总检测数并与基线的数量对照保存 slicer 版本的annotated_image与基线标注图并排查看重点看小目标密集区域——指南的示例展示中基线漏掉的小目标在切片推理下被检出FAQ 对这一效果的表述是dramatically improves recall for tiny targets。这是定性结论文档没有给出固定数值门槛是否够用以你的场景标注图为准。如果运行时看到警告 Detections returned by the callback have coordinates outside the slice bounds...说明 callback 返回的坐标超出了切片范围最常见原因是 callback 对整图做了推理而不是对传入的切片——按警告提示检查 callback 是否使用了image_slice。可选分支图片大到无法整图加载当输入是多 GB 的 GeoTIFF例如无人机正射影像时InferenceSlicer可以直接接收打开的rasterio数据集按窗口逐个读取切片避免把整幅栅格读进内存。这是 inference_slicer 文档给出的用法pip install supervision[geotiff]import numpy as np import rasterio import supervision as sv def callback(tile: np.ndarray) - sv.Detections: h, w tile.shape[:2] return sv.Detections( xyxynp.array([[w * 0.25, h * 0.25, w * 0.75, h * 0.75]], dtypefloat), confidencenp.array([0.9]), class_idnp.array([0]), ) slicer sv.InferenceSlicer( callbackcallback, slice_wh(256, 256), overlap_wh(64, 64), overlap_filtersv.OverlapFilter.NONE, ) with rasterio.open(RGB.byte.tif) as dataset: detections slicer(dataset)这里callback返回的是文档示例中构造的占位检测只用于演示调用链路实际使用时替换成你模型的推理逻辑。两条硬性限制GeoTIFF 必须使用投影坐标系地理坐标系如 WGS84的栅格要先重投影文档建议用gdalwarp再传入从数据集读出的切片保留原始 dtype 和全部波段需要在 callback 内自行转换或选取波段。限制与边界图片尺寸小于等于slice_wh时不会产生多个切片slicer 只做一次全图推理效果等同于基线。slice_wh、overlap_wh、thread_workers、batch_size传非法值非正整数、overlap_wh slice_wh等会在构造InferenceSlicer时抛ValueError。thread_workers 1时遇到 OBB 结果会退回串行处理并警告一次这是有意为之的线程安全保护。提高输入分辨率是另一条小目标思路如RFDETRMedium(resolution1280)或model(image, imgsz1280)但指南指出它消耗更多速度和内存对 4K 及以上分辨率效果有限切片推理与它互不冲突可按需叠加。小目标分割如果任务不只是画框指南同一篇文档给出了分割路径把模型换成RFDETRSegMedium或 Ultralytics 的yolov8x-seg.ptslicer 用法不变标注改用sv.MaskAnnotatorimport cv2 import numpy as np import supervision as sv from rfdetr.detr import RFDETRSegMedium model RFDETRSegMedium() image cv2.imread(SOURCE_IMAGE_PATH) def callback(image_slice: np.ndarray) - sv.Detections: return model.predict(image_slice[:, :, ::-1]) slicer sv.InferenceSlicer(callbackcallback) detections slicer(image) mask_annotator sv.MaskAnnotator() label_annotator sv.LabelAnnotator() annotated_image mask_annotator.annotate( sceneimage, detectionsdetections) annotated_image label_annotator.annotate( sceneannotated_image, detectionsdetections)高分辨率图上目标很多、掩码内存吃紧时把构造参数改成compact_masksTrue掩码会以 RLE 紧凑格式走完合并与标注流程文档提示此时每个掩码的裁剪区域覆盖整个切片需要对合并结果调用CompactMask.repack收紧到检测框。相关文档Detect Small Objects、InferenceSlicer API、Detections 核心对象。【免费下载链接】supervisionWe write your reusable computer vision tools. 项目地址: https://gitcode.com/GitHub_Trending/su/supervision创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表