【COCO数据集】COCO API 解析图像数据和目标标签,vision-transformer DETR的相关transforms操作实现

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 【COCO数据集】COCO API 解析图像数据和目标标签,vision-transformer DETR的相关transforms操作实现

在大多数情况下,我们在为模型创建训练数据集时无需担心注释格式。 COCO API为我们提供了一系列的api函数,方便我们获取任务的图像数据和目标标签。

PaddleViT: COCODataset

COCO数据集有一个名为pycocotools的 python API,供用户轻松加载和使用COCO数据集进行检测、分割和其他cv任务。 以下是基于 pycocotools 实现COCO检测数据集的PaddleViT实现,并用于训练和验证。

CocoDataset Class

CocoDataset 类由 paddle.io.Dataset 类实现, 并需要两个函数 __getitem__ 与 __len__ , 即:

class CocoDetection(paddle.io.Dataset):
    def __init__(self, image_folder, anno_file, transforms, return_mask):
        super().__init__()
        ...
    def __getitem__(self, idx):
        ...
    def __len__(self):
        ...

__init__ method

在类的初始化方法中:

  1. 通过调用pycocotools api加载coco数据集的anno文件。
  2. 获取图像id并删除没有注释的图像。
  3. 通过init参数设置数据转换(预处理器)。
  4. 定义标签转换方法。(详情见下节)。
from pycocotools.coco import COCO
...
class CocoDataset():
    def __init__(self):
        super().__init__()
        # step1
        self.coco = COCO(anno_file)
        # step2
        ids = list(sorted(self.coco.imgs.keys()))
        self.ids = self._remove_images_without_annotations(ids)
        # step3
        self._transforms = transforms
        # step4
        self.prepare = ConvertCocoPolysToMasks(return_masks)
        self.root = img_folder

__getitem__ method

__getitem__方法将索引作为输入,并输出包含单张图像及其目标标签的(image, target) 对。在coco检测中,这个目标是一个类似于以下形式的 dict :

target = {'image_id': image_id, 'annotations': target}

image_id 是在coco注释中相同的图像id.

target 是键值对的字典,例如 bbox 和 mask. (英文版单词拼写错误)

__getitem__ 方法定义:

  1. 使用COCO API加载指定的图像及其标签
  2. 转换标签(如将掩码从多边形转换为掩码数组)
  3. 输入数据的预处理转换
def __getitem__(self, idx):
    image_id = self.ids[idx]
    image = self._load_image(image_id)
    target = self._load_target(image_id)
    target = {'image_id': image_id, 'annotations': target}
    image, target = self.prepare(image, target)
    if self._transform is not None:
        image, target = self._transform(image, target)
    return image, target

__len__ method

返回数据集中的样本数,与ids长度相同:

def __len__(self):
    return len(self.ids)

_load_image, _load_target methods

PIL.Image 和 COCO API 用于根据给定索引获取图像数据和原始目标标签.

def _load_image(self, idx):
    """ Return PIL Image (RGB) according to COCO image id"""
    path = self.coco.loadImgs(idx)[0]['file_name']
    return Image.open(os.path.join(self.root, path)).convert('RGB')
def _load_target(self, idx):
    """ Return image annos according to COCO image id"""
    return self.coco.loadAnns(self.coco.getAnnIds(idx))

ConvertCocoPolysToMasks Class

该类定义了以图像和标签为输入并输出图像数组和处理后的标签。

专门对于目标标签的处理:

  1. 去掉iscrowd=1的图像;
  2. 将[x1, y1, x2, y2]中的包围框转换为numpy数组类型,然后根据包围框裁剪图像;
  3. 将类标签转换为numpy数组;
  4. 如果返回掩码(对于分割任务),使用coco api将多边形数据转换为掩码数组;
  5. 如果返回关键点(用于关键点检测),则将关键点加载到数组中;
  6. 消除面积为0的包围框;
  7. 将处理后的标签保存在target字典中。

Transforms Module

在转换模块(transforms.py)中定义了多种数据压缩方法。 定义我们自己的模块而不是使用paddle视觉转换的原因是,每个数据变换都必须应用于图像数据集其目标标签,例如bbox和掩码。假设在训练期间对图像数据应用类随机裁剪操作,则该图像中的bbox必需应用相同的裁剪。

Validation transforms

DETR 的验证转换具有以下操作:

  • RandomResize(): 将图像和标签调整为具有相同比例的特定大小。
  • ToTensor(): 将图像数据转换为 paddle.Tensor
  • Normalize(): 均值$-mean$和$/std$

