亚马逊AWS官方博客

在 Amazon SageMaker Ground Truth 中简化 YOLO 对象检测的数据标记流程

Original Link: https://aws.amazon.com/cn/blogs/machine-learning/streamlining-data-labeling-for-yolo-object-detection-in-amazon-sagemaker-ground-truth/

对象检测属于计算机视觉(CV)领域的一类常见任务,就准确度与速度而言,YOLOv3模型是最先进的。在迁移学习中,您有一个由大型通用数据集训练而成的模型,您使用自定义数据集对其重新训练。迁移学习中一个最耗时的部分,就是收集并标记图像数据以生成自定义训练数据集。本文将探讨如何在Amazon SageMaker Ground Truth中实现这一部分。

Ground Truth提供一套全面的平台,用以注释计算机视觉当中最常见的数据标记作业:图像分类、对象检测、语义分割与实例分割。您可以使用Amazon Mechanical Turk中的外包人员进行标记,或建立内部团队进行协作标记。当然,您也可以选择AWS Marketplace上的第三方数据标记服务商。Ground Truth为您提供易于使用的直观界面,您可以通过界面上的示例及注释,与标记者就特定任务的实际需求进行沟通。

数据标记已是一项辛苦的工作。为计算机视觉建模任务创建训练数据,要求收集并存储数据、设置标记作业,再对经过标记的数据进行后期处理。此外,不同的对象检测模型所需要的数据格式也有所区别。例如,Faster RCNN模型需要使用流行的Pascal VOC格式,而YOLO模型却无法使用这种格式。任何一种计算机视觉机器学习管道都涉及这些环节。有时候,您需要多次运行管道以逐步改进模型。本文将向大家介绍如何使用Python脚本高效执行这些步骤,以及如何尽快训练模型。本文用例使用YOLO格式,但这些步骤大多与数据格式无关。

在生成训练数据的任务中,标记图像常常需要手工完成。本文展示了如何创建一个可重用的框架以创建用于高效建立模型的训练数据。具体操作步骤包括:

  • 启动Ground Truth作业之前,在Amazon S3中创建必要目录结构。
  • 创建一个私有的标记人员小组,然后启动Ground Truth作业。
  • 在标记完成之后,收集注释内容并以pandas dataframe格式将其保存。
  • 对数据集进行后期处理以用于模型训练。

您可以从GitHub repo下载文本中用到的代码。本文将演示如何在可访问AWS账户的本地计算机上通过AWS CLI命令行界面运行代码。关于设置AWS CLI的更多详细信息,请参阅AWS命令行界面是什么?请确保对CLI进行配置,使其能够访问本文中使用的S3存储桶。或者,您也可以在AWS Cloud9中运行,或在Amazon EC2实例上。您也可以在Amazon SageMaker notebook中运行这些代码。

如果您使用的是Amazon SageMaker notebook,您仍然可以访问底层EC2实例上的Linux Shell,接着从Jupyter主页打开一个新终端,从/home/ec2-user/SageMaker 文件夹运行脚本。

设置S3存储桶

您需要做的第一项任务,就是将训练图像上传至S3存储桶。将此存储桶命名为ground-truth-data-labeling。这里要求每一项标记任务都在此存储桶内拥有自己的独立文件夹。如果您最初只是标记保留在第一个文件夹内的一小批图像,但随后发现由于数据不足,模型在第一轮训练后表现不佳,则可以将更多图像上传至同一存储桶内的其他文件夹当中,而后启动另一个标记任务。

对于第一项标记任务,请创建bounding_box文件夹并在其中创建以下三个子文件夹:

  • images – 您应将Ground Truth标记作业中的所有图像上传至此子文件夹内。
  • ground_truth_annots – 此子文件夹最初为空白,Ground Truth作业会自动进行填充,您可以在这里检索到最终注释。
  • yolo_annot_files – 此子文件夹最初同样为空,最终存放用于训练模型的注释文件。脚本会自动进行填充此文件夹。

