Meet YOLO26: next-gen vision AI.

Link to this section如何使用 Ultralytics YOLO 分离分割对象#

实例分割 会为每个检测到的对象生成像素级的掩码,这意味着你可以将每个对象从图像中单独提取出来。本指南将展示如何使用 预测模式 和 OpenCV 将 Ultralytics YOLO 分割结果转换为独立对象,并将其保存为黑色背景或透明背景的 PNG。



Watch: How to Remove Background and Isolate Objects with Ultralytics YOLO Segmentation & OpenCV in Python 🚀

Link to this section为什么要分离分割对象?#

从图像中提取单个对象可以开启一系列下游工作流程:

  • 背景去除:用于产品拍摄、目录制作或创意编辑。
  • 逐个对象裁剪:从检测结果中构建分类数据集。
  • 聚焦处理:确保后续步骤(如 OCR、颜色分析或测量)仅看到对象本身,而非周围场景。
  • 透明 PNG 导出:将对象合成到新背景上。

该方法适用于任何 Ultralytics YOLO 分割模型,并遵循四个阶段:运行推理提取每个轮廓分离对象保存结果

Link to this section运行分割推理#

安装所需的库,然后加载一个分割模型(带有 -seg 后缀,这是生成掩码所必需的),并对源图像运行预测:

from ultralytics import YOLO

# Load a segmentation model
model = YOLO("yolo26n-seg.pt")

# Run inference on a source
results = model.predict(source="path/to/image.jpg")
没有源图像?YOLO 会使用自带的示例图像

如果你在调用 model.predict() 时不指定 source,Ultralytics 将默认使用包中附带的示例图像(bus.jpgzidane.jpg),这对于快速测试工作流程非常方便。

Link to this section提取对象轮廓#

results 中的每一项对应一张图像,遍历结果即可一次获取一个检测对象。对于每个检测结果,复制原始图像,读取类别标签,并将对象的掩码轮廓绘制到空白的二值掩码上。该掩码的白色区域精确标记了哪些像素属于该对象。

本节和下一节中的代码片段都在下方的检测循环内部运行;完整的复制粘贴脚本可在 完整示例 中找到。

二值掩码图像{ width="240", align="right" }

from pathlib import Path

import cv2
import numpy as np

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem  # source image base-name

    # Iterate each detected object in the image
    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]  # class name

        # Build a binary mask and draw the object contour onto it
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
`c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)` 是做什么的?
  • c.masks.xy[0] returns the mask contour as (x, y) point coordinates for the object in this single-detection result.
  • .astype(np.int32) 将坐标点从 float32 转换为 OpenCV drawContours() 可接受的格式。
  • .reshape(-1, 1, 2) reshapes the points into the [N, 1, 2] layout drawContours() expects, where N is the number of contour points.

传入 [contour] 并使用索引 -1 可以绘制所提供轮廓的所有点,而 cv2.FILLED 则将所有封闭的像素填充为白色。

Link to this section分离对象#

准备好二值掩码后,将其与原始图像结合。根据你想要的背景效果,有两种常见的样式:

选择一种分离样式

将掩码转换为三个通道,并仅保留与对象重叠的像素。轮廓之外的所有区域都会变为黑色:

# Isolate object with a black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
![Example Full size Isolated Object Image Black Background](https://cdn.jsdelivr.net/gh/ultralytics/assets@main/docs/full-size-isolated-object-black-background.avif){ width=240 }
Full-size object on a black background
裁剪至边界框

如果只想保留对象所在的区域而不是全尺寸图像,可以将其裁剪至检测结果的边界框:

# Bounding box coordinates
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Crop the isolated image to the object region
iso_crop = isolated[y1:y2, x1:x2]
![Example Crop Isolated Object Image Black Background](https://cdn.jsdelivr.net/gh/ultralytics/assets@main/docs/example-crop-isolated-object-image-black-background.avif){ width=240 }
Object cropped to its bounding box
需要带有原始背景的裁剪图像吗?

这本身就是内置功能。将 save_crop=True 传递给 predict(),Ultralytics 就会自动保存边界框裁剪图,无需进行掩码处理。

Link to this section保存结果(可选)#

如何处理每个分离出的对象取决于你自己。一个常见的后续步骤是将其写入磁盘以便日后使用:

# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

这里的 img_name 是源图像名称,label 是类别名称,ci 是检测索引,因此同一类别的多个实例会获得唯一的文件名。如果你应用了上面的可选裁剪,请将 isolated 替换为 iso_crop

Link to this section完整示例#

下面的脚本将每个步骤合并为一个可运行的代码块。它默认使用黑色背景;如需获取透明 PNG,请将标记的那一行代码切换为 np.dstack([img, b_mask])

from pathlib import Path

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/image.jpg")

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem

    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]

        # Build a binary mask from the object contour
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)

        # Isolate the object (black background)
        mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
        isolated = cv2.bitwise_and(mask3ch, img)  # transparent PNG: isolated = np.dstack([img, b_mask])

        # Save or add your custom post-processing here
        cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

        # Optional: crop to the bounding box before saving
        # x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
        # cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated[y1:y2, x1:x2])

为了重复使用,可以将循环体封装在一个函数中,以便在多张图像上调用。

Link to this section结论#

你现在已经掌握了使用 Ultralytics YOLO 分离分割对象的完整流程:运行推理,从每个轮廓构建二值掩码,然后在黑色或透明背景上提取对象,并可选择将其裁剪至边界框。请探索完整的 分割任务预测模式 文档,以根据自己的类别调整工作流程。

Link to this section常见问题解答#

Link to this section如何使用 Ultralytics YOLO 分离分割任务中的对象?#

加载一个分割模型,运行推理,从每个检测结果的轮廓构建二值掩码,并将其与原始图像结合:

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/your/image.jpg")

img = np.copy(results[0].orig_img)
b_mask = np.zeros(img.shape[:2], np.uint8)
contour = results[0].masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)

mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)

请参阅 完整示例 以查看完整的逐个检测循环代码。

Link to this section分割后保存分离对象有哪些可用选项?#

有两种主要样式。对于 黑色背景,将掩码转换为三个通道并使用 cv2.bitwise_and()。对于 透明背景(保存为 PNG 时),使用 np.dstack([img, b_mask]) 将掩码堆叠为第四个 Alpha 通道。两者均在 分离对象 一节中有所展示。

Link to this section如何将分离的对象裁剪至其边界框?#

从检测结果中读取边界框坐标并对分离出的图像进行切片:

x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]

预测模式 文档中了解更多关于边界框结果的信息。

Link to this section为什么在分割任务中要使用 Ultralytics YOLO 来进行对象分离?#

Ultralytics YOLO 提供快速、实时的实例分割功能,具备精确的掩码和边界框生成能力,此外还有一个简洁的 Python API,只需几行 OpenCV 代码即可将推理结果转化为独立的对象。

Link to this section我可以使用 Ultralytics YOLO 保存包含原始背景的分离对象吗?#

Yes. Use the save_crop argument in predict() to save bounding-box crops with their original background:

results = model.predict(source="path/to/your/image.jpg", save_crop=True)

阅读 预测模式推理参数 部分以了解更多信息。

评论