Training transforms

DETR的训练转换具有以下操作:

  • RandomHorizontalFlip() 随机水平翻转数据。
  • RandomSelect() 随机选择两个子操作之一: (1) 一个单个 RandomResize 步骤; (2) 一个 三步骤操作: RandomReize, RandomSizeCrop, 以及 RandomResize
  • ToTensor(): 将图像数据转换为 paddle.Tensor
  • Normalize(): 图像数据标准化, $-mean$ 和 $/std$

RandomHorizontalFlip()

此变换需要初始化参数中的概率用来控制是否应用反转的随机性。

class RandomHorizontalFlip():
    def __init__(self, p=0.5):
        self.p = p
    def __call__(self, image, target):
        if random.random() < self.p:
            return hflip(image, target)
        return image, target

hflip 方法定义了图像和目标(包含包围框和盐吗的真实标注值的字典)的水平翻转操作。

RandomSelect()

RandomSelect()有一个prob值控制选择它的两个子操作之一的随机性。

class RandomSelect():
    """ Random select one the transforms to apply with probablity p"""
    def __init__(self, transforms1, transforms2, p=0.5):
        self.transforms1 = transforms1
        self.transforms2 = transforms2
        self.p = p
    def __call__(self, image, target):
        if random.random() > self.p:
            return self.transforms1(image, target)
        return self.transforms2(image, target)

两个转换操作在DETR训练中使用:

  • RandomResize()
  • RandomResize() + RandomSizeCrop() + RandomResize()

RandomResize()

RandomResize有两个参数:sizes 和 max_size. 该方法随机选择sizes中的一个值作为图像短边的目标尺寸,同时保持图像的比例不变。但是,如果图像的长边大于max_size(当使用所选尺寸作为短边时),则将图像的长边设置为max_size,而较短的尺寸需要重新计算以保持图像长宽比例不变。

必须在bbox和掩码使用相同的尺寸调整操作。 通过乘以高度和宽度的比例可以转换包围框。可以通过插值和二值化来转换掩码以获得缩放掩码(如果 values > 0.5则设置为1,否则设置为0)。

RandomSizeCrop()

RandomSizeCrop 将min_size和max_size 作为输入,然后将裁减图像中的随机区域作为输出。输出区域的尺寸为 [randint(min_size, max_size), randint(min_size, max_size)].

RandomSizeCrop 分为三个步骤实现:

  • STEP1: 给定 min_size, max_size 和原始图像尺寸,生成随机图像宽度和图像高度。
  • STEP2: 给定裁剪后的图像大小,随机选择图像内裁减区域的位置。这个区域可以用 [top, left, height, width]表示.
  • STEP3: 给定裁剪区域,裁剪图像和目标的标签,例如 包围框和掩码.

具体来说,我们实现了一个crop方法,其输入

(1)在[top, left, height, width]中的裁剪区域,

(2) 原始图像 以及 (3) 目标标签,然后返回裁剪后的图像和裁剪后的标签。

(请注意,在裁剪之后,原始包围框或者掩码也会被裁剪,甚至在裁剪后的图像中看不到,因此,我们必须从目标标签中消除那些无效的框和掩吗。)

ToTensor()

ToTensor 将图像数据从PIL.Image转换为paddle.Tensor, 返回图像张量和相应的标签,通过以下方式可以实现:

import paddle.vision.transforms as T
class ToTensor:
    def __call__(self, image, target):
        return T.to_tensor(image), target

Normalize()

在 Normalize方法中, 除了数据归一化(-mean & /std), 我们还将包围框从 [x0, y0, x1, y1] 归一化为 [cx, cy, w, h], 根据图像尺寸归一化为相对坐标. 实现方式如下:

class Normalize():
    def __init__(self, mean, std):
        self.mean = mean
        self.std = std
    def __call__(self, image, target=None):
        # -mean, / std
        image = T.functional.normalize(image, mean=self.mean, std=self.std)
        if target is None:
            return image, None
        target = target.copy()
        # from xyxy -> cxcywh -> relative coords
        h, w = image.shape[-2:]
        if 'boxes' in target and target['boxes'].shape[0] != 0:
            boxes = target['boxes']
            boxes = box_xyxy_to_cxcywh_numpy(boxes)
            boxes = boxes / np.array([w, h, w, h], dtype='float32')
            target['boxes'] = boxes
        return image, target