如果您的图像为.jpeg格式且在当前工作目录中可用,您可以使用以下代码上传图像:

aws s3 sync . s3://ground-truth-data-labeling/bounding_box/images/ –exclude “*” –include “*.jpg”

在本用例中,您使用五张图像。这些图像中共包含两类物体——铅笔与笔。您需要在图像中的各个物体周边绘制边界框。下图为您需要标记的示例,所有图像均可从GitHub repo中找到。

创建清单文件

Ground Truth作业需要一个JSON格式的清单文件才能正常运行,此文件中包含所有待标记的图像的Amazon S3路径。您需要先创建此文件,而后才能启动Ground Truth作业。此文件的格式非常简单:

{“source-ref”: < S3 path to image1 >}{“source-ref”: < S3 path to image2 >}…

但是,以手工方式为大量图像创建清单文件实在是繁琐。因此,您可以运行脚本以自动完成此流程。您首先需要创建一个包含了脚本所需的各项参数的文件。请使用以下内容在本地文件系统中创建文件input.json:

{   “s3_bucket”:”ground-truth-data-labeling”,   “job_id”:”bounding_box”,   “ground_truth_job_name”:”yolo-bbox”,   “yolo_output_dir”:”yolo_annot_files”}

将以下代码块保存在名为 prep_gt_job.py的文件当中:

import boto3import jsondef create_manifest(job_path):   “””   Creates the manifest file for the Ground Truth job   Input:   job_path: Full path of the folder in S3 for GT job   Returns:   manifest_file: The manifest file required for GT job   “””   s3_rec = boto3.resource(“s3”)   s3_bucket = job_path.split(“/”)[0]   prefix = job_path.replace(s3_bucket, “”)[1:]   image_folder = f”{prefix}/images”   print(f”using images from … {image_folder} \n”)   bucket = s3_rec.Bucket(s3_bucket)   objs = list(bucket.objects.filter(Prefix=image_folder))   img_files = objs[1:] # first item is the folder name   n_imgs = len(img_files)   print(f”there are {n_imgs} images \n”)   TOKEN = “source-ref”   manifest_file = “/tmp/manifest.json”   with open(manifest_file, “w”) as fout:       for img_file in img_files:           fname = f”s3://{s3_bucket}/{img_file.key}”           fout.write(f'{{“{TOKEN}”: “{fname}”}}\n’)    return manifest_file def upload_manifest(job_path, manifest_file):   “””   Uploads the manifest file into S3   Input:   job_path: Full path of the folder in S3 for GT job   manifest_file: Path to the local copy of the manifest file   “””   s3_rec = boto3.resource(“s3”)   s3_bucket = job_path.split(“/”)[0]   source = manifest_file.split(“/”)[-1]   prefix = job_path.replace(s3_bucket, “”)[1:]   destination = f”{prefix}/{source}”   print(f”uploading manifest file to {destination} \n”)   s3_rec.meta.client.upload_file(manifest_file, s3_bucket, destination) def main():   “””   Performs the following tasks:   1. Reads input from ‘input.json’   2. Collects image names from S3 and creates the manifest file for GT   3. Uploads the manifest file to S3   “””   with open(“input.json”) as fjson:       input_dict = json.load(fjson)   s3_bucket = input_dict[“s3_bucket”]   job_id = input_dict[“job_id”]   gt_job_path = f”{s3_bucket}/{job_id}”   man_file = create_manifest(gt_job_path)   upload_manifest(gt_job_path, man_file) if __name__ == “__main__”:   main()

运行以下脚本:

python prep_gt_job.py

此脚本将从输入文件内读取对应的S3存储桶与作业名称,创建一份images文件夹内可用图像的列表,创建manifest.json文件,并将此清单文件上传至S3存储桶 s3://ground-truth-data-labeling/bounding_box/内。

这种方法展示了以编程方式控制整个流程;当然,您也可以通过Ground Truth API创建文件。关于具体操作说明,请参阅创建Manifest文件

现在,S3存储桶内的文件夹结构应该如下所示:

