API 深度指南:裁剪、缩放、Letterbox、着色与批量落盘)
supervision 图像处理工具集Image UtilsAPI 深度指南裁剪、缩放、Letterbox、着色与批量落盘【免费下载链接】supervisionWe write your reusable computer vision tools. 项目地址: https://gitcode.com/GitHub_Trending/su/supervisionsupervision 的supervision.utils.image模块为计算机视觉工作流提供了一组小而通用的图像级工具函数与类覆盖裁剪、缩放、保持宽高比的 Letterbox 填充、单色着色、灰度化、分辨率查询、从 URL 加载图片以及批量保存图片等高频需求。这些 API 全部在包顶层通过sv.命名空间导出参见src/supervision/__init__.py且绝大部分同时接受 NumPy 数组与 PIL Image 两种输入并保持输出类型一致是搭建检测/跟踪/标注流水线前不可或缺的预处理与后处理基础件。读完本文你将掌握每个 API 的参数语义、默认值、异常边界与源码级实现细节并能直接组合出可用于真实项目的图像处理管线。一、模块总览与通用约定本文对应的官方 API 参考文档位于docs/utils/image.md其内容由 mkdocstrings 依据源码 docstring 自动渲染涵盖以下公开符号API作用默认行为要点crop_image(image, xyxy)按边界框裁剪坐标四舍五入并裁剪到图像边界内scale_image(image, scale_factor)等比缩放因子 1 放大 1 缩小resize_image(image, resolution_wh, keep_aspect_ratioFalse)缩放到指定分辨率可选保持宽高比letterbox_image(image, resolution_wh, colorColor.BLACK)缩放填充到目标分辨率居中填充保持宽高比tint_image(image, colorColor.BLACK, opacity0.5)半透明单色着色内部原地混合grayscale_image(image)转 3 通道灰度灰度广播到三通道get_image_resolution_wh(image)读取 (宽, 高)兼容 NumPy 与 PILload_image_from_url(value, ...)从 URL 加载图片默认磁盘缓存ImageSink上下文管理器批量落盘自动递增命名1.1 输入类型约定NumPy 与 PIL 双兼容大多数纯函数除load_image_from_url外都通过ensure_cv2_image_for_standalone_function装饰器做了统一处理内部实现始终基于 OpenCV/NumPy若传入的是PIL.Image.Image则先经pillow_to_cv2转为 BGR 数组处理完成后经cv2_to_pillow转回 PIL 对象返回若传入 NumPy 数组则直接处理并原样返回。因此调用方无需关心输入来源例如视频抽帧得到的是 NumPy、某些读取库返回的是 PIL输出类型会与输入保持一致。传入其他类型时装饰器会抛出TypeError(Unsupported image type: ...)。1.2 顶层导出所有本文介绍的 API 均已加入包级__all__白名单可通过import supervision as sv后直接以sv.crop_image、sv.ImageSink等短名调用无需再深入supervision.utils.image子模块src/supervision/__init__.py。这也与文档中所有示例的写法保持一致。二、crop_image按边界框精确裁剪sv.crop_image(image, xyxy)image待裁剪图像可为 NumPy 数组或 PIL Image。xyxy边界框坐标格式为(x_min, y_min, x_max, y_max)接受np.ndarray、list[int]或tuple[int, int, int, int]。返回值与输入同类型的裁剪结果。源码要点crop_image实现首先将xyxy转为float64数组并round()四舍五入为int32随后对 NumPy 输入按image[y_min:y_max, x_min:x_max]切片对 PIL 输入调用image.crop(...)。坐标在切片前会被np.clip限制在图像宽高范围内因此越界坐标不会触发负索引环绕或越界异常超界部分自动收敛到图像边界。 import numpy as np import supervision as sv image np.zeros((1080, 1920, 3), dtypenp.uint8) image.shape (1080, 1920, 3) xyxy (400, 400, 800, 800) cropped_image sv.crop_image(imageimage, xyxyxyxy) cropped_image.shape (400, 400, 3)灰度单通道输入同样受支持 image np.zeros((1920, 1080), dtypenp.uint8) image.shape (1920, 1080) xyxy (400, 400, 800, 800) cropped_image sv.crop_image(imageimage, xyxyxyxy) cropped_image.shape (400, 400)典型应用场景检测模型输出的Detections.xyxy本身就是(N, 4)的坐标数组逐行切片即可把每个检测框对应的局部图像裁出来做二次识别、车牌/人脸区域放大、ROI 存档等越界裁剪的稳健性保证了在图像边缘检测框也能安全处理。测试用例test_crop_image覆盖了 NumPy RGB/灰度、PIL RGB/灰度四类输入以及(-2, -1, 3, 3)这类越界坐标验证 NumPy 与 PIL 的裁剪结果完全一致。三、scale_image等比缩放sv.scale_image(image, scale_factor)scale_factor缩放倍数 1.0 放大、 1.0 缩小。必须为正数否则抛出ValueError(Scale factor must be positive.)源码在scale_image开头即校验。 import numpy as np import supervision as sv image np.zeros((1080, 1920, 3), dtypenp.uint8) image.shape (1080, 1920, 3) scaled_image sv.scale_image(imageimage, scale_factor0.5) scaled_image.shape (540, 960, 3)实现上先按width_old * scale_factor、height_old * scale_factor计算新尺寸向下取整再调用cv2.resize(..., interpolationcv2.INTER_LINEAR)。因此缩放是等比、同步进行宽高缩放的适合快速缩略图预览、内存控制等场景。灰度图同样有效例如(1920, 1080)单通道图在scale_factor0.5时输出(960, 540)。四、resize_image缩放到指定分辨率sv.resize_image(image, resolution_wh, keep_aspect_ratioFalse)resolution_wh目标分辨率(width, height)。keep_aspect_ratio是否保持原始宽高比默认False。两种模式的区别keep_aspect_ratioFalse默认直接拉伸到目标宽高可能产生形变。keep_aspect_ratioTrue在目标分辨率矩形内等比适配。源码resize_image先比较image_ratio w/h与target_ratio resolution_wh[0]/resolution_wh[1]若图像更宽则以目标宽为基准、高按比例计算否则以目标高为基准、宽按比例计算。结果通常只在一个维度恰好等于目标值。 import numpy as np import supervision as sv image np.zeros((1080, 1920, 3), dtypenp.uint8) image.shape (1080, 1920, 3) resized_image sv.resize_image( ... imageimage, resolution_wh(1000, 1000), keep_aspect_ratioTrue ... ) resized_image.shape (562, 1000, 3)一个 1920×1080宽 16:9的图像等比放入 1000×1000 目标框内输出宽度即被限制为目标宽 1000、高度按比例收窄到 562。测试test_resize_image_for_opencv_image与 PIL 对应用例验证了640×480 放入 1024×1024 得到 1024×768这一保持宽高比结果。提示若你的目标不是裁剪形变而是等比缩放后再补齐到整幅画面请直接使用下一节的letterbox_image它内部正是复用了resize_image的等比逻辑。五、letterbox_image缩放 居中填充Letterboxsv.letterbox_image(image, resolution_wh, colorColor.BLACK)resolution_wh目标分辨率(width, height)。color填充条颜色。传元组时按BGR 顺序默认Color.BLACK。也支持传入Color对象。工作流程letterbox_image将color统一为 BGR 元组unify_to_bgr以keep_aspect_ratioTrue调用resize_image等比缩放计算上下左右四边剩余像素// 2分配余数归入 bottom/right用cv2.copyMakeBorder(..., cv2.BORDER_CONSTANT, valuecolor)居中填充。 import numpy as np import supervision as sv image np.zeros((1080, 1920, 3), dtypenp.uint8) image.shape (1080, 1920, 3) letterboxed_image sv.letterbox_image( ... imageimage, resolution_wh(1000, 1000) ... ) letterboxed_image.shape (1000, 1000, 3)源码与测试同时确认了三种输入的特殊语义test_letterbox_image_*BGR 三通道填充条为指定颜色图像内容居中不变形BGRA 四通道内容区 alpha 保留原值填充区 alpha 被置为 0完全透明适合直接叠加到其他画面上灰度图填充值取color[0]即颜色元组第一个分量输出仍为单通道例如 4×6 灰度图填充到 10×10 的期望结果为上下各 2 行白色255纯色条。 gray np.zeros((4, 6), dtypenp.uint8) sv.letterbox_image(imagegray, resolution_wh(10, 10)).shape (10, 10)letterbox 是目标检测/推理前标准化的常用手段模型往往要求固定尺寸输入而直接拉伸会扭曲目标宽高比、损害精度letterbox 通过填充保持内容不变形。六、tint_image半透明单色着色sv.tint_image(image, colorColor.BLACK, opacity0.5)color叠加着色颜色默认黑色可为Color对象或 BGR 元组。opacity叠加不透明度取值范围[0.0, 1.0]默认0.5。越界会抛出ValueError(opacity must be between 0.0 and 1.0)。实现原理tint_image用np.full_like(image, fill_valuecolor.as_bgr())构造一张与输入同尺寸的纯色图层再调用cv2.addWeighted(src1overlay, alphaopacity, src2image, beta1-opacity, gamma0, dstimage)完成加权混合。 import numpy as np import supervision as sv image np.zeros((100, 100, 3), dtypenp.uint8) tinted_image sv.tint_image( ... imageimage, colorsv.Color.ROBOFLOW, opacity0.5 ... ) tinted_image.shape (100, 100, 3)两点值得注意的源码细节其一混合写回目标dstimage即对 NumPy 输入而言该函数会原地修改传入数组灰度等非 BGR 场景请先确认输入布局其二opacity同时作为叠加色权重与图像权重的互补因子opacity0时图像不变opacity1时整幅图被纯色覆盖。它常用于视觉区域蒙版、区域压暗高亮、占位占位标识等场景。七、grayscale_image转 3 通道灰度sv.grayscale_image(image)实现grayscale_image分两步先用cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)提取亮度单通道再用cv2.cvtColor(grayscaled, cv2.COLOR_GRAY2BGR)把亮度广播回三个通道。之所以保留三通道而非直接输出单通道灰度是为了与 supervision 内部大量面向 BGR 彩色图的绘图/标注工具兼容——比如在灰度图上叠加彩色文字、边界框注释时不会因通道数不匹配而报错。 import numpy as np import supervision as sv image np.ones((100, 100, 3), dtypenp.uint8) * 128 grayscale_image sv.grayscale_image(imageimage) grayscale_image.shape (100, 100, 3)八、get_image_resolution_wh统一读取分辨率sv.get_image_resolution_wh(image)NumPy 数组取shape[:2]得(height, width)后反转PIL 直接读image.size最终统一返回(width, height)get_image_resolution_wh。这一点与很多 OpenCV 习惯先高后宽、shape 中行高在前不同务必留意 import numpy as np import supervision as sv image np.zeros((1080, 1920, 3), dtypenp.uint8) sv.get_image_resolution_wh(image) (1920, 1080)异常行为NumPy 输入维度不足 2 时抛ValueError输入既非np.ndarray也非PIL.Image.Image时抛TypeError。参数化测试test_get_image_resolution_wh覆盖 RGB/灰度 × NumPy/PIL 四类组合。九、load_image_from_url从 URL 加载图片带本地缓存sv.load_image_from_url( value, cv_imread_flagscv2.IMREAD_COLOR, timeout30.0, use_cacheTrue, cache_dirNone, force_reloadFalse, )value图片的 HTTP(S) URL。cv_imread_flags传给cv2.imdecode的读取标志默认cv2.IMREAD_COLOR即返回 BGR 三通道。timeout请求超时秒默认30.0。use_cache是否在本地缓存下载的字节并在重复调用时复用默认True。cache_dir缓存目录为None时使用默认缓存路径。force_reload为True时强制重新下载并刷新缓存默认False。缓存机制源码见load_image_from_url与_get_image_url_cache_pathURL 先经_normalize_http_url规范化非 HTTP(S) 协议如file://会在此被拒绝测试test_rejects_non_http_url验证了请求层根本不会被触发缓存文件命名为md5(url)后缀后缀取自 URL 路径扩展名无法解析时用.image默认缓存根目录为Path(tempfile.gettempdir()) / supervision / image-urlSUPERVISION_CACHE_DIR定义于src/supervision/utils/file.py命中缓存且force_reloadFalse时直接解码本地字节若缓存字节损坏无法解码成图片实现会先删除坏缓存再重新下载use_cacheFalse时走tempfile.TemporaryDirectory临时下载全程不写持久缓存对应测试test_downloads_each_time_when_cache_is_disabled断言目录保持为空。import supervision as sv image sv.load_image_from_url(https://media.roboflow.com/quickstart/dog.jpeg) image.shape异常说明URL 非法或下载字节无法解码为图片时抛ValueError网络请求失败或返回错误状态码时抛出requests.RequestException。测试test_uses_cached_image_on_repeated_calls证实同一 URL 连续调用两次仅触发一次实际 HTTP 请求非常适合在循环或 Notebook 演示中反复引用同一素材。十、ImageSink上下文管理器批量保存图片sv.ImageSink(target_dir_path, overwriteFalse, image_name_patternimage_{:05d}.png)ImageSink是一个文件系统上下文管理器进入时创建目标目录目录已存在且overwriteTrue时先删除重建退出时无需清理其职责是把逐帧/逐张产生的图片按递增序号连续写入同一目录配合视频抽帧保存、结果归档等场景尤其顺手ImageSink。target_dir_path图片保存的目标目录路径。overwrite是否允许覆盖重建已存在的目录默认False。image_name_pattern文件名格式串默认image_{:05d}.png其中{:05d}会被当前序号补零填充第 0、1、2 张依次为image_00000.png、image_00001.png、image_00002.png。 import numpy as np import supervision as sv import tempfile import os with tempfile.TemporaryDirectory() as tmpdir: ... image np.zeros((100, 100, 3), dtypenp.uint8) ... with sv.ImageSink(target_dir_pathtmpdir, overwriteTrue) as sink: ... sink.save_image(imageimage) ... sink.save_image(imageimage) ... files sorted(os.listdir(tmpdir)) ... len(files) 2成员方法save_image(image, image_nameNone)image_name为None时用image_name_pattern自动生成文件名否则使用自定义文件名底层调用cv2.imwrite写入失败时抛出OSError(Failed to save image to path: ...)且内部计数保持不变测试test_image_sink_raises_when_cv2_write_fails验证了失败后image_count仍为 0。每次成功保存后内部image_count自增因此嵌套在逐帧循环里即可得到连续的图片序列。十一、组合实战一条完整的图像处理管线把上述 API 串起来一个贴近真实工程如目标检测后处理的示例大致长这样import supervision as sv from supervision import Detections # 1. 从 URL 取图带缓存得到 BGR numpy 图 frame sv.load_image_from_url(https://media.roboflow.com/quickstart/dog.jpeg) # 2. 查询分辨率并等比缩放到统一输入尺寸 width, height sv.get_image_resolution_wh(frame) preprocessed sv.letterbox_image(imageframe, resolution_wh(640, 640)) # 3. 假设模型返回了框坐标逐框裁剪出局部图像 # detections model.infer(...) # Detections.xyxy: (N, 4) # crop sv.crop_image(imagepreprocessed, xyxydetections.xyxy[i]) # 4. 批量导出每一帧处理结果 with sv.ImageSink(target_dir_pathoutput/frames, overwriteTrue) as sink: sink.save_image(imagepreprocessed, image_nameframe_001.png)实际工程中该模块经常与检测/跟踪管线配合letterbox_image负责统一推理输入crop_image配合Detections.xyxy提取 ROI参见检测工具文档 docs/detection/core.md 与 docs/utils/conversion.md 了解数据流tint_image/grayscale_image用于可视化与预处理降噪ImageSink在视频逐帧演示如 docs/utils/video.md 介绍的get_video_frames_generator场景中负责把结果落盘成连续图片序列。十二、边界与易错点小结综合源码与单元测试使用时最容易被忽视的细节集中在以下几点返回类型跟随输入类型凡装饰了ensure_cv2_image_for_standalone_function的函数传 PIL 回 PIL、传 NumPy 回 NumPyget_image_resolution_wh与load_image_from_url属于只读/加载类 API分别接受 PIL/NumPy 与仅接受 URL。坐标系与顺序xyxy为(x_min, y_min, x_max, y_max)resolution_wh是(width, height)get_image_resolution_wh返回的同样是(width, height)与 NumPy 数组的(height, width, ...)shape 顺序相反。异常面scale_factor 0、opacity越界、NumPy 图不足 2 维、输入类型不支持、URL 下载/解码失败均会在源码入口即时给出明确报错可据此快速定位问题。原地修改语义tint_image通过dstimage原地写回 NumPy 输入若需保留原图请先np.copy。缓存可控性重复加载同一 URL 默认命中磁盘缓存需要热更新远端图片时请显式传force_reloadTrue。完整实现、类型注解与逐参数 docstring 可继续阅读 src/supervision/utils/image.py行为层面的每一处断言越界裁剪一致性、letterbox 灰度/BGRA 语义、缓存命中与失效重下、写盘失败计数等都可在 tests/utils/test_image.py 中找到对应测试佐证这些 API 的官方文档入口即 docs/utils/image.md。掌握了这九件工具你就拥有了在任意 NumPy/PIL 图像与sv生态其他模块之间灵活衔接的瑞士军刀。【免费下载链接】supervisionWe write your reusable computer vision tools. 项目地址: https://gitcode.com/GitHub_Trending/su/supervision创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考