Ultralytics ObjectCropper API 全面解析:实现检测对象的实时裁剪与按帧持久化存储
【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics
ObjectCropper 是 Ultralytics Solutions 视觉方案包中的一个核心类,它继承自BaseSolution,面向"把视频流或图像中每一个被检测到的目标按照边界框精确抠出并保存成独立图片"这一任务。本文以ultralytics/solutions/object_cropper.py的 API 定义为主线,结合其配置系统、调用入口与测试用例,讲解裁剪目录管理、置信度/IoU 过滤、逐目标顺序编号保存等完整机制,帮助你在自动化数据采集、数据集构建与聚焦分析等场景中直接落地这套能力。
ObjectCropper 在 Ultralytics 中的定位
在 Ultralytics Solutions 方案体系里,ObjectCropper与ObjectBlurrer、ObjectCounter、Heatmap、AIGym等解决方案并列,统一由 solutions/init.py 导出,并注册在 Solutions 的 CLI 映射表中(cfg/init.py 中"crop": "ObjectCropper")。
从 object_cropper.py 的类定义(L10-L30)可以看到,其职责被明确描述为:在实时视频流或图像中管理检测对象的裁剪,基于检测到的边界框裁剪目标,并将裁剪图保存到指定目录,供后续分析或使用。与其它依赖目标跟踪(model.track)的 Solutions 不同,ObjectCropper 走的是纯检测路径(model.predict),因此不需要跨帧维持 ID,输出结果简单直接——这也是它特别适合"逐帧抽帧 + 抠目标"这类离线/在线批量任务的原因。
该类的核心设计要点包括:
- 继承
BaseSolution,自动获得统一的SolutionConfig配置合并、日志器、profiler 计时与可调用对象机制(solutions.py)。 - 通过类属性
crop_dir记录裁剪输出目录,crop_idx作为累计裁剪计数器,iou/conf用于在推理时过滤检测框。 - 提供唯一的对外处理入口
process(im0),输入一张图像(np.ndarray),返回携带裁剪总数的SolutionResults对象。
ObjectCropper 公开 API 速览
下表归纳了参考文档中公开的类成员与说明,出处为 object_cropper.py 的类 docstring(L16-L24):
| 成员 | 类型/返回 | 说明 |
|---|---|---|
crop_dir | 属性(str) | 裁剪对象图片的存放目录,来源于配置项crop_dir,默认"cropped-detections" |
crop_idx | 属性(int) | 累计裁剪对象数量计数器,每裁剪一个目标自增 1 |
iou | 属性(float) | 非极大值抑制(NMS)用的 IoU 阈值,默认0.7 |
conf | 属性(float) | 检测结果过滤的置信度阈值,默认0.25 |
__init__(**kwargs) | 构造器 | 向父类透传关键字参数,并读取crop_dir、iou、conf等配置 |
process(im0) | SolutionResults | 从输入图像中检测并裁剪对象,逐张保存,返回含total_crop_objects的结果对象 |
类 docstring 给出的最小用法如下(官方示例,见 L25-L29):
cropper = ObjectCropper() frame = cv2.imread("frame.jpg") processed_results = cropper.process(frame) print(f"Total cropped objects: {cropper.crop_idx}")快速开始:命令行与 Python 两种用法
ObjectCropper同时暴露了 CLI 与 Python 两套入口。由于参考文档以 API 为主,这里依据配套教程 guides/object-cropping.md 补充可直接运行的示例。
CLI 方式
# 直接裁剪(未指定 source 时 Solutions CLI 会自动下载演示视频作为输入) yolo solutions crop # 传入自己的视频源 yolo solutions crop source="path/to/video.mp4" # 只裁剪指定的类别(COCO 预训练模型下 0 代表人,2 代表车) yolo solutions crop classes="[0, 2]"在 CLI 内部,yolo solutions crop会被解析为实例化solutions.ObjectCropper(is_cli=True, **overrides),随后逐帧调用solution(frame)(cfg/init.py)。值得注意的一个特殊分支:crop 是唯一不写输出视频的 Solutions——代码中当solution_name != "crop"时才初始化cv2.VideoWriter,因为 ObjectCropper 的产出是裁剪图片而非标注视频。
Python 方式
import cv2 from ultralytics import solutions cap = cv2.VideoCapture("path/to/video.mp4") assert cap.isOpened(), "Error reading video file" # 初始化对象裁剪器 cropper = solutions.ObjectCropper( model="yolo26n.pt", # 用于目标检测的模型,例如可换 yolo26x.pt classes=[0, 2], # 只裁剪指定类别(COCO 预训练下:人、车) # conf=0.5, # 提高置信度阈值,只保留可靠检测 # crop_dir="cropped-detections", # 自定义裁剪保存目录 ) while cap.isOpened(): success, im0 = cap.read() if not success: print("Video frame is empty or processing is complete.") break results = cropper(im0) # 内部会调用 process(),并附带耗时统计 # print(results) # 可通过 SolutionResults 查看输出 cap.release() cv2.destroyAllWindows()当未显式传入crop_dir时,会使用默认值"cropped-detections",每张裁剪图都会被写入该目录,文件名按顺序编号(如crop_1.jpg、crop_2.jpg)。这意味着无需额外编写任何落盘代码,即可直接获得可检查、可继续喂给下游流程的裁剪数据集。
构造流程与参数体系:配置从哪来、默认值是什么
ObjectCropper.__init__(object_cropper.py)会调用super().__init__(**kwargs),把全部关键字参数交给BaseSolution。BaseSolution初始化(solutions.py)的核心步骤包括:
- 通过
SolutionConfig().update(**kwargs)生成统一的配置字典self.CFG,并将结果记录到日志; - 检查
shapely>=2.0.0依赖; - 若
model为空,则回退到默认模型yolo26n.pt,并加载YOLO模型; - 提取
classes、show_conf、show_labels、device、iou、conf、max_det、imgsz等推理相关参数。
随后 ObjectCropper 专属初始化做了三件事:
- 从
CFG中取出crop_dir,并用Path(crop_dir).mkdir(parents=True, exist_ok=True)立即创建目录,保证后续写入不因目录缺失而失败; - 检测到
show=True时发出告警"show=True is not supported for ObjectCropper; saving crops to '{self.crop_dir}'.",并强制关闭窗口显示——因为本方案的产物是图片文件而非可视化窗口(对应的show=True分支测试见 tests/test_solutions.py); - 初始化
crop_idx = 0,并把iou、conf缓存在实例上。
全部相关配置项与默认值
配置中心的定义位于 config.py,对 ObjectCropper 有直接影响的参数整理如下(默认值同时被 solutions-args.md 文档宏引用):
| 参数 | 类型 | 默认值 | 对 ObjectCropper 的作用 |
|---|---|---|---|
crop_dir | str | 'cropped-detections' | 裁剪图片的输出目录,构造时自动创建 |
model | str | None(回退yolo26n.pt) | 用于检测的模型权重路径 |
classes | list[int] | None | 只裁剪指定类别索引,None表示全部类别 |
conf | float | 0.25 | 保留检测的最低置信度,用于过滤误检 |
iou | float | 0.7 | NMS 的 IoU 阈值 |
imgsz | int | 640 | 送入模型的输入尺寸 |
device | str | None | 推理设备(如'cpu'、'0'),默认自动选择 |
max_det | int | 300 | 单帧允许的最大检测数量 |
quantize | int/str | None | 推理精度设置(如 16 即 FP16),替换旧half参数 |
source | str | None | 仅 CLI 使用,视频输入路径 |
verbose | bool | True | 每帧打印类别计数与耗时日志 |
show | bool | False | ObjectCropper 不支持,置True会告警并强制关闭 |
SolutionConfig.update()(config.py)会逐个校验关键字:只有已声明的属性才能被覆盖,否则抛出ValueError,这一机制保证了传入参数不会被静默忽略;同时它支持将旧版half参数自动迁移到quantize。
process() 源码级拆解:检测、过滤、裁剪的完整链路
核心处理逻辑process(im0)(object_cropper.py)非常精炼,但包含了一条完整的数据管线:
1. 推理阶段
with self.profilers[0]: results = self.model.predict( im0, classes=self.classes, conf=self.conf, iou=self.iou, device=self.CFG["device"], imgsz=self.CFG["imgsz"], verbose=False, )[0] self.clss = results.boxes.cls.tolist() # required for logging only.- 推理被包裹在
self.profilers[0]中计时,结果交给BaseSolution.__call__汇总为predict耗时; - 通过
classes、conf、iou三个参数把配置中的过滤策略直接下发给predict,实现类别过滤 + 置信度过滤 + NMS 过滤的一站式执行; verbose=False使内部推理静默,避免每帧刷屏;self.clss仅用于后续逐帧日志统计各类别数量。
2. 裁剪阶段
for box in results.boxes: self.crop_idx += 1 save_one_box( box.xyxy, im0, file=Path(self.crop_dir) / f"crop_{self.crop_idx}.jpg", BGR=True, )- 遍历当前帧全部检测框
results.boxes; crop_idx是跨帧累加的全局计数器,因此即使视频后续帧目标更多或更少,文件名也始终全局唯一、严格递增,不会互相覆盖;- 每个框调用
save_one_box,把框坐标(box.xyxy)、原图im0与目标路径传入,BGR=True表示按 OpenCV 的 BGR 顺序直接落盘(这与cv2.VideoCapture读取的通道顺序一致)。
3. 结果返回阶段
return SolutionResults(plot_im=im0, total_crop_objects=self.crop_idx)返回的SolutionResults对象(定义见 solutions.py)携带两个关键信息:
plot_im:原始输入帧(ObjectCropper 不叠加任何可视化标注,因此 CLI 分支无需写输出视频);total_crop_objects:到目前为止的累计裁剪总数,可通过results.total_crop_objects直接读取。
裁剪底层的实现细节:save_one_box 都做了什么
裁剪动作最终落在ultralytics.utils.plotting.save_one_box(plotting.py)。理解它有助于你预测裁剪结果的边界行为:
- 格式转换与取整:
xyxy被转为xywh后先按gain放大并加pad像素,再转回xyxy并取整(b[:, 2:] * gain + pad),默认gain=1.02、pad=10,即裁剪框四周会留出约 2% 外扩与 10 像素边距,避免目标紧贴裁剪边界; - 边界裁剪保护:通过
ops.clip_boxes(xyxy, im.shape)将越界坐标裁回图像范围,保证靠近图像边缘的目标不会产生切片越界错误; - 通道序处理:
BGR=True时保持 BGR 顺序(灰度图天然不受影响),否则会做通道反转; - 返回与保存两用:
save=True时写入磁盘,同时始终返回裁剪后的crop数组。
因此 ObjectCropper 生成的每张crop_N.jpg并不是严格的裸检测框,而是带少量边距、经过边界保护的原图子块。
调用时机的性能统计与逐帧日志
虽然process()是逻辑入口,但推荐用法是直接调用实例(cropper(im0)),因为BaseSolution.__call__(solutions.py)提供了两层附加价值:
- 耗时拆分:通过两个独立的
profiler计算出predict(检测推理)与solution(方案自身逻辑)各自耗时,单位为毫秒,写入results.speed字典; - verbose 日志:当
CFG["verbose"]为True时,逐帧输出帧号、输入分辨率、各类别检测数量以及推理速度,例如形如"Speed: xx.xms predict, x.xms solution per image..."的信息。注意在__call__中,ObjectCropper 类型会被识别为走predict而非track计时路径(solutions.py),这也再次印证了它不依赖跟踪链路。
基于测试用例的可靠性验证
仓库的解决方案测试套件 tests/test_solutions.py 对 ObjectCropper 覆盖了两个维度:
- 端到端视频流程(L133-L140):在参数化测试
test_solution中,以"ObjectCropper"+solutions.ObjectCropper配对,使用crop_video演示视频、temp_crop_dir(会映射成临时目录下的cropped-detections)运行完整process_video,验证其能从真实视频中稳定产出裁剪图片;测试统一设置了imgsz=320以控制 CI 推理成本; - 构造告警覆盖(L451-L453):
test_object_crop_with_show_True专门以show=True实例化,覆盖构造函数中"不支持窗口显示并强制关闭"的告警分支。
这说明 API 文档所描述的行为(目录写入、逐帧裁剪、show 告警)均有自动化测试兜底,可作为二次开发时校验自身集成的参照。
使用建议与已知限制
结合源码行为,给出以下实操要点与边界说明:
- 构建数据集的理想拍档:配合
classes过滤 + 适度提高conf,可以只把可靠目标落入磁盘;配合逐帧读取视频,即可在无人值守下把整段视频转换为"目标子图集合",供后续分类、检索、标注或模型训练使用。 - 不要指望可视化输出:ObjectCropper 不绘制标注框、不支持
show,也不在 CLI 下生成结果视频。若同时需要"标注可视化",建议改用predict/track模式或自行基于plot_im叠加标注。 - 模型与设备选择:模型默认
yolo26n.pt,可按精度需求换yolo26s.pt、yolo26x.pt等;大批量处理时通过device="0"(GPU)与imgsz权衡吞吐。以上均为配置文件与 CLI 可覆盖项。 - 参数合法性有兜底:任何不在
SolutionConfig中的关键字都会触发ValueError,写错参数名不会静默失败。 - 文件命名全局单调递增:
crop_idx从实例创建起累计,若在长视频中意外中断并新建实例,编号会从 1 重新开始,可能与旧文件重名——建议为不同批次指定不同crop_dir。
相关参考
- API 参考页面:docs/en/reference/solutions/object_cropper.md
- 配套实战教程:docs/en/guides/object-cropping.md
- 核心实现:ultralytics/solutions/object_cropper.py
- 基类与统一调用/结果对象:ultralytics/solutions/solutions.py
- 配置中心与默认值:ultralytics/solutions/config.py
- 裁剪落盘函数
save_one_box:ultralytics/utils/plotting.py - CLI 解决方案映射与执行分支:ultralytics/cfg/init.py
- 自动化测试:tests/test_solutions.py
- Solutions 方案总览:docs/en/solutions/index.md
【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考