ground-truth-data-labeling |– bounding_box   |– ground_truth_annots   |– images   |– yolo_annot_files   |– manifest.json

创建Ground Truth作业

您现在可以创建自己的Ground Truth作业了。您需要指定作业的详细信息与任务类型,并创建标记小组以及标记任务的具体细节。接下来,即可登录开始标记作业。

指定作业详情

要指定作业详情,请完成以下操作步骤:

  1. 在Amazon SageMaker控制台的Ground Truth之下, 选择 Labeling jobs

  1. Labeling jobs页面上, 选择 Create labeling job

  1. 在 Job overview部分的Job name处,输入yolo-bbox。其具体值应为前述input.json文件内定义的名称。
  2. Input Data Setup之下选择Pick Manual Data Setup 。
  3. Input dataset location部分,输入s3://ground-truth-data-labeling/bounding_box/manifest.json。
  4. Output dataset location部分,输入 s3://ground-truth-data-labeling/bounding_box/ground_truth_annots。

  1. 在 Create an IAM role部分,首先从下拉菜单中选择Create a new role,而后选择Specific S3 buckets
  2. 输入ground-truth-data-labeling

  1. 选择 Create

指定任务类型

要指定任务类型,请完成以下操作步骤:

  1. Task selection 部分,从Task Category下拉菜单中选择 Image
  2. 选择Bounding box

  1. 其中的Enable enhanced image access为默认勾选,请保留勾选状态。这启用跨源资源共享(CORS)机制,某些工作人员在注释工作当中可能需要使用这一机制。
  2. 选择 Next

创建标记人员小组

要创建标记人员小组,请完成以下操作步骤:

  1. 在 Workers部分,选择 Private
  2. 按照说明创建新小组。


团队中的每位成员都会收到一封带有初始登录凭证的通知电子邮件,标题为“You’re invited to work on a labeling project(邀请您参与标记项目)”。在本用例中,创建一个仅包含您自己的标记小组。

指定标记任务详情

在 Bounding box labeling tool部分,您应该可以看到已经上传的Amazon S3图像。您应该已经在之前的步骤中检查了路径是否正确。要指定任务详情,请完成以下操作步骤:

  1. 在文本框内,输入任务的简短描述。

如果数据标记团队的成员不止一位,而且您希望确保每位成员在绘制边框时都遵循相同的规则,这一描述非常关键。边界框创建过程中的任何不一致,都有可能令您的对象检测模型陷入混乱。例如,如果您要给饮料罐添加标签,且只希望在可见的徽标边上创建一个紧贴边框,而非包含整个罐体,您应该向所有标注人员明确这一要求来得到一致的标注。在本用例中,您输入“Please enter a tight bounding box around the entire object(请在整个物体周围输入一个紧贴的边界框)”。

  1. 作为可选项,您可以上传边界框的正确与错误示例。

通过提供正确与错误的示例,您确保您的团队在标记上统一一致。

  1. 在 Labels之下,为您用于识别各个边界框的标签输入名称;在本用例中,分别输入pencil 与 pen。

各个标签会自动被分配某个颜色,这有助于显示重合物体上的边框。

  1. 要运行最终健全性检查, 请选择 Preview

  1. 选择 Create job

整个作业创建可能需要几分钟。在完成之后,您会在Ground Truth Labeling jobs页面上看到一个名为yolo-bbox的作业,状态为“In progress”。

  1. 要查看作业详情,请选择该作业。

这也是验证路径正确与否的好时机。如果名称不一致,则脚本将无法正常运行。

关于提供标记说明的更多详细信息,请参阅为Amazon SageMaker Ground Truth标记作业创建高质量的说明

登录并开始标记

在收到初始证书以注册为作业的标记人员之后,请单击链接以重置密码并开始标记。

如果需要中断标记会话,您可以在SageMaker控制台上的Ground Truth下选择Labeling workforces以恢复标记作业。

您可以在Private选项卡上找到指向标记门户的链接。此页面还列出了参与此项内部标记任务的团队及个人。

