隔离分割对象
执行分段任务后,有时需要从推理结果中提取孤立对象。本指南提供了如何使用Ultralytics 预测模式实现这一目的的通用方法。
食谱漫步
-
有关安装所需程序库的快速指南,请参见Ultralytics 快速入门安装部分。
-
加载模型并运行
predict()
方法。from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
没有预测论据?
如果未指定来源,则将使用图库中的示例图像:
这有助于使用
predict()
方法。有关细分模型的更多信息,请访问 分段任务 页。了解更多
predict()
方法,见 预测模式 部分。
-
现在遍历结果和轮廓。对于要将图像保存到文件的工作流程,源图像
base-name
和检测class-label
检索,以供以后使用(可选)。from pathlib import Path import numpy as np # (2) Iterate detection results (helpful for multiple images) for r in res: img = np.copy(r.orig_img) img_name = Path(r.path).stem # source image base-name # Iterate each object contour (multiple detections) for ci, c in enumerate(r): # (1) Get detection class name label = c.names[c.boxes.cls.tolist().pop()]
- 要了解有关使用检测结果的更多信息,请参阅 "预测模式方框 "部分。
- 了解更多信息
predict()
结果见 处理预测模式的结果
For-Loop
单幅图像只会重复第一个循环一次。只有一个检测的单个图像将只重复每个循环一次。
-
首先从源图像生成一个二元遮罩,然后在遮罩上绘制填充轮廓。这样就可以将对象与图像的其他部分隔离开来。示例
bus.jpg
为检测到的其中一个person
右侧显示的是类对象。import cv2 # Create binary mask b_mask = np.zeros(img.shape[:2], np.uint8) # (1) Extract contour result contour = c.masks.xy.pop() # (2) Changing the type contour = contour.astype(np.int32) # (3) Reshaping contour = contour.reshape(-1, 1, 2) # Draw contour onto mask _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
-
更多信息
c.masks.xy
看看 预测模式的掩码部分. -
在这里,这些值被转入
np.int32
以兼容drawContours()
从 OpenCV. -
OpenCV
drawContours()
函数希望轮廓的形状为[N, 1, 2]
更多详情,请参阅下文扩展部分。
扩展,以了解在界定
contour
变量。-
c.masks.xy
::提供遮罩轮廓点的坐标,格式为(x, y)
.有关详细信息,请参阅 预测模式的掩码部分. -
.pop()
::作为masks.xy
是一个包含单个元素的列表,该元素将使用pop()
方法。 -
.astype(np.int32)
::使用masks.xy
将返回数据类型为float32
但这与 OpenCVdrawContours()
函数,因此会将数据类型更改为int32
兼容性。 -
.reshape(-1, 1, 2)
::将数据重新格式化为所需的[N, 1, 2]
其中N
是轮廓点的数量,每个点用一个条目表示1
条目包括2
价值观值-1
表示该维度的数值数量是灵活的。
展开以了解
drawContours()
配置。-
封装
contour
变量置于方括号内、[contour]
在测试过程中,发现它能有效生成所需的轮廓掩码。 -
价值
-1
指定的drawContours()
参数指示函数绘制图像中的所有轮廓。 -
"(《世界人权宣言》)
tuple
(255, 255, 255)
代表白色,这是在二进制掩码中绘制轮廓所需的颜色。 -
增加
cv2.FILLED
会给轮廓边界所包围的所有像素涂上相同的颜色,在这种情况下,所有被包围的像素都将是白色。 -
参见 OpenCV 文档
drawContours()
了解更多信息。
-
-
接下来,有两个选项可供选择,分别是如何从此时开始继续处理图像,以及每个选项的后续选项。
对象隔离选项
示例
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
它是如何工作的?
-
首先,二进制掩码要从单通道图像转换为三通道图像。这一转换对于随后将遮罩和原始图像合并的步骤是必要的。两幅图像的通道数必须相同,以便与混合操作兼容。
-
使用 OpenCV 函数合并原始图像和三通道二进制掩码
bitwise_and()
.该操作可保留 只是 像素值大于零(> 0)
从两幅图像中提取。由于掩码像素大于零(> 0)
只是 在轮廓区域内,原始图像中剩余的像素就是与轮廓重叠的像素。
用黑色像素隔离子选项
全尺寸图片
如果保留全尺寸图像,则无需其他步骤。
经裁剪的对象图像
裁剪图像使其只包括目标区域所需的其他步骤。
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- 有关边界框结果的更多信息,请参阅 "预测模式 "中的 "框 "部分。
这段代码有什么作用?
-
"(《世界人权宣言》)
c.boxes.xyxy.cpu().numpy()
调用会以 NumPy 数组的形式在xyxy
格式,其中xmin
,ymin
,xmax
和ymax
代表边界框矩形的坐标。参见 预测模式的方框部分 了解更多详情。 -
"(《世界人权宣言》)
squeeze()
操作会删除 NumPy 数组中不必要的维数,确保数组具有预期的形状。 -
使用
.astype(np.int32)
将方框坐标数据类型从float32
至int32
这样就可以使用索引切片对图像进行裁剪。 -
最后,使用索引切片从图像中裁剪出边界框区域。边界由
[ymin:ymax, xmin:xmax]
检测边界框的坐标。
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
它是如何工作的?
- 使用 NumPy
dstack()
功能(沿深度轴堆叠数组)与生成的二进制掩膜相结合,将创建一个具有四个通道的图像。这样,在保存为图像时,对象轮廓以外的所有像素都将是透明的。PNG
锉刀
用透明像素隔离:子选项
全尺寸图片
如果保留全尺寸图像,则无需其他步骤。
经裁剪的对象图像
裁剪图像使其只包括目标区域所需的其他步骤。
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- 有关边界框结果的更多信息,请参阅 "预测模式 "中的 "框 "部分。
这段代码有什么作用?
-
使用时
c.boxes.xyxy.cpu().numpy()
,边界框会以 NumPy 数组的形式返回,使用xyxy
方框坐标格式,对应于点xmin, ymin, xmax, ymax
的边界框(矩形),请参见 预测模式的方框部分 了解更多信息。 -
添加
squeeze()
确保从 NumPy 数组中删除任何无关的维数。 -
使用
.astype(np.int32)
将方框坐标数据类型从float32
至int32
这在使用索引切片裁剪图像时是兼容的。 -
最后,使用索引切片法裁剪边界框的图像区域,并使用
[ymin:ymax, xmin:xmax]
检测边界框的坐标。
如果我想要包括背景在内的裁剪对象怎么办?
这是Ultralytics 库的内置功能。请参见
save_crop
论点 预测模式推理参数 了解详情。
-
-
下一步该怎么做,完全取决于开发人员。下面是一个可能的下一步的基本示例(将图像保存到文件以备将来使用)。
- 注意:此步骤为可选步骤,如果您的具体使用情况不需要,可跳过此步骤。
最后一步示例
- 在这个例子中,
img_name
是源图像文件的基本名称、label
是检测到的类名,而ci
是 物体检测 (在多个实例具有相同类名的情况下)。
完整示例代码
在这里,上一节中的所有步骤都合并为一个代码块。如果要重复使用,最好定义一个函数来执行以下代码中的部分或全部命令 for
-但这是留给读者的一个练习。
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
m = YOLO("yolo11n-seg.pt") # (4)!
res = m.predict() # (3)!
# Iterate detection results (5)
for r in res:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
# Iterate each object contour (6)
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
b_mask = np.zeros(img.shape[:2], np.uint8)
# Create contour mask (1)
contour = c.masks.xy.pop().astype(np.int32).reshape(-1, 1, 2)
_ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Choose one:
# OPTION-1: Isolate object with black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
# OPTION-2: Isolate object with transparent background (when saved as PNG)
isolated = np.dstack([img, b_mask])
# OPTIONAL: detection crop (from either OPT1 or OPT2)
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]
# TODO your actions go here (2)
- 填充以下内容的行
contour
在这里合并为一行,而在上面是分成多行的。 - 这里的内容由你决定!
- 有关更多信息,请参阅预测模式。
- 更多信息,请参阅 "分段任务"。
- 了解更多有关 "与成果合作 "的信息
- 进一步了解分段屏蔽结果
常见问题
如何使用Ultralytics YOLO11 分离对象以执行分割任务?
要使用Ultralytics YOLO11 隔离对象,请按照以下步骤操作:
-
加载模型并运行推理
-
生成二进制掩码并绘制轮廓:
-
使用二进制掩码隔离对象:
有哪些选项可用于保存分割后的孤立对象?
Ultralytics YOLO11 为保存孤立对象提供了两个主要选项:
-
黑色背景:
-
透明背景
有关详细信息,请访问预测模式部分。
如何使用Ultralytics YOLO11 将孤立对象裁剪到其边界框内?
按照边界框裁剪孤立对象:
-
读取边界框坐标:
-
裁剪孤立的图像:
有关边界框结果的更多信息,请参阅预测模式文档。
为什么要在分割任务中使用Ultralytics YOLO11 进行对象隔离?
Ultralytics YOLO11 提供:
- 高速实时物体检测和分割。
- 精确生成边界框和遮罩,实现精确的对象隔离。
- 全面的文档和易于使用的应用程序接口可实现高效开发。
在分段任务文档中探索使用YOLO 的好处。
我可以使用Ultralytics YOLO11 保存包括背景在内的孤立对象吗?
是的,这是Ultralytics YOLO11 的内置功能。使用 save_crop
参数中的 predict()
方法。例如
了解更多 save_crop
参数中的 预测模式推理参数 节。