目录
相关文章
|
4天前
|
XML 数据挖掘 API
1688商品详情数据示例参考,1688API接口系列
在成长的路上,我们都是同行者。这篇关于详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
1天前
|
JSON Shell API
如何通过API获取淘宝商品月销售数据
淘宝开放平台提供了丰富的API接口,允许开发者获取商品的详细信息,包括月销售数据。
|
11天前
|
搜索推荐 数据挖掘 API
Lazada 淘宝详情 API 的价值与应用解析
在全球化电商浪潮下,Lazada 和淘宝作为东南亚和中国电商市场的关键力量,拥有海量商品数据和庞大用户群体。详情 API 接口为电商开发者、商家和分析师提供了获取商品详细信息(如描述、价格、库存、评价等)的工具,助力业务决策与创新。本文深入解析 Lazada 和淘宝详情 API 的应用场景及价值,并提供 Python 调用示例,帮助读者更好地理解和运用这两个强大的工具。
45 18
|
10天前
|
数据采集 搜索推荐 API
小红书笔记详情 API 接口:获取、应用与收益全解析
小红书(RED)是国内领先的生活方式分享平台,汇聚大量用户生成内容(UGC),尤以“种草”笔记闻名。小红书笔记详情API接口为开发者提供了获取笔记详细信息的强大工具,包括标题、内容、图片、点赞数等。通过注册开放平台账号、申请API权限并调用接口,开发者可构建内容分析工具、笔记推荐系统、数据爬虫等应用,提升用户体验和运营效率,创造新的商业模式。本文将详细介绍该API的获取、应用及潜在收益,并附上代码示例。
98 13
|
1天前
|
数据采集 JSON Java
Java爬虫获取微店快递费用item_fee API接口数据实现
本文介绍如何使用Java开发爬虫程序,通过微店API接口获取商品快递费用(item_fee)数据。主要内容包括:微店API接口的使用方法、Java爬虫技术背景、需求分析和技术选型。具体实现步骤为:发送HTTP请求获取数据、解析JSON格式的响应并提取快递费用信息,最后将结果存储到本地文件中。文中还提供了完整的代码示例,并提醒开发者注意授权令牌、接口频率限制及数据合法性等问题。
|
6天前
|
数据采集 前端开发 API
SurfGen爬虫:解析HTML与提取关键数据
SurfGen爬虫:解析HTML与提取关键数据
|
11天前
|
数据采集 监控 搜索推荐
深度解析淘宝商品详情API接口:解锁电商数据新维度,驱动业务增长
淘宝商品详情API接口,是淘宝开放平台为第三方开发者提供的一套用于获取淘宝、天猫等电商平台商品详细信息的应用程序接口。该接口涵盖了商品的基本信息(如标题、价格、图片)、属性参数、库存状况、销量评价、物流信息等,是电商企业实现商品管理、市场分析、营销策略制定等功能的得力助手。
|
6天前
|
人工智能 数据挖掘 API
淘宝评论与商品详情数据API接口的使用与应用
商品详情数据API:获取商品的基本信息(如标题、价格、库存、描述等)。 评论数据API:获取商品的用户评价数据(如评分、评论内容、用户昵称、购买时间等)。
|
9天前
|
XML API 开发者
使用 API 接口获取京东商品详情全解析
京东作为头部电商平台,其商品数据极具价值。开发者可通过API接口获取商品详情、订单数据等信息,满足各种业务需求。使用前需注册账号并创建应用获取App Key和App Secret。调用流程包括认证授权、构建请求、发送请求及处理响应。注意事项包括遵守平台规则、控制调用频率和确保数据时效性。通过这些步骤,可为电商数据分析提供有力支持。
|
21天前
|
搜索推荐 API 开发者
深度解析:利用商品详情 API 接口实现数据获取与应用
在电商蓬勃发展的今天,数据成为驱动业务增长的核心。商品详情API接口作为连接海量商品数据的桥梁,帮助运营者、商家和开发者获取精准的商品信息(如价格、描述、图片、评价等),优化策略、提升用户体验。通过理解API概念、工作原理及不同平台特点,掌握获取权限、构建请求、处理响应和错误的方法,可以将数据应用于商品展示、数据分析、竞品分析和个性化推荐等场景,助力电商创新与发展。未来,随着技术进步,API接口将与人工智能、大数据深度融合,带来更多变革。
62 3

热门文章

最新文章

推荐镜像

更多