在登录之后,选择Start working即可开始标记。

由于数据集中只有五张图像需要标记,因此您可以在单一会话中完成整个任务。对于规模较大的数据集,您可以选择Stop working以暂停任务,并随后返回完成任务。

检查作业状态

在标记完成之后,标记作业的状态将转换为Complete。在 s3://ground-truth-data-labeling/bounding_box/ground_truth_annots/yolo-bbox/manifests/output/output.manifest位置上出现一个新的名为output.manifest 的包含注释结果的JSON文件。

解析Ground Truth注释

现在,您可以解析注释内容并执行必要的后期处理步骤,确保可以使用其进行模型训练。首先请运行以下代码块:

from io import StringIOimport jsonimport s3fsimport boto3import pandas as pddef parse_gt_output(manifest_path, job_name):   “””   Captures the json Ground Truth bounding box annotations into a pandas dataframe   Input:   manifest_path: S3 path to the annotation file   job_name: name of the Ground Truth job   Returns:   df_bbox: pandas dataframe with bounding box coordinates             for each item in every image   “””   filesys = s3fs.S3FileSystem()   with filesys.open(manifest_path) as fin:       annot_list = []       for line in fin.readlines():           record = json.loads(line)           if job_name in record.keys(): # is it necessary?               image_file_path = record[“source-ref”]               image_file_name = image_file_path.split(“/”)[-1]               class_maps = record[f”{job_name}-metadata”][“class-map”]               imsize_list = record[job_name][“image_size”]               assert len(imsize_list) == 1               image_width = imsize_list[0][“width”]               image_height = imsize_list[0][“height”]                for annot in record[job_name][“annotations”]:                   left = annot[“left”]                   top = annot[“top”]                   height = annot[“height”]                   width = annot[“width”]                   class_name = class_maps[f'{annot[“class_id”]}’]                    annot_list.append(                       [                           image_file_name,                           class_name,                           left,                           top,                           height,                           width,                           image_width,                           image_height,                       ]                   )       df_bbox = pd.DataFrame(           annot_list,           columns=[               “img_file”,               “category”,               “box_left”,              “box_top”,               “box_height”,               “box_width”,               “img_width”,               “img_height”,           ],       )   return df_bbox def save_df_to_s3(df_local, s3_bucket, destination):   “””   Saves a pandas dataframe to S3   Input:   df_local: Dataframe to save   s3_bucket: Bucket name   destination: Prefix   “””   csv_buffer = StringIO()   s3_resource = boto3.resource(“s3”)   df_local.to_csv(csv_buffer, index=False)   s3_resource.Object(s3_bucket, destination).put(Body=csv_buffer.getvalue()) def main():   “””   Performs the following tasks:   1. Reads input from ‘input.json’   2. Parses the Ground Truth annotations and creates a dataframe   3. Saves the dataframe to S3   “””    with open(“input.json”) as fjson:       input_dict = json.load(fjson)   s3_bucket = input_dict[“s3_bucket”]   job_id = input_dict[“job_id”]   gt_job_name = input_dict[“ground_truth_job_name”]   mani_path = f”s3://{s3_bucket}/{job_id}/ground_truth_annots/{gt_job_name}/manifests/output/output.manifest”   df_annot = parse_gt_output(mani_path, gt_job_name)   dest = f”{job_id}/ground_truth_annots/{gt_job_name}/annot.csv”   save_df_to_s3(df_annot, s3_bucket, dest) if __name__ == “__main__”:   main()

在AWS CLI上,将以上代码块保存在parse_annot.py文件内并运行:

python parse_annot.py

Ground Truth将使用以下四个数字返回边界框信息:x与y坐标,以及边界框的高度与宽度。parse_gt_output 程序会扫描output.manifest文件,并将各个边界框的信息存储在pandas dataframe内。save_df_to_s3程序则将其以表格格式保存在S3存储桶的annot.csv 文件内以供后续处理。

