如何从COCO数据集或Open Images V6数据集中提取特定类别前景对象
从公开分割数据集中提取特定类别前景的操作步骤
你已经完成了带person类分割标注的COCO数据集下载,接下来可以按照以下两种方案提取无背景的前景对象:
方案1:基于已导出的FiftyOne分割结果批量抠图
你导出的ImageSegmentationDirectory格式数据集包含两个核心文件夹:
images:存储原始COCO图片labels:存储和图片同名的单通道语义掩码图,你仅筛选了person类,因此掩码中像素值为1的区域对应person,值为0的区域对应背景
使用以下代码即可批量抠出person类前景,保存为带透明通道的PNG文件:
from PIL import Image import os import numpy as np # 替换为你自己的路径配置 export_dir = "path/fiftyone/image-segmentation-dataset" output_dir = "path/person_foreground" os.makedirs(output_dir, exist_ok=True) img_dir = os.path.join(export_dir, "images") mask_dir = os.path.join(export_dir, "labels") for img_filename in os.listdir(img_dir): # 读取原图并转为RGBA格式(支持透明通道) img_path = os.path.join(img_dir, img_filename) raw_img = Image.open(img_path).convert("RGBA") # 匹配同名掩码文件 mask_filename = f"{os.path.splitext(img_filename)[0]}.png" mask_path = os.path.join(mask_dir, mask_filename) if not os.path.exists(mask_path): continue # 生成透明通道:person区域保留,背景区域透明 mask = np.array(Image.open(mask_path)) alpha_channel = np.where(mask == 1, 255, 0).astype(np.uint8) raw_img.putalpha(Image.fromarray(alpha_channel)) # 保存前景图 output_filename = f"{os.path.splitext(img_filename)[0]}_person.png" raw_img.save(os.path.join(output_dir, output_filename))
方案2:不依赖FiftyOne的通用提取方案
如果不想使用FiftyOne,也可以直接通过对应数据集的官方API完成提取,以COCO官方API为例,操作逻辑如下:
- 下载COCO 2017对应拆分的原图和实例标注JSON文件
- 通过
pycocotools筛选person类的实例标注,生成对应掩码 - 用掩码从原图中抠除背景,保存前景
核心代码示例:
from pycocotools.coco import COCO import cv2 import os import numpy as np # 替换为你自己的路径配置 ann_path = "path/to/instances_val2017.json" img_root = "path/to/val2017" output_dir = "path/person_foreground" os.makedirs(output_dir, exist_ok=True) # 初始化COCO工具 coco = COCO(ann_path) person_cat_id = coco.getCatIds(catNms=["person"])[0] img_ids = coco.getImgIds(catIds=[person_cat_id]) # 取前10张测试,可根据需求调整数量 for img_id in img_ids[:10]: img_info = coco.loadImgs(img_id)[0] img = cv2.imread(os.path.join(img_root, img_info["file_name"]), cv2.IMREAD_UNCHANGED) # 获取当前图片所有person实例的标注 ann_ids = coco.getAnnIds(imgIds=img_id, catIds=[person_cat_id], iscrowd=0) anns = coco.loadAnns(ann_ids) # 逐个提取每个person实例 for ann_idx, ann in enumerate(anns): mask = coco.annToMask(ann) # 生成带透明通道的前景图 fg_img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) fg_img[mask == 0, 3] = 0 # 背景区域透明 # 保存 cv2.imwrite(os.path.join(output_dir, f"person_{img_id}_{ann_idx}.png"), fg_img)
优化提示
- 抠出的前景需要保存为PNG格式才能保留透明通道,不要存储为JPG格式
- 合成到新场景前可以对前景边缘做1~3像素的羽化处理,避免边缘过于生硬
- Open Images V6的提取逻辑一致,只要拿到对应类别的实例分割掩码和原图对齐后即可完成抠取
内容的提问来源于stack exchange,提问作者Dev01
相关产品推荐
相关产品推荐

