将COCO 2017数据集多类别语义分割数据集转化为人前景和背景两类的人语义分割数据集

如何将COCO 2017数据集多类别语义分割数据集转化为人前景和背景两类的人语义分割数据集

提示:本文章参考了博主AICVHub的博客https://blog.youkuaiyun.com/oYeZhou/article/details/111994155
链接: 从coco2017数据集中提取语义分割mask



前言

1.人语义分割和多类别语义分割的区别是什么?

人语义分割和多类别语义分割在分类的精细程度和应用场景上存在显著差异。人语义分割专注于对图像中的人进行精确分割,而多类别语义分割则适用于需要对图像中的多个物体或区域进行细粒度的分类和分割的场景。

人语义分割

1.专注于对图像中的人进行精确分割。
2.目的是将图像中的人与背景或其他物体区分开来。
3.在这种分割中,通常不考虑图像中除人以外的其他物体的分类。

多类别语义分割

1.将图像中的每个像素分配到多个不同的类别中。
2.这种方法适用于需要对图像中的多个物体或区域进行细粒度的分类和分割的场景。
3.例如,在自动驾驶领域中,多类别语义分割可以将道路、车辆、行人、交通标志等不同的物体进行准确的分割和识别。

2.为什么要进行人语义分割?

人语义分割是计算机视觉领域中的一种重要技术,它通过对图像中的每个像素进行分类,实现对人体区域的精确识别与分割。
还能为其他计算机视觉任务提供有力的支持。以下是人语义分割对其他计算机视觉任务的具体作用:

1.人语义分割能够精确地将图像中的人体与背景或其他物体区分开来,为人体目标检测与跟踪提供了关键信息。通过结合人语义分割的结果,目标检测算法可以更准确地定位人体区域,减少误检和漏检的情况。同时,在跟踪过程中,人语义分割可以帮助算法更好地锁定人体目标,提高跟踪的稳定性和鲁棒性。

2.人语义分割技术能够识别出图像中的人体区域,并对其进行精确的分割。这一信息对于行为识别和姿态估计等任务至关重要。通过分割出的人体区域,算法可以更准确地捕捉人体的动作和姿态特征,从而实现对人体行为的精确识别和姿态的准确估计。

3.在人语义分割的基础上,可以进一步进行人体属性识别和重识别等任务。人体属性识别是指对人体的一些基本属性(如性别、年龄、服饰等)进行识别,而人体重识别则是指在跨摄像头场景下对人体进行身份匹配。人语义分割提供的精确人体区域信息有助于这些任务的实现,因为它能够减少背景噪声的干扰,提高算法的识别精度和鲁棒性。


提示:以下是本篇文章正文内容,下面案例可供参考

一、原作者博文介绍

"""
get semantic segmentation annotations from coco data set.
"""
from PIL import Image
import imgviz
import argparse
import os
import tqdm
from pycocotools.coco import COCO
 
 
def save_colored_mask(mask, save_path):
    lbl_pil = Image.fromarray(mask.astype(np.uint8), mode="P")
    colormap = imgviz.label_colormap()
    lbl_pil.putpalette(colormap.flatten())
    lbl_pil.save(save_path)
 
 
def main(args):
    annotation_file = os.path.join(args.input_dir, 'annotations', 'instances_{}.json'.format(args.split))
    os.makedirs(os.path.join(args.input_dir, 'SegmentationClass'), exist_ok=True)
    os.makedirs(os.path.join(args.input_dir, 'JPEGImages'), exist_ok=True)
    coco = COCO(annotation_file)
    catIds = coco.getCatIds()
    imgIds = coco.getImgIds()
    print("catIds len:{}, imgIds len:{}".format(len(catIds), len(imgIds)))
    for imgId in tqdm.tqdm(imgIds, ncols=100):
        img = coco.loadImgs(imgId)[0]
        annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
        anns = coco.loadAnns(annIds)
        if len(annIds) > 0:
            mask = coco.annToMask(anns[0]) * anns[0]['category_id']
            for i in range(len(anns) - 1):
                mask += coco.annToMask(anns[i + 1]) * anns[i + 1]['category_id']
            img_origin_path = os.path.join(args.input_dir, 'images', args.split, img['file_name'])
            img_output_path = os.path.join(args.input_dir, 'JPEGImages', img['file_name'])
            seg_output_path = os.path.join(args.input_dir, 'SegmentationClass', img['file_name'].replace('.jpg', '.png'))
            shutil.copy(img_origin_path, img_output_path)
            save_colored_mask(mask, seg_output_path)
 
 