这里之所以要创建dataframe,主要出于以下几个原因。首先,JSON文件难以阅读,而且output.manifest文件中包含的信息(例如标签元数据等)量超过我们在下一步需要的。因此,仅在dataframe内包含相关信息,您可以轻松查看确信一切正常。

要从Amazon S3获取annot.csv 文件并保存一份本地副本,请运行以下命令:

aws s3 cp s3://ground-truth-data-labeling/bounding_box/ground_truth_annots/yolo-bbox/annot.csv

您可以将其读取为pandas dataframe并检查前几行,具体参见以下代码:

import pandas as pddf_ann = pd.read_csv(‘annot.csv’)df_ann.head()

以下截屏所示为相关结果。

您还可以通过img_width 与 img_height捕捉图像大小。之所以需要进行这项操作,是因为对象检测模型需要了解图像中各个边界框的具体位置。在这种情况下,大家可以看到数据集内的图像是以4608 x 3456的分辨率捕捉的。

这里我们将注释信息保存到dataframe内,这种作法的好处包括:

  • 在后续步骤中,您需要将边界框坐标重新缩放为YOLO可读的格式。您可以在dataframe内轻松完成这项操作。
  • 如果您决定后续继续捕捉并标记更多图像以扩充现有数据集,则可以直接将新创建的dataframe与原有dataframe结合起来。再一次,您使用dataframe轻松完成。
  • 截至本文撰稿时,Ground Truth还无法通过控制台将超过30种不同类别的标签添加至同一作业内。如果您的数据集包含更多标签类别,则需要通过多个Ground Truth作业进行标记,然后合并他们。Ground Truth会将每个边界框关联到output.manifest文件中的一个整数索引。因此,如果您的标签类别超过30种,则各Ground Truth作业中的整数标签都是不同的。dataframe格式的注释使得合并他们更轻松,同时避免多个作业中不同类别的命名冲突。在以上的截图当中,可以看到您使用的是类别列下的实际名称,而非整数索引。

生成YOLO注释

现在,您可以重新格式化Ground Truth提供的边界框坐标,使其成为YOLO模型接受的格式。

在YOLO格式中,每个边界框都由框的中心坐标外加其宽度、高度进行描述。每个数字均按图像维度进行等比例缩放;因此,各数字均在0到1之间。YOLO模型期望使用相应的整数类别,而非类别名称。

因此,您需要将dataframe类别列中的各个名称映射为唯一的整数。此外,YOLOv3的官方 Darknet实现要求将图像名称与注释文本的文件名相匹配。例如,如果图像文件名为pic01.jpg,则相应的注释文件应命名为pic01.txt。

以下代码块执行上述这些任务:

