如何将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文件位置和结果如下图
原作者的图像是多语义的:
我运行后的图像是人语义和背景