def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input_dir", default="../dataset/coco2017", type=str,
                        help="input dataset directory")
    parser.add_argument("--split", default="train2017", type=str,
                        help="train2017 or val2017")
    return parser.parse_args()
 
 
if __name__ == '__main__':
    args = get_args()
    main(args)

1.通过解析命令行参数以获取输入目录(input_dir)和数据集划分(split,如train2017或val2017)
提示: 作者默认情况下是解析训练集

2.创建用于保存分割掩码和原始图像的目录。
3.使用COCO类加载指定的COCO注解文件。
4.获取所有类别ID(catIds)和图像ID(imgIds)。
5.遍历所有图像ID,为每个图像加载其注释标签。
提示: 查看coco数据集的标签文件是json格式如下图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
6.对于每个图像,如果它有注解,则生成一个分割掩码。这个掩码是通过将每个注解的掩码与其类别ID相乘(为了区分不同的类别),然后将它们相加得到的。
提示: 作者在原文中关于为什么相乘有更加恰当的解释
7.将原始图像复制到指定的输出目录,并将生成的分割掩码保存到另一个指定的输出目录(掩码文件的扩展名从.jpg更改为.png)

二、修改后实现人语义和背景语义数据集

代码如下:

"""
get semantic segmentation annotations from coco data set.
"""
import shutil

import numpy as np
from PIL import Image
import imgviz
import argparse
import os
import tqdm
from pycocotools.coco import COCO


def save_colored_mask(mask, save_path):
    lbl_pil = Image.fromarray(mask.astype(np.uint8), mode="P")
    colormap = imgviz.label_colormap()
    lbl_pil.putpalette(colormap.flatten())
    lbl_pil.save(save_path)


def main(args):
    annotation_file = os.path.join(args.input_dir, 'annotations', 'instances_{}.json'.format(args.split))
    os.makedirs(os.path.join(args.input_dir, 'SegmentationOnlyPerson'), exist_ok=True)
    # os.makedirs(os.path.join(args.input_dir, 'JPEGImages'), exist_ok=True)
    coco = COCO(annotation_file)
    catIds = coco.getCatIds()
    imgIds = coco.getImgIds()
    print("catIds len:{}, imgIds len:{}".format(len(catIds), len(imgIds)))
    print(catIds)
    for imgId in tqdm.tqdm(imgIds, ncols=100):
        img = coco.loadImgs(imgId)[0]

        annIds = coco.getAnnIds(imgIds=img['id'], catIds=[1], iscrowd=None)
        anns = coco.loadAnns(annIds)
        print(anns)
        if len(annIds) > 0:
            # mask = coco.annToMask(anns[0]) * anns[0]['category_id']
         mask = coco.annToMask(anns[0])
         for i in range(len(anns) - 1):
            mask += coco.annToMask(anns[i + 1])
                    # mask += coco.annToMask(anns[i + 1]) * anns[i + 1]['category_id']
         # img_origin_path = os.path.join(args.input_dir,args.split, img['file_name'])
         # img_output_path = os.path.join(args.input_dir, 'JPEGImages', img['file_name'])
         seg_output_path = os.path.join(args.input_dir, 'SegmentationOnlyPerson',
                                               img['file_name'].replace('.jpg', '.png'))
         # shutil.copy(img_origin_path, img_output_path)
         save_colored_mask(mask, seg_output_path)
        # else:
        #     height, width = img['height'], img['width']
        #     black_mask = np.zeros((height, width), dtype=np.uint8)
        #
        #     # 保存全黑掩码图像
        #     seg_output_path = os.path.join(args.input_dir, 'SegmentationClass',
        #                                    img['file_name'].replace('.jpg', '.png'))
        #     image_black_mask = Image.fromarray(black_mask)
        #     image_black_mask.save(seg_output_path)