import osimport jsonfrom io import StringIOimport boto3import s3fsimport pandas as pddef annot_yolo(annot_file, cats):   “””   Prepares the annotation in YOLO format   Input:   annot_file: csv file containing Ground Truth annotations   ordered_cats: List of object categories in proper order for model training   Returns:   df_ann: pandas dataframe with the following columns           img_file int_category box_center_w box_center_h box_width box_height   Note:   YOLO data format: <object-class> <x_center> <y_center> <width> <height>   “””   df_ann = pd.read_csv(annot_file)   df_ann[“int_category”] = df_ann[“category”].apply(lambda x: cats.index(x))   df_ann[“box_center_w”] = df_ann[“box_left”] + df_ann[“box_width”] / 2   df_ann[“box_center_h”] = df_ann[“box_top”] + df_ann[“box_height”] / 2   # 按图像尺寸缩放框尺寸   df_ann[“box_center_w”] = df_ann[“box_center_w”] / df_ann[“img_width”]   df_ann[“box_center_h”] = df_ann[“box_center_h”] / df_ann[“img_height”]   df_ann[“box_width”] = df_ann[“box_width”] / df_ann[“img_width”]   df_ann[“box_height”] = df_ann[“box_height”] / df_ann[“img_height”]   return df_anndef save_annots_to_s3(s3_bucket, prefix, df_local):   “””   For every image in the dataset, save a text file with annotation in YOLO format   Input:   s3_bucket: S3 bucket name   prefix: Folder name under s3_bucket where files will be written   df_local: pandas dataframe with the following columns             img_file int_category box_center_w box_center_h box_width box_height   “””   unique_images = df_local[“img_file”].unique()   s3_resource = boto3.resource(“s3”)   for image_file in unique_images:       df_single_img_annots = df_local.loc[df_local.img_file == image_file]       annot_txt_file = image_file.split(“.”)[0] + “.txt”       destination = f”{prefix}/{annot_txt_file}”       csv_buffer = StringIO()       df_single_img_annots.to_csv(           csv_buffer,           index=False,           header=False,           sep=” “,           float_format=”%.4f”,           columns=[               “int_category”,               “box_center_w”,               “box_center_h”,               “box_width”,               “box_height”,           ],       )       s3_resource.Object(s3_bucket, destination).put(Body=csv_buffer.getvalue()) def get_cats(json_file):   “””   Makes a list of the category names in proper order   Input:   json_file: s3 path of the json file containing the category information   Returns:   cats: List of category names   “””   filesys = s3fs.S3FileSystem()   with filesys.open(json_file) as fin:       line = fin.readline()       record = json.loads(line)       labels = [item[“label”] for item in record[“labels”]]   return labelsdef main():   “””   Performs the following tasks:   1. Reads input from ‘input.json’   2. Collect the category names from the Ground Truth job   3. Creates a dataframe with annotaion in YOLO format   4. Saves a text file in S3 with YOLO annotations       for each of the labeled images   “””   with open(“input.json”) as fjson:      input_dict = json.load(fjson)   s3_bucket = input_dict[“s3_bucket”]   job_id = input_dict[“job_id”]   gt_job_name = input_dict[“ground_truth_job_name”]   yolo_output = input_dict[“yolo_output_dir”]   s3_path_cats = (       f”s3://{s3_bucket}/{job_id}/ground_truth_annots/{gt_job_name}/annotation-tool/data.json”   )   categories = get_cats(s3_path_cats)   print(“\n labels used in Ground Truth job: “)   print(categories, “\n”)    gt_annot_file = “annot.csv”   s3_dir = f”{job_id}/{yolo_output}”   print(f”annotation files saved in = “, s3_dir)    df_annot = annot_yolo(gt_annot_file, categories)   save_annots_to_s3(s3_bucket, s3_dir, df_annot)if __name__ == “__main__”:

main()

在AWS CLI上,将以上代码块保存为create_annot.py文件并运行它:

python create_annot.py

其中annot_yolo程序通过按图像大小重新缩放框坐标来对您创建的dataframe进行转换;save_annots_to_s3程序则将与各个图像对应的注释保存至文本文件中,并将文本文件存储在Amazon S3。

现在,您可以检查几张图像及其对应注释,确保已经正常完成可用于模型训练的格式化。但是,您首先需要编写程序以在图像上绘制YOLO格式的边框。保存以下代码块在visualize.py文件中:

import matplotlib.pyplot as pltimport matplotlib.image as mpimgimport matplotlib.colors as mcolorsimport argparse def visualize_bbox(img_file, yolo_ann_file, label_dict, figure_size=(6, 8)):   “””   Plots bounding boxes on images   Input:   img_file : numpy.array   yolo_ann_file: Text file containing annotations in YOLO format   label_dict: Dictionary of image categories   figure_size: Figure size   “””   img = mpimg.imread(img_file)   fig, ax = plt.subplots(1, 1, figsize=figure_size)   ax.imshow(img)   im_height, im_width, _ = img.shape   palette = mcolors.TABLEAU_COLORS   colors = [c for c in palette.keys()]   with open(yolo_ann_file, “r”) as fin:       for line in fin:           cat, center_w, center_h, width, height = line.split()           cat = int(cat)           category_name = label_dict[cat]           left = (float(center_w) – float(width) / 2) * im_width           top = (float(center_h) – float(height) / 2) * im_height           width = float(width) * im_width           height = float(height) * im_height           rect = plt.Rectangle(               (left, top),               width,               height,               fill=False,               linewidth=2,               edgecolor=colors[cat],           )           ax.add_patch(rect)           props = dict(boxstyle=”round”, facecolor=colors[cat], alpha=0.5)           ax.text(               left,               top,               category_name,               fontsize=14,               verticalalignment=”top”,               bbox=props,           )    plt.show()def main():   “””   Plots bounding boxes   “””   labels = {0: “pen”, 1: “pencil”}   parser = argparse.ArgumentParser()   parser.add_argument(“img”, help=”image file”)   args = parser.parse_args()   img_file = args.img   ann_file = img_file.split(“.”)[0] + “.txt”   visualize_bbox(img_file, ann_file, labels, figure_size=(6, 8))if __name__ == “__main__”:   main()

从Amazon S3中下载图像以及相应的注释文件。具体参见以下代码:

aws s3 cp s3://ground-truth-data-labeling/bounding_box/yolo_annot_files/IMG_20200816_205004.txt .

aws s3 cp s3://ground-truth-data-labeling/bounding_box/images/IMG_20200816_205004.jpg .

要显示每个边界框的正确标签,您需要指定标记在字典中的对象名称,并将其传递给visualize_bbox。在本用例中,列表中只包含两项。但标签的顺序非常重要,应该与您创建Ground Truth标记作业时使用的顺序相匹配。如果您不太确定具体顺序,可以访问Amazon S3当中的 s3://data-labeling-ground-truth/bounding_box/ground_truth_annots/bbox-yolo/annotation-tool/data.json文件,此文件由Ground Truth作业自动创建。

data.json文件中的内容类似于以下代码:

{“document-version”:”2018-11-28″,”labels”:[{“label”:”pencil”},{“label”:”pen”}]}

这样,在 visualize.py中创建了包含以下标签的字典:

labels = {0: ‘pencil’, 1: ‘pen’}

现在运行以下代码查看图像:

python visualize.py IMG_20200816_205004.jpg

下列截图是正确对两支笔绘制的边界框。

要使用笔与铅笔对图像进行混合绘制,请从Amazon S3处获取图像以及相应的注释文本。具体参见以下代码:

aws s3 cp s3://ground-truth-data-labeling/bounding_box/yolo_annot_files/IMG_20200816_205029.txt .    aws s3 cp s3://ground-truth-data-labeling/bounding_box/images/IMG_20200816_205029.jpg .

将visualize_bbox程序中的默认图像大小覆盖为(10,12),而后运行下列代码:

python visualize.py IMG_20200816_205029.jpg

下列截图是根据两种物体类型正确绘制出的四个边界框。

总结

本文介绍了如何在Amazon Ground Truth中为对象检测模型创建高效的端到端数据收集管道。您可以在创建对象检测模型时亲自体验整个操作过程。您也可以修改后期处理注释,以Pascal VOC格式生成带有标签的数据,可用于Faster RCNN等模型。您还可以在适当修改之后,将这套基本框架应用于其他特定于不同作业需求的数据标记管道。例如,您可以重写注释后处理过程改造框架用于实例分割任务,即对各类对象进行像素级标记,而不是本文示例中在对象周边绘制矩形。Amazon Ground Truth还会定期更新增强功能。请查阅说明文档以获取最新功能。

本篇作者

申绍勇

申绍勇是AWS资深解决方案架构师,主要负责基于AWS的云计算解决方案进行架构咨询和设计,目前服务移动互联网(包含媒体、游戏、广告、电商、区块链等)、金融、制造业等各行业客户,提供有关云计算、AI、大数据、物联网、高性能计算等各类云计算解决方案的咨询和架构设计。

本篇作者

Arkajyoti Misra

AWS专业服务团队数据科学家。他热衷于研究机器学习算法,喜欢阅读关于深度学习新领域的技术文章。