def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input_dir", default="./", type=str,
                        help="input dataset directory")
    parser.add_argument("--split", default="val2017", type=str,
                        help="train2017 or val2017")
    return parser.parse_args()


if __name__ == '__main__':
    args = get_args()
    main(args)

在这里插入图片描述
查看json文件可以发现如下图可以发现每一个语义类别对应不同的id,因此可以根据需要只保留catIds=[]括号里面是类别id。

在这里插入图片描述
然后根据我个人需要修改了文件路径以及要保存的图片。
最终python文件位置和结果如下图
在这里插入图片描述
在这里插入图片描述

原作者的图像是多语义的:
在这里插入图片描述
我运行后的图像是人语义和背景

在这里插入图片描述

### Matlab 图像分割与抠图方法 在 MATLAB 中实现图像分割抠图可以通过多种算法完成,例如基于 TriMap 的 Alpha Matting 方法[^1] 或者利用更先进的语义分割模型如 Deeplabv3+ 进行自动化处理[^2]。以下是具体的技术细节: #### 使用 Alpha Matting 实现抠图 Alpha Matting 是一种经典的图像分割技术,其核心在于解决如下方程: \[ C = \alpha F - (1-\alpha) B \] 其中 \(C\) 表示输入图像的颜色值,\(F\) \(B\) 分别表示前景背景颜色,\(\alpha\) 则是透明度掩码。由于该方程存在多个未知变量 (\(F, B, \alpha\)),因此需要额外的约束条件来简化问题。 常见的做法是引入 TriMap 来辅助计算。TriMap 将图像分为三类区域:已知背景(黑色)、已知前景(白色)以及不确定区域(灰色)。MATLAB 提供了 `imsegkmeans` 函数用于初步聚类分割,并通过手动标注生成 TriMap 后调用第三方工具包(如 Grady's Matting Toolbox)执行精确的 Alpha 值估计。 ```matlab % 加载原始图像 I = imread('input_image.jpg'); % 创建初始分割标签 L = imsegkmeans(I, 2); % 聚类为两部分:前景背景 % 手动编辑 L 得到最终 Trimap figure; imshow(label2rgb(L)); title('Initial Segmentation'); ``` #### 应用语义分割网络自动去除背景 对于更加复杂的场景,可以采用预训练好的深度学习模型来进行全自动化的背景移除操作。虽然 TensorFlow 是常用的框架之一,但在 MATLAB 中也可以借助 Deep Learning 工具箱加载这些模型并部署推理流程。 以下是一个简单的例子展示如何使用 Mask R-CNN 完成目标检测及实例分割任务从而轻松去掉不需要的部分: ```matlab net = maskrcnnResNet50COCO(); % 下载 COCO 数据集上预训练过的 Mask R-CNN 模型 [labels,scores,bboxes,masks] = detect(net,I); for i=1:length(labels) if strcmpi(char(labels{i}),'person') || ... % 只保留感兴趣的对象类别 strcmpi(char(labels{i}),'dog') I(~masks(:,:,i)) = uint8(zeros(size(I))); % 替换掉其他所有东西 end end imshow(I); title('After Removing Background'); ``` 以上代码片段展示了如何选取特定对象而忽略其余环境干扰因素。 #### 黑白线条化转换作为替代方案 如果仅需简单效果而非高质量分离,则可考虑将原彩照先转化为素描风格再进一步加工。调整阈值参数即可控制黑白对比程度达到理想状态[^3]。 ```matlab grayImage = rgb2gray(I); edgeImage = edge(grayImage,'sobel',0.1); % Sobel 边缘探测器配合适当灵敏度设定 bwImage = imbinarize(edgeImage,.4); % 自定义二值化界限形成清晰轮廓 imshow(bwImage); title('Black and White Sketch Representation'); ``` 此方式快速简便适合某些特殊艺术创作需求场合下应用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值