

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用清单文件导入图像
<a name="md-create-dataset-ground-truth"></a>

您可以使用 Amazon A SageMaker I Ground Truth 格式的清单文件创建数据集。你可以使用 Amazon A SageMaker I Ground Truth 任务中的清单文件。如果您的图像和标签不是 SageMaker AI Ground Truth 清单文件的格式，则可以创建 A SageMaker I 格式的清单文件并使用它来导入已贴标签的图像。

`CreateDataset` 操作已更新，允许您在创建新数据集时选择性地指定标签。标签是键值对，可用于对资源进行分类和管理。

**Topics**
+ [使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）](#md-create-dataset-ground-truth-console)
+ [使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集](#md-create-dataset-ground-truth-sdk)
+ [创建数据集请求](#create-dataset-ground-truth-request)
+ [使用 Amazon A SageMaker I Ground Truth 作业为图片加标签](md-create-dataset-ground-truth-job.md)
+ [创建清单文件](md-create-manifest-file.md)
+ [在清单文件中导入图像级标签](md-create-manifest-file-classification.md)
+ [清单文件中的物体定位](md-create-manifest-file-object-detection.md)
+ [清单文件的验证规则](md-create-manifest-file-validation-rules.md)
+ [将其他数据集格式转换为清单文件](md-converting-to-sm-format.md)

## 使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）
<a name="md-create-dataset-ground-truth-console"></a>

以下过程向您展示如何使用 SageMaker AI Ground Truth 格式的清单文件创建数据集。

1. 通过执行下列操作之一，为训练数据集创建清单文件：
   + 按照中的说明创建包含 A SageMaker I GroundTruth Job 的清单文件[使用 Amazon A SageMaker I Ground Truth 作业为图片加标签](md-create-dataset-ground-truth-job.md)。
   + 按照[创建清单文件](md-create-manifest-file.md)中的说明创建您自己的清单文件。

   如果要创建测试数据集，请重复步骤 1 以创建测试数据集。

1. 打开亚马逊 Rekognition 控制台，网址为[https://console.aws.amazon.com/rekognition/](https://console.aws.amazon.com/rekognition/)。

1. 选择**使用自定义标签**。

1. 选择**开始**。

1. 在左侧导航窗格中，选择**项目**。

1. 在**项目**页面上，选择要向其添加数据集的项目。此时将显示项目的详细信息页面。

1. 选择**创建数据集**。此时将显示**创建数据集**页面。

1. 在**开始配置**中，选择**从单个数据集开始**或**从训练数据集开始**。要创建更高质量的模型，建议从单独的训练和测试数据集开始。

------
#### [ Single dataset ]

   1. 在**训练数据集详细信息**部分，选择**导入 SageMaker由 Ground Truth 标注的图像**。

   1. 在 **.manifest 文件位置**中，输入您在步骤 1 中创建的清单文件的位置。

   1. 选择**创建数据集**。这时会打开项目的数据集页面。

------
#### [ Separate training and test datasets ]

   1. 在**训练数据集详细信息**部分，选择**导入 SageMaker由 Ground Truth 标注的图像**。

   1. 在 **.manifest 文件位置**中，输入您在步骤 1 中创建的训练数据集清单文件的位置。

   1. 在**测试数据集详细信息**部分，选择**导入 SageMaker 由 Ground Truth 标注的图像**。
**注意**  
训练数据集和测试数据集可以有不同的图像源。

   1. 在 **.manifest 文件位置**中，输入您在步骤 1 中创建的测试数据集清单文件的位置。

   1. 选择**创建数据集**。这时会打开项目的数据集页面。

------

1. 如果需要添加或更改标签，请执行[标注图像](md-labeling-images.md)中的操作。

1. 按照[训练模型（控制台）](training-model.md#tm-console)中的步骤训练您的模型。

## 使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集
<a name="md-create-dataset-ground-truth-sdk"></a>

以下过程向您展示如何使用 [CreateDataset](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_CreateDataset)API 从清单文件创建训练或测试数据集。

您可以使用现有的清单文件，例如 [SageMaker AI Ground Truth 任务](md-create-dataset-ground-truth-job.md)的输出，也可以创建自己的[清单文件](md-create-manifest-file.md)。

1. 如果您尚未这样做，请安装并配置 AWS CLI 和 AWS SDKs。有关更多信息，请参阅 [步骤 4：设置 AWS CLI 和 AWS SDKs](su-awscli-sdk.md)。

1. 通过执行下列操作之一，为训练数据集创建清单文件：
   + 按照中的说明创建包含 A SageMaker I GroundTruth Job 的清单文件[使用 Amazon A SageMaker I Ground Truth 作业为图片加标签](md-create-dataset-ground-truth-job.md)。
   + 按照[创建清单文件](md-create-manifest-file.md)中的说明创建您自己的清单文件。

   如果要创建测试数据集，请重复步骤 2 以创建测试数据集。

1. 使用以下示例代码创建训练和测试数据集。

------
#### [ AWS CLI ]

   使用以下代码创建数据集。替换以下内容：
   + `project_arn`：要添加测试数据集的项目的 ARN。
   + `type`：要创建的数据集的类型（TRAIN 或 TEST）
   + `bucket`：包含数据集清单文件的存储桶。
   + `manifest_file`：清单文件的路径和文件名。

   ```
   aws rekognition create-dataset --project-arn project_arn \
     --dataset-type type \
     --dataset-source '{ "GroundTruthManifest": { "S3Object": { "Bucket": "bucket", "Name": "manifest_file" } } }' \
     --profile custom-labels-access
     --tags '{"key1": "value1", "key2": "value2"}'
   ```

------
#### [ Python ]

   使用以下值创建数据集。提供以下命令行参数：
   + `project_arn`：要添加测试数据集的项目的 ARN。
   + `dataset_type`：要创建的数据集的类型（`train` 或 `test`）。
   + `bucket`：包含数据集清单文件的存储桶。
   + `manifest_file`：清单文件的路径和文件名。

   ```
   #Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
   #PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-custom-labels-developer-guide/blob/master/LICENSE-SAMPLECODE.)
   
   
   import argparse
   import logging
   import time
   import json
   import boto3
   from botocore.exceptions import ClientError
   
   logger = logging.getLogger(__name__)
   
   def create_dataset(rek_client, project_arn, dataset_type, bucket, manifest_file):
       """
       Creates an Amazon Rekognition Custom Labels dataset.
       :param rek_client: The Amazon Rekognition Custom Labels Boto3 client.
       :param project_arn: The ARN of the project in which you want to create a dataset.
       :param dataset_type: The type of the dataset that you want to create (train or test).
       :param bucket: The S3 bucket that contains the manifest file.
       :param manifest_file: The path and filename of the manifest file.
       """
   
       try:
           #Create the project
           logger.info("Creating %s dataset for project %s",dataset_type, project_arn)
   
           dataset_type = dataset_type.upper()
   
           dataset_source = json.loads(
               '{ "GroundTruthManifest": { "S3Object": { "Bucket": "'
               + bucket
               + '", "Name": "'
               + manifest_file
               + '" } } }'
           )
   
           response = rek_client.create_dataset(
               ProjectArn=project_arn, DatasetType=dataset_type, DatasetSource=dataset_source
           )
   
           dataset_arn=response['DatasetArn']
   
           logger.info("dataset ARN: %s",dataset_arn)
   
           finished=False
           while finished is False:
   
               dataset=rek_client.describe_dataset(DatasetArn=dataset_arn)
   
               status=dataset['DatasetDescription']['Status']
               
               if status == "CREATE_IN_PROGRESS":
                   logger.info("Creating dataset: %s ",dataset_arn)
                   time.sleep(5)
                   continue
   
               if status == "CREATE_COMPLETE":
                   logger.info("Dataset created: %s", dataset_arn)
                   finished=True
                   continue
   
               if status == "CREATE_FAILED":
                   error_message = f"Dataset creation failed: {status} : {dataset_arn}"
                   logger.exception(error_message)
                   raise Exception (error_message)
                   
               error_message = f"Failed. Unexpected state for dataset creation: {status} : {dataset_arn}"
               logger.exception(error_message)
               raise Exception(error_message)
               
           return dataset_arn
      
       
       except ClientError as err:
           logger.exception("Couldn't create dataset: %s",err.response['Error']['Message'])
           raise
   
   def add_arguments(parser):
       """
       Adds command line arguments to the parser.
       :param parser: The command line parser.
       """
   
       parser.add_argument(
           "project_arn", help="The ARN of the project in which you want to create the dataset."
       )
   
       parser.add_argument(
           "dataset_type", help="The type of the dataset that you want to create (train or test)."
       )
   
       parser.add_argument(
           "bucket", help="The S3 bucket that contains the manifest file."
       )
       
       parser.add_argument(
           "manifest_file", help="The path and filename of the manifest file."
       )
   
   
   def main():
   
       logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
   
       try:
   
           #Get command line arguments.
           parser = argparse.ArgumentParser(usage=argparse.SUPPRESS)
           add_arguments(parser)
           args = parser.parse_args()
   
           print(f"Creating {args.dataset_type} dataset for project {args.project_arn}")
   
           #Create the dataset.
           session = boto3.Session(profile_name='custom-labels-access')
           rekognition_client = session.client("rekognition")
   
           dataset_arn=create_dataset(rekognition_client, 
               args.project_arn,
               args.dataset_type,
               args.bucket,
               args.manifest_file)
   
           print(f"Finished creating dataset: {dataset_arn}")
   
   
       except ClientError as err:
           logger.exception("Problem creating dataset: %s", err)
           print(f"Problem creating dataset: {err}")
   
   
   
   if __name__ == "__main__":
       main()
   ```

------
#### [ Java V2 ]

   使用以下值创建数据集。提供以下命令行参数：
   + `project_arn`：要添加测试数据集的项目的 ARN。
   + `dataset_type`：要创建的数据集的类型（`train` 或 `test`）。
   + `bucket`：包含数据集清单文件的存储桶。
   + `manifest_file`：清单文件的路径和文件名。

   ```
   /*
      Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
      SPDX-License-Identifier: Apache-2.0
   */
   
   package com.example.rekognition;
   
   import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
   import software.amazon.awssdk.regions.Region;
   import software.amazon.awssdk.services.rekognition.RekognitionClient;
   import software.amazon.awssdk.services.rekognition.model.CreateDatasetRequest;
   import software.amazon.awssdk.services.rekognition.model.CreateDatasetResponse;
   import software.amazon.awssdk.services.rekognition.model.DatasetDescription;
   import software.amazon.awssdk.services.rekognition.model.DatasetSource;
   import software.amazon.awssdk.services.rekognition.model.DatasetStatus;
   import software.amazon.awssdk.services.rekognition.model.DatasetType;
   import software.amazon.awssdk.services.rekognition.model.DescribeDatasetRequest;
   import software.amazon.awssdk.services.rekognition.model.DescribeDatasetResponse;
   import software.amazon.awssdk.services.rekognition.model.GroundTruthManifest;
   import software.amazon.awssdk.services.rekognition.model.RekognitionException;
   import software.amazon.awssdk.services.rekognition.model.S3Object;
   
   import java.util.logging.Level;
   import java.util.logging.Logger;
   
   public class CreateDatasetManifestFiles {
   
       public static final Logger logger = Logger.getLogger(CreateDatasetManifestFiles.class.getName());
   
       public static String createMyDataset(RekognitionClient rekClient, String projectArn, String datasetType,
               String bucket, String name) throws Exception, RekognitionException {
   
           try {
   
               logger.log(Level.INFO, "Creating {0} dataset for project : {1} from s3://{2}/{3} ",
                       new Object[] { datasetType, projectArn, bucket, name });
   
               DatasetType requestDatasetType = null;
   
               switch (datasetType) {
               case "train":
                   requestDatasetType = DatasetType.TRAIN;
                   break;
               case "test":
                   requestDatasetType = DatasetType.TEST;
                   break;
               default:
                   logger.log(Level.SEVERE, "Could not create dataset. Unrecognized dataset type: {0}", datasetType);
                   throw new Exception("Could not create dataset. Unrecognized dataset type: " + datasetType);
   
               }
   
               GroundTruthManifest groundTruthManifest = GroundTruthManifest.builder()
                       .s3Object(S3Object.builder().bucket(bucket).name(name).build()).build();
   
               DatasetSource datasetSource = DatasetSource.builder().groundTruthManifest(groundTruthManifest).build();
   
               CreateDatasetRequest createDatasetRequest = CreateDatasetRequest.builder().projectArn(projectArn)
                       .datasetType(requestDatasetType).datasetSource(datasetSource).build();
   
               CreateDatasetResponse response = rekClient.createDataset(createDatasetRequest);
   
               boolean created = false;
   
               do {
   
                   DescribeDatasetRequest describeDatasetRequest = DescribeDatasetRequest.builder()
                           .datasetArn(response.datasetArn()).build();
                   DescribeDatasetResponse describeDatasetResponse = rekClient.describeDataset(describeDatasetRequest);
   
                   DatasetDescription datasetDescription = describeDatasetResponse.datasetDescription();
   
                   DatasetStatus status = datasetDescription.status();
   
                   logger.log(Level.INFO, "Creating dataset ARN: {0} ", response.datasetArn());
   
                   switch (status) {
   
                   case CREATE_COMPLETE:
                       logger.log(Level.INFO, "Dataset created");
                       created = true;
                       break;
   
                   case CREATE_IN_PROGRESS:
                       Thread.sleep(5000);
                       break;
   
                   case CREATE_FAILED:
                       String error = "Dataset creation failed: " + datasetDescription.statusAsString() + " "
                               + datasetDescription.statusMessage() + " " + response.datasetArn();
                       logger.log(Level.SEVERE, error);
                       throw new Exception(error);
   
                   default:
                       String unexpectedError = "Unexpected creation state: " + datasetDescription.statusAsString() + " "
                               + datasetDescription.statusMessage() + " " + response.datasetArn();
                       logger.log(Level.SEVERE, unexpectedError);
                       throw new Exception(unexpectedError);
                   }
   
               } while (created == false);
   
               return response.datasetArn();
   
           } catch (RekognitionException e) {
               logger.log(Level.SEVERE, "Could not create dataset: {0}", e.getMessage());
               throw e;
           }
   
       }
   
       public static void main(String[] args) {
   
           String datasetType = null;
           String bucket = null;
           String name = null;
           String projectArn = null;
           String datasetArn = null;
   
           final String USAGE = "\n" + "Usage: " + "<project_arn> <dataset_type> <dataset_arn>\n\n" + "Where:\n"
                   + "   project_arn - the ARN of the project that you want to add copy the datast to.\n\n"
                   + "   dataset_type - the type of the dataset that you want to create (train or test).\n\n"
                   + "   bucket - the S3 bucket that contains the manifest file.\n\n"
                   + "   name - the location and name of the manifest file within the bucket.\n\n";
   
           if (args.length != 4) {
               System.out.println(USAGE);
               System.exit(1);
           }
   
           projectArn = args[0];
           datasetType = args[1];
           bucket = args[2];
           name = args[3];
   
           try {
   
               // Get the Rekognition client
               RekognitionClient rekClient = RekognitionClient.builder()
                   .credentialsProvider(ProfileCredentialsProvider.create("custom-labels-access"))
                   .region(Region.US_WEST_2)
                   .build();
   
   
                // Create the dataset
               datasetArn = createMyDataset(rekClient, projectArn, datasetType, bucket, name);
   
               System.out.println(String.format("Created dataset: %s", datasetArn));
   
               rekClient.close();
   
           } catch (RekognitionException rekError) {
               logger.log(Level.SEVERE, "Rekognition client error: {0}", rekError.getMessage());
               System.exit(1);
           } catch (Exception rekError) {
               logger.log(Level.SEVERE, "Error: {0}", rekError.getMessage());
               System.exit(1);
           }
   
       }
   
   }
   ```

------

1. 如果需要添加或更改标签，请参阅[管理标签 (SDK)](md-labels.md#md-labels-sdk)。

1. 按照[训练模型（SDK）](training-model.md#tm-sdk)中的步骤训练您的模型。

## 创建数据集请求
<a name="create-dataset-ground-truth-request"></a>

 以下是 CreateDataset 操作请求的格式：

```
{
"DatasetSource": {
"DatasetArn": "string",
"GroundTruthManifest": {
"S3Object": {
"Bucket": "string",
"Name": "string",
"Version": "string"
}
}
},
"DatasetType": "string",
"ProjectArn": "string",
"Tags": {
"string": "string"
}
}
```

# 使用 Amazon A SageMaker I Ground Truth 作业为图片加标签
<a name="md-create-dataset-ground-truth-job"></a>

借助 SageMaker Amazon AI Ground Truth，你可以使用来自你选择的供应商公司 Amazon Mechanical Turk 的工作人员，也可以使用内部私人员工以及允许你创建一组带标签的图像的机器学习。亚马逊 Rekognition 自定义标签会从你指定的亚马逊 S3 存储桶中导入 SageMaker AI Ground Truth 清单文件。

亚马逊 Rekognition 自定义标签支持以下 A SageMaker I Ground Truth 任务。
+ [图像分类](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-image-classification.html)
+ [边界框](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-bounding-box.html)

导入的文件包括图像和清单文件。清单文件中包含导入的图像的标签和边界框信息。

Amazon Rekognition 需要具有访问存储图像的 Amazon S3 存储桶的权限。如果使用的是 Amazon Rekognition Custom Labels 为您设置的控制台存储桶，则所需权限已设置完毕。如果使用的不是控制台存储桶，请参阅[访问外部 Amazon S3 存储桶](su-console-policy.md#su-external-buckets)。

## 使用 SageMaker AI Ground Truth 任务创建清单文件（控制台）
<a name="md-create-dataset-ground-truth-job-console"></a>

以下过程向您展示如何使用由 SageMaker AI Ground Truth 作业标记的图像来创建数据集。该作业的输出文件存储在您的 Amazon Rekognition Custom Labels 控制台存储桶中。<a name="create-dataset-procedure-ground-truth"></a>

**使用由 SageMaker AI Ground Truth 作业标记的图像创建数据集（控制台）**

1. 登录 AWS 管理控制台 并打开 Amazon S3 控制台，网址为[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在控制台存储桶中，[创建一个文件夹](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-folder.html)来存放训练图像。
**注意**  
控制台存储桶是在您首次在某个地区打开 Amazon Rekognition 自定义标签控制台时创建的。 AWS 有关更多信息，请参阅 [管理 Amazon Rekognition Custom Labels 项目](managing-project.md)。

1. [上传图像](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)至您刚才创建的文件夹。

1. 在控制台存储桶中，创建一个文件夹来存放 Ground Truth 作业的输出。

1. 打开 SageMaker AI 控制台，网址为[https://console.aws.amazon.com/sagemaker/](https://console.aws.amazon.com/sagemaker/)。

1. 创建 Ground Truth 标注作业。您需要将 Amazon S3 URLs 用于您在步骤 2 和步骤 4 中创建的文件夹。有关更多信息，请参阅[使用 Amazon G SageMaker round Truth 进行数据标签](https://docs.aws.amazon.com/sagemaker/latest/dg/sms.html)。

1. 记下 `output.manifest` 文件在步骤 4 中创建的文件夹中的位置。它应该位于子文件夹 `Ground-Truth-Job-Name/manifests/output` 中。

1. 按照[使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console)中的说明，使用上传的清单文件创建数据集。对于步骤 8，在 **.manifest 文件位置**中，输入您在上一步中记下的该位置的 Amazon S3 URL。如果您使用的是 AWS SDK，请这样做[使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。

1. 重复步骤 1-6，为您的测试数据集创建 SageMaker AI Ground Truth 作业。

# 创建清单文件
<a name="md-create-manifest-file"></a>

您可以通过导入 SageMaker AI Ground Truth 格式的清单文件来创建测试或训练数据集。如果您的图像的标签格式不是 SageMaker AI Ground Truth 清单文件，请使用以下信息创建 SageMaker AI Ground Truth 格式的清单文件。

清单文件采用 [JSON 行](http://jsonlines.org)格式，其中的每一行都是一个代表图像标注信息的完整 JSON 对象。亚马逊 Rekognition 自定义标签支持带有以下格式的 JSON 行的 SageMaker AI Ground Truth 清单：
+ [分类作业输出](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-data-output.html#sms-output-class)：用于向图像添加图像级标签。图像级标签定义了图像上的场景、概念或物体（如果不需要物体位置信息）的类别。一张图像可以有多个图像级标签。有关更多信息，请参阅 [在清单文件中导入图像级标签](md-create-manifest-file-classification.md)。
+ [边界框作业输出](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-data-output.html#sms-output-box)：用于标注图像上一个或多个物体的类别和位置。有关更多信息，请参阅 [清单文件中的物体定位](md-create-manifest-file-object-detection.md)。

图像级和定位（边界框）JSON 行可在同一个清单文件中链接在一起。

**注意**  
本部分的 JSON 行示例为便于阅读调整了格式。

当您导入清单文件时，Amazon Rekognition Custom Labels 会应用关于限制、语法和语义的验证规则。有关更多信息，请参阅 [清单文件的验证规则](md-create-manifest-file-validation-rules.md)。

清单文件引用的图像必须位于同一 Amazon S3 存储桶中。清单文件与图像可以位于不同于的 Amazon S3 存储桶中。您应在 JSON 行的 `source-ref` 字段中指定图像的位置。

Amazon Rekognition 需要具有访问存储图像的 Amazon S3 存储桶的权限。如果使用的是 Amazon Rekognition Custom Labels 为您设置的控制台存储桶，则所需权限已设置完毕。如果使用的不是控制台存储桶，请参阅[访问外部 Amazon S3 存储桶](su-console-policy.md#su-external-buckets)。

**Topics**
+ [创建清单文件](#md-create-manifest-file-console)

## 创建清单文件
<a name="md-create-manifest-file-console"></a>

以下过程创建包含训练和测试数据集的项目。这些数据集是从您创建的训练和测试清单文件创建的。

<a name="create-dataset-procedure-manifest-file"></a>

**使用 SageMaker AI Ground Truth 格式的清单文件创建数据集（控制台）**

1. 在控制台存储桶中，[创建一个文件夹](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-folder.html)来存放清单文件。

1. 在控制台存储桶中，创建一个文件夹来存放图像。

1. 上传图像至您刚才创建的文件夹。

1. 为您的训练数据集创建 A SageMaker I Ground Truth 格式的清单文件。有关更多信息，请参阅[在清单文件中导入图像级标签](md-create-manifest-file-classification.md)和[清单文件中的物体定位](md-create-manifest-file-object-detection.md)。
**重要**  
每个 JSON 行中的 `source-ref` 字段值必须映射到您上传的一张图像。

1. 为您的测试数据集创建 SageMaker AI Ground Truth 格式的清单文件。

1. [上传清单文件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)至您刚才创建的文件夹。

1. 记下清单文件的位置。

1. 按照[使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console)中的说明，使用上传的清单文件创建数据集。对于步骤 8，在 **.manifest 文件位置**中，输入您在上一步中记下的该位置的 Amazon S3 URL。如果您使用的是 AWS SDK，请这样做[使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。

# 在清单文件中导入图像级标签
<a name="md-create-manifest-file-classification"></a>

要导入图像级标签（标有场景、概念或不需要本地化信息的对象的图像），可以将 SageMaker AI Ground Truth 分类[作业输出](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-data-output.html#sms-output-class)格式 JOB 行添加到清单文件中。清单文件由一个或多个 JSON 行组成，每个行对应一张您要导入的图像。

**提示**  
为了简化清单文件的创建，我们提供了从 CSV 文件创建清单文件的 Python 脚本。有关更多信息，请参阅 [从 CSV 文件创建清单文件](ex-csv-manifest.md)。

**创建图像级标签的清单文件**

1. 创建一个空文本文件。

1. 为要导入的每张图像各添加一个 JSON 行。每个 JSON 行应该与下面类似。

   ```
   {"source-ref":"s3://custom-labels-console-us-east-1-nnnnnnnnnn/gt-job/manifest/IMG_1133.png","TestCLConsoleBucket":0,"TestCLConsoleBucket-metadata":{"confidence":0.95,"job-name":"labeling-job/testclconsolebucket","class-name":"Echo Dot","human-annotated":"yes","creation-date":"2020-04-15T20:17:23.433061","type":"groundtruth/image-classification"}}
   ```

1. 保存该文件。您可以使用扩展名 `.manifest`，但不要求必须如此。

1. 使用您创建的清单文件，创建一个数据集。有关更多信息，请参阅 [使用 SageMaker AI Ground Truth 格式的清单文件创建数据集（控制台）](md-create-manifest-file.md#create-dataset-procedure-manifest-file)。

 

## 图像级 JSON 行
<a name="md-manifest-classification-json"></a>

在本部分中，我们将介绍如何为单张图像创建 JSON 行。请考虑以下图像。下图的场景可能叫做 *Sunrise*。

![\[落日时分的湖面，有一个码头和几艘小船，周围群山环绕。\]](http://docs.aws.amazon.com/zh_cn/rekognition/latest/customlabels-dg/images/sunrise.png)


上面这张包含 *Sunrise* 场景的图像的 JSON 行可能如下所示。

```
{
    "source-ref": "s3://bucket/images/sunrise.png",
    "testdataset-classification_Sunrise": 1,
    "testdataset-classification_Sunrise-metadata": {
        "confidence": 1,
        "job-name": "labeling-job/testdataset-classification_Sunrise",
        "class-name": "Sunrise",
        "human-annotated": "yes",
        "creation-date": "2020-03-06T17:46:39.176",
        "type": "groundtruth/image-classification"
    }
}
```

请注意以下信息。

### source-ref
<a name="w2aac20c17c25c27c19c11c13"></a>

（必需）图像的 Amazon S3 位置。格式为 `"s3://BUCKET/OBJECT_PATH"`。所导入数据集中的图像必须存储在同一 Amazon S3 存储桶中。

### *testdataset-classification\$1Sunrise*
<a name="w2aac20c17c25c27c19c11c15"></a>

（必需）标签属性。您选择的字段名称。该字段的值（在前面的示例中为 1）是标签属性的标识符。Amazon Rekognition Custom Labels 不使用它，它可以是任何整数值。必须有相应的元数据，这些元数据通过字段名称进行标识，并附有 *-metadata*。例如 `"testdataset-classification_Sunrise-metadata"`。

### *testdataset-classification\$1Sunrise*-元数据
<a name="w2aac20c17c25c27c19c11c17"></a>

（必需）与标签属性相关的元数据。该字段名称必须与标签属性附加 *-metadata* 之后相同。

*confidence*  
（必需）Amazon Rekognition Custom Labels 目前未使用该属性，但必须为其提供介于 0 和 1 之间的值。

*job-name*  
（可选）您为用于处理图像的作业选择的名称。

*class-name*  
（必需）您为适用于图像的场景或概念选择的类别名称。例如 `"Sunrise"`。

*human-annotated*  
（必需）如果注释由人工完成，请指定 `"yes"`。否则为 `"no"`。

*creation-date*   
（必需）创建标签的协调世界时 (UTC) 日期和时间。

*type*  
（必需）应该应用于图像的处理类型。对于图像级标签，该值为 `"groundtruth/image-classification"`。

### 为图像添加多个图像级标签
<a name="md-dataset-purpose-classification-multiple-labels"></a>

可以为图像添加多个标签。例如，以下 JSON 为单个图像添加两个标签：*football* 和 *ball*。

```
{
    "source-ref": "S3 bucket location", 
    "sport0":0, # FIRST label
    "sport0-metadata": { 
        "class-name": "football", 
        "confidence": 0.8, 
        "type":"groundtruth/image-classification", 
        "job-name": "identify-sport", 
        "human-annotated": "yes", 
        "creation-date": "2018-10-18T22:18:13.527256" 
    },
    "sport1":1, # SECOND label
    "sport1-metadata": { 
        "class-name": "ball", 
        "confidence": 0.8, 
        "type":"groundtruth/image-classification", 
        "job-name": "identify-sport", 
        "human-annotated": "yes", 
        "creation-date": "2018-10-18T22:18:13.527256" 
    }
}  # end of annotations for 1 image
```

# 清单文件中的物体定位
<a name="md-create-manifest-file-object-detection"></a>

通过将 SageMaker AI Ground Truth [Box Job Output 格式 JOB](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-data-output.html#sms-output-box) 行添加到清单文件中，你可以导入标有对象定位信息的图像。

定位信息表示物体在图像上的位置。该位置由围绕物体的边界框表示。边界框结构包含边界框的左上角坐标和边界框的宽度与高度。边界框格式的 JSON 行包含图像上一个或多个物体的位置的边界框以及图像上每个物体的类别。

清单文件由一个或多个 JSON 行组成，每行包含单张图像的信息。

**创建物体定位的清单文件**

1. 创建一个空文本文件。

1. 为要导入的每张图像各添加一个 JSON 行。每个 JSON 行应该与下面类似。

   ```
   {"source-ref": "s3://bucket/images/IMG_1186.png", "bounding-box": {"image_size": [{"width": 640, "height": 480, "depth": 3}], "annotations": [{ "class_id": 1,	"top": 251,	"left": 399, "width": 155, "height": 101}, {"class_id": 0, "top": 65, "left": 86, "width": 220,	"height": 334}]}, "bounding-box-metadata": {"objects": [{ "confidence": 1}, {"confidence": 1}],	"class-map": {"0": "Echo",	"1": "Echo Dot"}, "type": "groundtruth/object-detection", "human-annotated": "yes",	"creation-date": "2013-11-18T02:53:27", "job-name": "my job"}}
   ```

1. 保存该文件。您可以使用扩展名 `.manifest`，但不要求必须如此。

1. 使用您刚才创建的文件创建数据集。有关更多信息，请参阅 [使用 SageMaker AI Ground Truth 格式的清单文件创建数据集（控制台）](md-create-manifest-file.md#create-dataset-procedure-manifest-file)。



## 物体边界框 JSON 行
<a name="md-manifest-object-localization-json"></a>

在本部分中，我们将介绍如何为单张图像创建 JSON 行。下图显示了 Amazon Echo 和 Amazon Echo Dot 设备周围的边界框。

![\[木质表面上有两个 Amazon 智能扬声器，一个带有绿色边界框，另一个带有蓝色边界框。\]](http://docs.aws.amazon.com/zh_cn/rekognition/latest/customlabels-dg/images/echos.png)


以下是上面这张图像的边界框 JSON 行。

```
{
	"source-ref": "s3://custom-labels-bucket/images/IMG_1186.png",
	"bounding-box": {
		"image_size": [{
			"width": 640,
			"height": 480,
			"depth": 3
		}],
		"annotations": [{
			"class_id": 1,
			"top": 251,
			"left": 399,
			"width": 155,
			"height": 101
		}, {
			"class_id": 0,
			"top": 65,
			"left": 86,
			"width": 220,
			"height": 334
		}]
	},
	"bounding-box-metadata": {
		"objects": [{
			"confidence": 1
		}, {
			"confidence": 1
		}],
		"class-map": {
			"0": "Echo",
			"1": "Echo Dot"
		},
		"type": "groundtruth/object-detection",
		"human-annotated": "yes",
		"creation-date": "2013-11-18T02:53:27",
		"job-name": "my job"
	}
}
```

请注意以下信息。

### source-ref
<a name="cd-manifest-source-ref"></a>

（必需）图像的 Amazon S3 位置。格式为 `"s3://BUCKET/OBJECT_PATH"`。所导入数据集中的图像必须存储在同一 Amazon S3 存储桶中。

### *bounding-box*
<a name="md-manifest-source-bounding-box"></a>

（必需）标签属性。您选择的字段名称。包含图像大小和图像中检测到的每个物体的边界框。必须有相应的元数据，这些元数据通过字段名称进行标识，并附有 *-metadata*。例如 `"bounding-box-metadata"`。

*image\$1size*  
（必需）包含图像大小（以像素为单位）的单个元素数组。  
+ *height*：（必需）图像的高度（以像素为单位）。
+ *width*：（必需）图像的深度（以像素为单位）。
+ *depth*：（必需）图像的通道数。对于 RGB 图像，该值为 3。Amazon Rekognition Custom Labels 目前未使用该属性，但必须为其提供一个值。

*annotations*  
（必需）图像中检测到的每个物体的边界框信息数组。  
+ *class\$1id*：（必需）映射到 *class-map* 中的标签。在上面的示例中，*class\$1id* 为 `1` 的物体是图像中的 Echo Dot。
+ *top*：（必需）从图像顶部到边界框顶部的距离（以像素为单位）。
+ *left*：（必需）从图像左侧到边界框左侧的距离（以像素为单位）。
+ *width*：（必需）边界框的宽度（以像素为单位）。
+ *height*：（必需）边界框的高度（以像素为单位）。

### *bounding-box*-元数据
<a name="md-manifest-source-bounding-box-metadata"></a>

（必需）与标签属性相关的元数据。该字段名称必须与标签属性附加 *-metadata* 之后相同。图像中检测到的每个物体的边界框信息数组。

*Objects*  
（必需）图像中的物体数组。按索引映射到 *annotations* 数组。Amazon Rekognition Custom Labels 不使用 confidence 属性。

*class-map*  
（必需）适用于图像中检测到的物体的类别映射。

*type*  
（必需）分类作业的类型。`"groundtruth/object-detection"` 将作业标识为物体检测。

*creation-date*   
（必需）创建标签的协调世界时 (UTC) 日期和时间。

*human-annotated*  
（必需）如果注释由人工完成，请指定 `"yes"`。否则为 `"no"`。

*job-name*  
（可选）处理图像的作业的名称。

# 清单文件的验证规则
<a name="md-create-manifest-file-validation-rules"></a>

 当您导入清单文件时，Amazon Rekognition Custom Labels 会应用关于限制、语法和语义的验证规则。 SageMaker AI Ground Truth 架构强制执行语法验证。有关更多信息，请参阅[输出](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-data-output.html)。以下是限制和语义的验证规则。

**注意**  
所有验证规则累计遵循 20% 的无效规则。如果由于任意组合（例如 15% 的无效 JSON 和 15% 的无效图像）导致导入超过 20% 的限制，则导入将失败。
每个数据集对象都对应于清单中的一行。空行/无效行也算作数据集对象。
重叠度为（测试和训练之间的共用标签数）/（训练标签数）。

**Topics**
+ [限制](#md-validation-rules-limits)
+ [语义](#md-validation-rules-semantics)

## 限制
<a name="md-validation-rules-limits"></a>


| 验证 | 限制 | 出现错误 | 
| --- | --- | --- | 
|  清单文件大小  |  最大 1 GB  |  错误  | 
|  清单文件的最大行数  |  一个清单中最多可以包含 250,000 个数据集对象行。  |  错误  | 
|  每个标签的有效数据集对象总数的下限   |  >=1  |  错误  | 
|  标签数下限  |  >=2  |  错误  | 
|  标签数上限  |  <=250  |  错误  | 
|  每张图像的最小边界框数  |  0  |  无  | 
|  每张图像的最大边界框数  |  50  |  无  | 

## 语义
<a name="md-validation-rules-semantics"></a>




| 验证 | 限制 | 出现错误 | 
| --- | --- | --- | 
|  空清单  |    |  错误  | 
|  source-ref 对象丢失/无法访问  |  对象数量小于 20%  |  警告  | 
|  source-ref 对象丢失/无法访问  |  对象数量 > 20%  |  错误  | 
|  训练数据集中不存在测试标签   |  标签中至少有 50% 的重叠  |  错误  | 
|  在数据集中混合标签与同一标签的对象示例。针对同一类别在数据集对象中进行分类和检测。  |    |  没有错误或警告  | 
|  测试与训练之间的重叠资产   |  测试数据集与训练数据集之间不应有重叠。  |    | 
|  数据集中的图像必须来自同一个存储桶   |  如果对象位于不同的存储桶中，则会出错  |  错误  | 

# 将其他数据集格式转换为清单文件
<a name="md-converting-to-sm-format"></a>

您可以使用以下信息从各种源数据集格式创建 SageMaker Amazon AI 格式的清单文件。创建清单文件后，即可使用它来创建数据集。有关更多信息，请参阅 [使用清单文件导入图像](md-create-dataset-ground-truth.md)。

**Topics**
+ [将 COCO 数据集转换为清单文件格式](md-transform-coco.md)
+ [转换多标签 SageMaker AI Ground Truth 清单文件](md-gt-cl-transform.md)
+ [从 CSV 文件创建清单文件](ex-csv-manifest.md)

# 将 COCO 数据集转换为清单文件格式
<a name="md-transform-coco"></a>

[COCO](http://cocodataset.org/#home) 是一种用于指定大规模物体检测、分段和字幕数据集的格式。此 Python [示例](md-coco-transform-example.md)说明了如何将 COCO 物体检测格式的数据集转换为 Amazon Rekognition Custom Labels [边界框格式的清单文件](md-create-manifest-file-object-detection.md)。本部分还提供了可用于编写自己的代码的信息。

COCO 格式的 JSON 文件由五个部分组成，提供了*整个数据集*的信息。有关更多信息，请参阅 [COCO 数据集格式](md-coco-overview.md)。
+ `info`：有关数据集的一般信息。
+ `licenses `：数据集中图像的许可信息。
+ [`images`](md-coco-overview.md#md-coco-images)：数据集中图像的列表。
+ [`annotations`](md-coco-overview.md#md-coco-annotations)：数据集中所有图像中存在的注释（包括边界框）的列表。
+ [`categories`](md-coco-overview.md#md-coco-categories)：标签类别列表。

您需要来自 `images`、`annotations` 和 `categories` 列表的信息，才能创建 Amazon Rekognition Custom Labels 清单文件。

Amazon Rekognition Custom Labels 清单文件采用 JSON 行格式，其中每行都包含了*一张图像上*的一个或多个物体的边界框和标签信息。有关更多信息，请参阅 [清单文件中的物体定位](md-create-manifest-file-object-detection.md)。

## 将 COCO 对象映射到自定义标签 JSON 行
<a name="md-mapping-coco"></a>

要转换 COCO 格式的数据集，需要将 COCO 数据集映射到 Amazon Rekognition Custom Labels 清单文件以进行物体定位。有关更多信息，请参阅 [清单文件中的物体定位](md-create-manifest-file-object-detection.md)。要为每张图片构建 JSON 行，清单文件需要映射 COCO 数据集`image`和`category`对象字段 IDs。`annotation`

下面是一个 COCO 清单文件示例。有关更多信息，请参阅 [COCO 数据集格式](md-coco-overview.md)。

```
{
    "info": {
        "description": "COCO 2017 Dataset","url": "http://cocodataset.org","version": "1.0","year": 2017,"contributor": "COCO Consortium","date_created": "2017/09/01"
    },
    "licenses": [
        {"url": "http://creativecommons.org/licenses/by/2.0/","id": 4,"name": "Attribution License"}
    ],
    "images": [
        {"id": 242287, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/xxxxxxxxxxxx.jpg", "flickr_url": "http://farm3.staticflickr.com/2626/xxxxxxxxxxxx.jpg", "width": 426, "height": 640, "file_name": "xxxxxxxxx.jpg", "date_captured": "2013-11-15 02:41:42"},
        {"id": 245915, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/nnnnnnnnnnnn.jpg", "flickr_url": "http://farm1.staticflickr.com/88/xxxxxxxxxxxx.jpg", "width": 640, "height": 480, "file_name": "nnnnnnnnnn.jpg", "date_captured": "2013-11-18 02:53:27"}
    ],
    "annotations": [
        {"id": 125686, "category_id": 0, "iscrowd": 0, "segmentation": [[164.81, 417.51,......167.55, 410.64]], "image_id": 242287, "area": 42061.80340000001, "bbox": [19.23, 383.18, 314.5, 244.46]},
        {"id": 1409619, "category_id": 0, "iscrowd": 0, "segmentation": [[376.81, 238.8,........382.74, 241.17]], "image_id": 245915, "area": 3556.2197000000015, "bbox": [399, 251, 155, 101]},
        {"id": 1410165, "category_id": 1, "iscrowd": 0, "segmentation": [[486.34, 239.01,..........495.95, 244.39]], "image_id": 245915, "area": 1775.8932499999994, "bbox": [86, 65, 220, 334]}
    ],
    "categories": [
        {"supercategory": "speaker","id": 0,"name": "echo"},
        {"supercategory": "speaker","id": 1,"name": "echo dot"}
    ]
}
```

下图显示了*数据集*的 COCO 数据集列表如何映射到图像的 Amazon Rekognition Custom Labels JSON 行。图像的每个 JSON 行都有一个 source-ref、作业和作业元数据字段。匹配的颜色表示单张图像的信息。请注意，在清单中，一张图像可能有多个注释和元数据/类别。

![\[图中显示 COCO 清单的结构，其中包含图像、注释和类别。\]](http://docs.aws.amazon.com/zh_cn/rekognition/latest/customlabels-dg/images/coco-transform.png)


**获取单个 JSON 行的 COCO 对象**

1. 对于图像列表中的每张图像，从注释列表中获取注释，其中注释字段 `image_id` 的值与图像 `id` 字段匹配。

1. 对于步骤 1 中匹配的每个注释，请通读 `categories` 列表并获取 `category` 字段 `id` 的值与 `annotation` 对象 `category_id` 字段匹配的每个 `category`。

1. 使用匹配的 `image`、`annotation` 和 `category` 对象为图像创建 JSON 行。要映射字段，请参阅[将 COCO 对象字段映射到自定义标签 JSON 行对象字段](#md-mapping-fields-coco)。

1. 重复步骤 1-3，直到为 `image` 列表中的每个 `images` 对象创建 JSON 行。

有关示例代码，请参阅[转换 COCO 数据集](md-coco-transform-example.md)。

## 将 COCO 对象字段映射到自定义标签 JSON 行对象字段
<a name="md-mapping-fields-coco"></a>

确定 Amazon Rekognition Custom Labels JSON 行的 COCO 对象后，需要将 COCO 对象字段映射到相应的 Amazon Rekognition Custom Labels JSON 行对象字段。以下示例 Amazon Rekognition Custom Labels JSON 行将一张图像 (`id`=`000000245915`) 映射到上面的 COCO JSON 示例。请注意以下信息。
+ `source-ref` 是图像在 Amazon S3 存储桶中的位置。如果 COCO 图像不是存储在 Amazon S3 存储桶中，则需要将它们移到 Amazon S3 存储桶中。
+ `annotations` 列表中包含了图像上每个物体的 `annotation` 对象。`annotation` 对象包含边界框信息（`top`、`left`、`width`、`height`）和标签标识符 (`class_id`)。
+ 标签标识符 (`class_id`) 映射到元数据中的 `class-map` 列表。该列表会列出图像上使用的标签。

```
{
	"source-ref": "s3://custom-labels-bucket/images/000000245915.jpg",
	"bounding-box": {
		"image_size": {
			"width": 640,
			"height": 480,
			"depth": 3
		},
		"annotations": [{
			"class_id": 0,
			"top": 251,
			"left": 399,
			"width": 155,
			"height": 101
		}, {
			"class_id": 1,
			"top": 65,
			"left": 86,
			"width": 220,
			"height": 334
		}]
	},
	"bounding-box-metadata": {
		"objects": [{
			"confidence": 1
		}, {
			"confidence": 1
		}],
		"class-map": {
			"0": "Echo",
			"1": "Echo Dot"
		},
		"type": "groundtruth/object-detection",
		"human-annotated": "yes",
		"creation-date": "2018-10-18T22:18:13.527256",
		"job-name": "my job"
	}
}
```

按照以下信息将 Amazon Rekognition Custom Labels 清单文件字段映射到 COCO 数据集 JSON 字段。

### source-ref
<a name="md-source-ref-coco"></a>

图像位置的 S3 格式 URL。该图像必须存储在 S3 存储桶中。有关更多信息，请参阅 [source-ref](md-create-manifest-file-object-detection.md#cd-manifest-source-ref)。如果 `coco_url` COCO 字段指向 S3 存储桶位置，则可以使用 `coco_url` 的值作为 `source-ref` 的值。或者，也可以将 `source-ref` 映射到 `file_name` (COCO) 字段，然后在转换代码中将所需的 S3 路径添加到图像的存储位置。

### *bounding-box*
<a name="md-label-attribute-id-coco"></a>

您选择的标签属性名称。有关更多信息，请参阅 [*bounding-box*](md-create-manifest-file-object-detection.md#md-manifest-source-bounding-box)。

#### image\$1size
<a name="md-image-size-coco"></a>

图像大小（以像素为单位）。映射到 [images](md-coco-overview.md#md-coco-images) 列表中的 `image` 对象。
+ `height`-> `image.height`
+ `width`-> `image.width`
+ `depth`：Amazon Rekognition Custom Labels 未使用该属性，但必须为其提供一个值。

#### annotations
<a name="md-annotations-coco"></a>

`annotation` 对象的列表。图像上的每个物体都有一个 `annotation`。

#### annotation
<a name="md-annotation-coco"></a>

包含图像上物体的一个实例的边界框信息。
+ `class_id`：映射到自定义标签的 `class-map` 列表的数字 ID。
+ `top` -> `bbox[1]`
+ `left` -> `bbox[0]`
+ `width` -> `bbox[2]`
+ `height` -> `bbox[3]`

### *bounding-box*-元数据
<a name="md-metadata-coco"></a>

标签属性的元数据。包含标签和标签标识符。有关更多信息，请参阅 [*bounding-box*-元数据](md-create-manifest-file-object-detection.md#md-manifest-source-bounding-box-metadata)。

#### Objects
<a name="cd-metadata-objects-coco"></a>

图像中的物体数组。按索引映射到 `annotations` 列表。

##### Object
<a name="cd-metadata-object-coco"></a>
+ Amazon Rekognition Custom Labels 未使用该属性，但必须为其指定值 (1)。

#### class-map
<a name="md-metadata-class-map-coco"></a>

适用于图像中检测到的物体的标签（类别）映射。映射到 [categories](md-coco-overview.md#md-coco-categories) 列表中的 category 对象。
+ `id` -> `category.id`
+ `id value` -> `category.name`

#### 类型
<a name="md-type-coco"></a>

必须是 `groundtruth/object-detection`

#### human-annotated
<a name="md-human-annotated-coco"></a>

指定 `yes` 或 `no`。有关更多信息，请参阅 [*bounding-box*-元数据](md-create-manifest-file-object-detection.md#md-manifest-source-bounding-box-metadata)。

#### creation-date -> [image](md-coco-overview.md#md-coco-images).date\$1captured
<a name="md-creation-date-coco"></a>

图像的创建日期和时间。映射到 COCO 图像列表中的图像的 [image](md-coco-overview.md#md-coco-images).date\$1captured 字段。Amazon Rekognition Custom Labels 期望的 `creation-date` 格式为 *Y-M-DTH:M:S*。

#### job-name
<a name="md-job-name-coco"></a>

您选择的作业名称。

# COCO 数据集格式
<a name="md-coco-overview"></a>

COCO 数据集由五个信息部分组成，提供了整个数据集的信息。COCO 物体检测数据集的格式记录在 [COCO 数据格式](http://cocodataset.org/#format-data)中。
+ info：有关数据集的一般信息。
+ licenses：数据集中图像的许可信息。
+ [images](#md-coco-images)：数据集中图像的列表。
+ [annotations](#md-coco-annotations)：数据集中所有图像中存在的注释（包括边界框）的列表。
+ [categories](#md-coco-categories)：标签类别列表。

要创建自定义标签清单，需要使用 COCO 清单文件中的 `images`、`annotations` 和 `categories` 列表。其他两个部分（`info`、`licences`）不是必需的。下面是一个 COCO 清单文件示例。

```
{
    "info": {
        "description": "COCO 2017 Dataset","url": "http://cocodataset.org","version": "1.0","year": 2017,"contributor": "COCO Consortium","date_created": "2017/09/01"
    },
    "licenses": [
        {"url": "http://creativecommons.org/licenses/by/2.0/","id": 4,"name": "Attribution License"}
    ],
    "images": [
        {"id": 242287, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/xxxxxxxxxxxx.jpg", "flickr_url": "http://farm3.staticflickr.com/2626/xxxxxxxxxxxx.jpg", "width": 426, "height": 640, "file_name": "xxxxxxxxx.jpg", "date_captured": "2013-11-15 02:41:42"},
        {"id": 245915, "license": 4, "coco_url": "http://images.cocodataset.org/val2017/nnnnnnnnnnnn.jpg", "flickr_url": "http://farm1.staticflickr.com/88/xxxxxxxxxxxx.jpg", "width": 640, "height": 480, "file_name": "nnnnnnnnnn.jpg", "date_captured": "2013-11-18 02:53:27"}
    ],
    "annotations": [
        {"id": 125686, "category_id": 0, "iscrowd": 0, "segmentation": [[164.81, 417.51,......167.55, 410.64]], "image_id": 242287, "area": 42061.80340000001, "bbox": [19.23, 383.18, 314.5, 244.46]},
        {"id": 1409619, "category_id": 0, "iscrowd": 0, "segmentation": [[376.81, 238.8,........382.74, 241.17]], "image_id": 245915, "area": 3556.2197000000015, "bbox": [399, 251, 155, 101]},
        {"id": 1410165, "category_id": 1, "iscrowd": 0, "segmentation": [[486.34, 239.01,..........495.95, 244.39]], "image_id": 245915, "area": 1775.8932499999994, "bbox": [86, 65, 220, 334]}
    ],
    "categories": [
        {"supercategory": "speaker","id": 0,"name": "echo"},
        {"supercategory": "speaker","id": 1,"name": "echo dot"}
    ]
}
```

## 图像列表
<a name="md-coco-images"></a>

COCO 数据集引用的图像列在图像数组中。每个图像对象都包含了有关该图像的信息，例如图像文件名。在以下示例图像对象中，请注意以下信息以及创建 Amazon Rekognition Custom Labels 清单文件需要哪些字段。
+ `id`：（必需）图像的唯一标识符。`id` 字段映射到注释数组（存储边界框信息的地方）中的 `id` 字段。
+ `license`：（非必需）映射到许可证数组。
+ `coco_url`：（可选）图像的位置。
+ `flickr_url`：（非必需）图像在 Flickr 上的位置。
+ `width`：（必需）图像的宽度。
+ `height`：（必需）图像的高度。
+ `file_name`：（必需）图像文件名。在本示例中，`file_name` 与 `id` 匹配，但 COCO 数据集对此不作要求。
+ `date_captured`：（必需）图像拍摄的日期和时间。

```
{
    "id": 245915,
    "license": 4,
    "coco_url": "http://images.cocodataset.org/val2017/nnnnnnnnnnnn.jpg",
    "flickr_url": "http://farm1.staticflickr.com/88/nnnnnnnnnnnnnnnnnnn.jpg",
    "width": 640,
    "height": 480,
    "file_name": "000000245915.jpg",
    "date_captured": "2013-11-18 02:53:27"
}
```

## 注释（边界框）列表
<a name="md-coco-annotations"></a>

所有图像上的所有物体的边界框信息都存储在注释列表中。单个注释对象包含单个物体的边界框信息以及该物体在图像上的标签。图像上物体的每个实例都有一个注释对象。

在以下示例中，请注意以下信息以及创建 Amazon Rekognition Custom Labels 清单文件需要哪些字段。
+ `id`：（非必需）注释的标识符。
+ `image_id`：（必需）对应于图像数组中的图像 `id`。
+ `category_id`：（必需）用于标识边界框内物体的标签的标识符。它映射到类别数组的 `id` 字段。
+ `iscrowd`：（非必需）指定图像中是否包含物体群。
+ `segmentation`：（非必需）图像中物体的分段信息。Amazon Rekognition Custom Labels 不支持分段。
+ `area`：（非必需）注释的区域。
+ `bbox`：（必需）包含图像中物体的边界框的坐标（以像素为单位）。

```
{
    "id": 1409619,
    "category_id": 1,
    "iscrowd": 0,
    "segmentation": [
        [86.0, 238.8,..........382.74, 241.17]
    ],
    "image_id": 245915,
    "area": 3556.2197000000015,
    "bbox": [86, 65, 220, 334]
}
```

## 类别列表
<a name="md-coco-categories"></a>

标签信息存储在类别数组中。在以下示例类别对象中，请注意以下信息以及创建 Amazon Rekognition Custom Labels 清单文件需要哪些字段。
+ `supercategory`：（非必需）标签的父类别。
+ `id`：（必需）标签标识符。`id` 字段映射到 `annotation` 对象中的 `category_id` 字段。在以下示例中，echo dot 的标识符为 2。
+ `name`：（必需）标签名称。

```
        {"supercategory": "speaker","id": 2,"name": "echo dot"}
```

# 转换 COCO 数据集
<a name="md-coco-transform-example"></a>

使用以下 Python 示例将边界框信息从 COCO 格式的数据集转换为 Amazon Rekognition Custom Labels 清单文件。该代码会将创建的清单文件上载到您的 Amazon S3 存储桶。该代码还提供了一个 AWS CLI 命令，您可以使用该命令上传您的图像。

**转换 COCO 数据集 (SDK)**

1. 如果您尚未执行以下操作，请：

   1. 确保您具有 `AmazonS3FullAccess` 权限。有关更多信息，请参阅 [设置 SDK 权限](su-sdk-permissions.md)。

   1. 安装并配置 AWS CLI 和 AWS SDKs。有关更多信息，请参阅 [步骤 4：设置 AWS CLI 和 AWS SDKs](su-awscli-sdk.md)。

1. 使用以下 Python 代码转换 COCO 数据集。设置以下值。
   + `s3_bucket`：要在其中存储图像和 Amazon Rekognition Custom Labels 清单文件的 S3 存储桶的名称。
   + `s3_key_path_images`：S3 存储桶 (`s3_bucket`) 中将要放置图像的位置的路径。
   + `s3_key_path_manifest_file`：S3 存储桶 (`s3_bucket`) 中将要放置自定义标签清单文件的位置的路径。
   + `local_path`：示例打开输入 COCO 数据集并保存新的自定义标签清单文件的位置的本地路径。
   + `local_images_path`：要用于训练的图像的本地路径。
   + `coco_manifest`：输入 COCO 数据集的文件名。
   + `cl_manifest_file`：该示例创建的清单文件的名称。该文件保存在 `local_path` 指定的位置。按照惯例，该文件具有扩展名 `.manifest`，但这不是必需要求的。
   + `job_name`：自定义标签作业的名称。

   ```
   import json
   import os
   import random
   import shutil
   import datetime
   import botocore
   import boto3
   import PIL.Image as Image
   import io
   
   #S3 location for images
   s3_bucket = 'bucket'
   s3_key_path_manifest_file = 'path to custom labels manifest file/'
   s3_key_path_images = 'path to images/'
   s3_path='s3://' + s3_bucket  + '/' + s3_key_path_images
   s3 = boto3.resource('s3')
   
   #Local file information
   local_path='path to input COCO dataset and output Custom Labels manifest/'
   local_images_path='path to COCO images/'
   coco_manifest = 'COCO dataset JSON file name'
   coco_json_file = local_path + coco_manifest
   job_name='Custom Labels job name'
   cl_manifest_file = 'custom_labels.manifest'
   
   label_attribute ='bounding-box'
   
   open(local_path + cl_manifest_file, 'w').close()
   
   # class representing a Custom Label JSON line for an image
   class cl_json_line:  
       def __init__(self,job, img):  
   
           #Get image info. Annotations are dealt with seperately
           sizes=[]
           image_size={}
           image_size["width"] = img["width"]
           image_size["depth"] = 3
           image_size["height"] = img["height"]
           sizes.append(image_size)
   
           bounding_box={}
           bounding_box["annotations"] = []
           bounding_box["image_size"] = sizes
   
           self.__dict__["source-ref"] = s3_path + img['file_name']
           self.__dict__[job] = bounding_box
   
           #get metadata
           metadata = {}
           metadata['job-name'] = job_name
           metadata['class-map'] = {}
           metadata['human-annotated']='yes'
           metadata['objects'] = [] 
           date_time_obj = datetime.datetime.strptime(img['date_captured'], '%Y-%m-%d %H:%M:%S')
           metadata['creation-date']= date_time_obj.strftime('%Y-%m-%dT%H:%M:%S') 
           metadata['type']='groundtruth/object-detection'
           
           self.__dict__[job + '-metadata'] = metadata
   
   
   print("Getting image, annotations, and categories from COCO file...")
   
   with open(coco_json_file) as f:
   
       #Get custom label compatible info    
       js = json.load(f)
       images = js['images']
       categories = js['categories']
       annotations = js['annotations']
   
       print('Images: ' + str(len(images)))
       print('annotations: ' + str(len(annotations)))
       print('categories: ' + str(len (categories)))
   
   
   print("Creating CL JSON lines...")
       
   images_dict = {image['id']: cl_json_line(label_attribute, image) for image in images}
   
   print('Parsing annotations...')
   for annotation in annotations:
   
       image=images_dict[annotation['image_id']]
   
       cl_annotation = {}
       cl_class_map={}
   
       # get bounding box information
       cl_bounding_box={}
       cl_bounding_box['left'] = annotation['bbox'][0]
       cl_bounding_box['top'] = annotation['bbox'][1]
    
       cl_bounding_box['width'] = annotation['bbox'][2]
       cl_bounding_box['height'] = annotation['bbox'][3]
       cl_bounding_box['class_id'] = annotation['category_id']
   
       getattr(image, label_attribute)['annotations'].append(cl_bounding_box)
   
   
       for category in categories:
            if annotation['category_id'] == category['id']:
               getattr(image, label_attribute + '-metadata')['class-map'][category['id']]=category['name']
           
       
       cl_object={}
       cl_object['confidence'] = int(1)  #not currently used by Custom Labels
       getattr(image, label_attribute + '-metadata')['objects'].append(cl_object)
   
   print('Done parsing annotations')
   
   # Create manifest file.
   print('Writing Custom Labels manifest...')
   
   for im in images_dict.values():
   
       with open(local_path+cl_manifest_file, 'a+') as outfile:
               json.dump(im.__dict__,outfile)
               outfile.write('\n')
               outfile.close()
   
   # Upload manifest file to S3 bucket.
   print ('Uploading Custom Labels manifest file to S3 bucket')
   print('Uploading'  + local_path + cl_manifest_file + ' to ' + s3_key_path_manifest_file)
   print(s3_bucket)
   s3 = boto3.resource('s3')
   s3.Bucket(s3_bucket).upload_file(local_path + cl_manifest_file, s3_key_path_manifest_file + cl_manifest_file)
   
   # Print S3 URL to manifest file,
   print ('S3 URL Path to manifest file. ')
   print('\033[1m s3://' + s3_bucket + '/' + s3_key_path_manifest_file + cl_manifest_file + '\033[0m') 
   
   # Display aws s3 sync command.
   print ('\nAWS CLI s3 sync command to upload your images to S3 bucket. ')
   print ('\033[1m aws s3 sync ' + local_images_path + ' ' + s3_path + '\033[0m')
   ```

1. 运行该代码。

1. 在程序输出中，记下 `s3 sync` 命令。您在下一个步骤中需要用到它。

1. 在命令提示符处，运行 `s3 sync` 命令。您的图像将上传到 S3 存储桶。如果该命令在上传过程中失败，请再次运行它，直到您的本地图像与 S3 存储桶同步为止。

1. 在程序输出中，记下清单文件的 S3 URL 路径。您在下一个步骤中需要用到它。

1. 按照[使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console)中的说明，使用上传的清单文件创建数据集。对于步骤 8，在 **.manifest 文件位置**中，输入您在上一步中记下的 Amazon S3 URL。如果使用的是 AWS SDK，请执行[使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。

# 转换多标签 SageMaker AI Ground Truth 清单文件
<a name="md-gt-cl-transform"></a>

本主题向您展示如何将多标签 Amazon A SageMaker I Ground Truth 清单文件转换为亚马逊 Rekognition 自定义标签格式的清单文件。

SageMaker 多标签作业的 AI Ground Truth 清单文件的格式与 Amazon Rekognition 自定义标签格式清单文件的格式不同。多标签分类是指将一个图像分类为一组类别，但可能同时属于多个类别。在这种情况下，该图像可能会有多个标签（多标签），例如 *football* 和 *ball*。

有关多标签 SageMaker AI Ground Truth 作业的信息，请参阅[图像分类（多标签](https://docs.aws.amazon.com/sagemaker/latest/dg/sms-image-classification-multilabel.html)）。有关多标签格式的 Amazon Rekognition Custom Labels 清单文件的信息，请参阅[为图像添加多个图像级标签](md-create-manifest-file-classification.md#md-dataset-purpose-classification-multiple-labels)。

## 获取 A SageMaker I Ground Truth 任务的清单文件
<a name="md-get-gt-manifest"></a>

以下过程向您展示了如何获取 Amazon A SageMaker I Ground Truth 任务的输出清单文件 (`output.manifest`)。您可以将 `output.manifest` 用作下一过程的输入。

**下载 A SageMaker I Ground Truth 任务清单文件**

1. 打开 [https://console.aws.amazon.com/sagemaker/](https://console.aws.amazon.com/sagemaker/)。

1. 在导航窗格中，选择 **Ground Truth**，然后选择**标注作业**。

1. 选择包含要使用的清单文件的标注作业。

1. 在详细信息页面上，选择**输出数据集位置**下的链接。Amazon S3 控制台将在数据集所在位置打开。

1. 依次选择 `Manifests`、`output` 和 `output.manifest`。

1. 选择**对象操作**，然后选择**下载**，下载清单文件。

## 转换多标签 SageMaker AI 清单文件
<a name="md-transform-ml-gt"></a>

以下过程根据现有的多标签格式 AI 清单文件创建多标签格式 Amazon Rekognition 自定义标签清单文件。 SageMaker GroundTruth

**注意**  
要运行此代码，您需要使用 Python 版本 3 或更高版本。<a name="md-procedure-multi-label-transform"></a>

**转换多标签 SageMaker AI 清单文件**

1. 运行以下 Python 代码。提供您在[获取 A SageMaker I Ground Truth 任务的清单文件](#md-get-gt-manifest)中创建的清单文件名称作为命令行参数。

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier:  Apache-2.0
   """
   Purpose
   Shows how to create and Amazon Rekognition Custom Labels format
   manifest file from an Amazon SageMaker Ground Truth Image
   Classification (Multi-label) format manifest file.
   """
   import json
   import logging
   import argparse
   import os.path
   
   logger = logging.getLogger(__name__)
   
   def create_manifest_file(ground_truth_manifest_file):
       """
       Creates an Amazon Rekognition Custom Labels format manifest file from
       an Amazon SageMaker Ground Truth Image Classification (Multi-label) format
       manifest file.
       :param: ground_truth_manifest_file: The name of the Ground Truth manifest file,
       including the relative path.
       :return: The name of the new Custom Labels manifest file.
       """
   
       logger.info('Creating manifest file from %s', ground_truth_manifest_file)
       new_manifest_file = f'custom_labels_{os.path.basename(ground_truth_manifest_file)}'
   
       # Read the SageMaker Ground Truth manifest file into memory.
       with open(ground_truth_manifest_file) as gt_file:
           lines = gt_file.readlines()
   
       #Iterate through the lines one at a time to generate the
       #new lines for the Custom Labels manifest file.
       with open(new_manifest_file, 'w') as the_new_file:
           for line in lines:
               #job_name - The of the Amazon Sagemaker Ground Truth job.
               job_name = ''
               # Load in the old json item from the Ground Truth manifest file
               old_json = json.loads(line)
   
               # Get the job name
               keys = old_json.keys()
               for key in keys:
                   if 'source-ref' not in key and '-metadata' not in key:
                       job_name = key
   
               new_json = {}
               # Set the location of the image
               new_json['source-ref'] = old_json['source-ref']
   
               # Temporarily store the list of labels
               labels = old_json[job_name]
   
               # Iterate through the labels and reformat to Custom Labels format
               for index, label in enumerate(labels):
                   new_json[f'{job_name}{index}'] = index
                   metadata = {}
                   metadata['class-name'] = old_json[f'{job_name}-metadata']['class-map'][str(label)]
                   metadata['confidence'] = old_json[f'{job_name}-metadata']['confidence-map'][str(label)]
                   metadata['type'] = 'groundtruth/image-classification'
                   metadata['job-name'] = old_json[f'{job_name}-metadata']['job-name']
                   metadata['human-annotated'] = old_json[f'{job_name}-metadata']['human-annotated']
                   metadata['creation-date'] = old_json[f'{job_name}-metadata']['creation-date']
                   # Add the metadata to new json line
                   new_json[f'{job_name}{index}-metadata'] = metadata
               # Write the current line to the json file
               the_new_file.write(json.dumps(new_json))
               the_new_file.write('\n')
   
       logger.info('Created %s', new_manifest_file)
       return  new_manifest_file
   
   def add_arguments(parser):
       """
       Adds command line arguments to the parser.
       :param parser: The command line parser.
       """
   
       parser.add_argument(
           "manifest_file", help="The Amazon SageMaker Ground Truth manifest file"
           "that you want to use."
       )
   
   
   def main():
       logging.basicConfig(level=logging.INFO,
                           format="%(levelname)s: %(message)s")
       try:
           # get command line arguments
           parser = argparse.ArgumentParser(usage=argparse.SUPPRESS)
           add_arguments(parser)
           args = parser.parse_args()
           # Create the manifest file
           manifest_file = create_manifest_file(args.manifest_file)
           print(f'Manifest file created: {manifest_file}')
       except FileNotFoundError as err:
           logger.exception('File not found: %s', err)
           print(f'File not found: {err}. Check your manifest file.')
   
   if __name__ == "__main__":
       main()
   ```

1. 记下脚本显示的新清单文件的名称。您将在下一个步骤中使用它。

1. [上传清单文件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)至要用于存储清单文件的 Amazon S3 存储桶。
**注意**  
确保 Amazon Rekognition Custom Labels 可以访问清单文件 JSON 行的 `source-ref` 字段中引用的 Amazon S3 存储桶。有关更多信息，请参阅 [访问外部 Amazon S3 存储桶](su-console-policy.md#su-external-buckets)。如果 Ground Truth 作业将图像存储在 Amazon Rekognition Custom Labels 控制台存储桶中，则无需添加权限。

1. 按照[使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console)中的说明，使用上传的清单文件创建数据集。对于步骤 8，在 **.manifest 文件位置**中，请输入清单文件位置的 Amazon S3 URL。如果使用的是 AWS SDK，请执行[使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。

# 从 CSV 文件创建清单文件
<a name="ex-csv-manifest"></a>

此示例 Python 脚本使用逗号分隔值 (CSV) 文件来标注图像，从而简化了清单文件的创建工作。您需要创建 CSV 文件。该清单文件适用于[多标签图像分类](getting-started.md#gs-multi-label-image-classification-example)或[多标签图像分类](getting-started.md#gs-multi-label-image-classification-example)。有关更多信息，请参阅 [查找物体、场景和概念](understanding-custom-labels.md#tm-classification)。

**注意**  
此脚本无法创建适用于查找[物体位置](understanding-custom-labels.md#tm-object-localization)或[品牌位置](understanding-custom-labels.md#tm-brand-detection-localization)的清单文件。

清单文件描述了用于训练模型的图像。例如，图像位置和分配给图像的标签。清单文件由一个或多个 JSON 行组成。每个 JSON 行都描述了一张图像。有关更多信息，请参阅 [在清单文件中导入图像级标签](md-create-manifest-file-classification.md)。

CSV 文件代表文本文件中多行的表格数据。一行中的各个字段用逗号分隔。有关更多信息，请参阅[逗号分隔的值](https://en.wikipedia.org/wiki/Comma-separated_values)。对于此脚本，CSV 文件中的每一行都代表一张图像，并映射到清单文件中的一个 JSON 行。要为支持[多标签图像分类](getting-started.md#gs-multi-label-image-classification-example)的清单文件创建 CSV 文件，您需要向每行添加一个或多个图像级标签。要创建适用于[图像分类](getting-started.md#gs-image-classification-example)的清单文件，请在每行中添加一个图像级标签。

例如，以下 CSV 文件描述了[多标签图像分类](getting-started.md#gs-multi-label-image-classification-example) (Flowers) *入门*项目中的图像。

```
camellia1.jpg,camellia,with_leaves
camellia2.jpg,camellia,with_leaves
camellia3.jpg,camellia,without_leaves
helleborus1.jpg,helleborus,without_leaves,not_fully_grown
helleborus2.jpg,helleborus,with_leaves,fully_grown
helleborus3.jpg,helleborus,with_leaves,fully_grown
jonquil1.jpg,jonquil,with_leaves
jonquil2.jpg,jonquil,with_leaves
jonquil3.jpg,jonquil,with_leaves
jonquil4.jpg,jonquil,without_leaves
mauve_honey_myrtle1.jpg,mauve_honey_myrtle,without_leaves
mauve_honey_myrtle2.jpg,mauve_honey_myrtle,with_leaves
mauve_honey_myrtle3.jpg,mauve_honey_myrtle,with_leaves
mediterranean_spurge1.jpg,mediterranean_spurge,with_leaves
mediterranean_spurge2.jpg,mediterranean_spurge,without_leaves
```

该脚本会为每一行生成 JSON 行。例如，以下是第一行 (`camellia1.jpg,camellia,with_leaves`) 的 JSON 行。

```
{"source-ref": "s3://bucket/flowers/train/camellia1.jpg","camellia": 1,"camellia-metadata":{"confidence": 1,"job-name": "labeling-job/camellia","class-name": "camellia","human-annotated": "yes","creation-date": "2022-01-21T14:21:05","type": "groundtruth/image-classification"},"with_leaves": 1,"with_leaves-metadata":{"confidence": 1,"job-name": "labeling-job/with_leaves","class-name": "with_leaves","human-annotated": "yes","creation-date": "2022-01-21T14:21:05","type": "groundtruth/image-classification"}}
```

在示例 CSV 中，没有图像的 Amazon S3 路径。如果您的 CSV 文件不包含图像的 Amazon S3 路径，请使用 `--s3_path` 命令行参数指定图像的 Amazon S3 路径。

该脚本会在去重图像 CSV 文件中记录每张图像的第一个条目。去重图像 CSV 文件包含在输入 CSV 文件中找到的每张图像的单个实例。输入 CSV 文件中存在的图像的其他实例将记录在重复图像 CSV 文件中。如果脚本发现重复的图像，便会检查重复图像 CSV 文件并根据需要更新去重图像 CSV 文件。使用去重文件，重新运行该脚本。如果在输入 CSV 文件中未找到重复项，则脚本会删除经过重复数据删除的图像 CSV 文件和重复的图像 CSVfile，因为它们为空。

 在此过程中，您将创建 CSV 文件并运行 Python 脚本以创建清单文件。

**通过 CSV 文件创建清单文件**

1. 创建一个 CSV 文件，并且在每一行中包含以下字段（每张图像占一行）。请勿在 CSV 文件中添加标题行。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/rekognition/latest/customlabels-dg/ex-csv-manifest.html)

   例如，`camellia1.jpg,camellia,with_leaves` 或 `s3://my-bucket/flowers/train/camellia1.jpg,camellia,with_leaves` 

1. 保存 CSV 文件。

1. 运行以下 Python 脚本。提供以下参数：
   + `csv_file`：您在步骤 1 中创建的 CSV 文件。
   + `manifest_file`：您要创建的清单文件的名称。
   + （可选）`--s3_path s3://path_to_folder/`：要添加到图像文件名（字段 1）的 Amazon S3 路径。如果字段 1 中的图像不包含 S3 路径，则使用 `--s3_path`。

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier:  Apache-2.0
   
   from datetime import datetime, timezone
   import argparse
   import logging
   import csv
   import os
   import json
   
   """
   Purpose
   Amazon Rekognition Custom Labels model example used in the service documentation.
   Shows how to create an image-level (classification) manifest file from a CSV file.
   You can specify multiple image level labels per image.
   CSV file format is
   image,label,label,..
   If necessary, use the bucket argument to specify the S3 bucket folder for the images.
   https://docs.aws.amazon.com/rekognition/latest/customlabels-dg/md-gt-cl-transform.html
   """
   
   logger = logging.getLogger(__name__)
   
   
   def check_duplicates(csv_file, deduplicated_file, duplicates_file):
       """
       Checks for duplicate images in a CSV file. If duplicate images
       are found, deduplicated_file is the deduplicated CSV file - only the first
       occurence of a duplicate is recorded. Other duplicates are recorded in duplicates_file.
       :param csv_file: The source CSV file.
       :param deduplicated_file: The deduplicated CSV file to create. If no duplicates are found
       this file is removed.
       :param duplicates_file: The duplicate images CSV file to create. If no duplicates are found
       this file is removed.
       :return: True if duplicates are found, otherwise false.
       """
   
       logger.info("Deduplicating %s", csv_file)
   
       duplicates_found = False
   
       # Find duplicates.
       with open(csv_file, 'r', newline='', encoding="UTF-8") as f,\
               open(deduplicated_file, 'w', encoding="UTF-8") as dedup,\
               open(duplicates_file, 'w', encoding="UTF-8") as duplicates:
   
           reader = csv.reader(f, delimiter=',')
           dedup_writer = csv.writer(dedup)
           duplicates_writer = csv.writer(duplicates)
   
           entries = set()
           for row in reader:
               # Skip empty lines.
               if not ''.join(row).strip():
                   continue
   
               key = row[0]
               if key not in entries:
                   dedup_writer.writerow(row)
                   entries.add(key)
               else:
                   duplicates_writer.writerow(row)
                   duplicates_found = True
   
       if duplicates_found:
           logger.info("Duplicates found check %s", duplicates_file)
   
       else:
           os.remove(duplicates_file)
           os.remove(deduplicated_file)
   
       return duplicates_found
   
   
   def create_manifest_file(csv_file, manifest_file, s3_path):
       """
       Reads a CSV file and creates a Custom Labels classification manifest file.
       :param csv_file: The source CSV file.
       :param manifest_file: The name of the manifest file to create.
       :param s3_path: The S3 path to the folder that contains the images.
       """
       logger.info("Processing CSV file %s", csv_file)
   
       image_count = 0
       label_count = 0
   
       with open(csv_file, newline='', encoding="UTF-8") as csvfile,\
               open(manifest_file, "w", encoding="UTF-8") as output_file:
   
           image_classifications = csv.reader(
               csvfile, delimiter=',', quotechar='|')
   
           # Process each row (image) in CSV file.
           for row in image_classifications:
               source_ref = str(s3_path)+row[0]
   
               image_count += 1
   
               # Create JSON for image source ref.
               json_line = {}
               json_line['source-ref'] = source_ref
   
               # Process each image level label.
               for index in range(1, len(row)):
                   image_level_label = row[index]
   
                   # Skip empty columns.
                   if image_level_label == '':
                       continue
                   label_count += 1
   
                  # Create the JSON line metadata.
                   json_line[image_level_label] = 1
                   metadata = {}
                   metadata['confidence'] = 1
                   metadata['job-name'] = 'labeling-job/' + image_level_label
                   metadata['class-name'] = image_level_label
                   metadata['human-annotated'] = "yes"
                   metadata['creation-date'] = \
                       datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%f')
                   metadata['type'] = "groundtruth/image-classification"
   
                   json_line[f'{image_level_label}-metadata'] = metadata
   
                   # Write the image JSON Line.
               output_file.write(json.dumps(json_line))
               output_file.write('\n')
   
       output_file.close()
       logger.info("Finished creating manifest file %s\nImages: %s\nLabels: %s",
                   manifest_file, image_count, label_count)
   
       return image_count, label_count
   
   
   def add_arguments(parser):
       """
       Adds command line arguments to the parser.
       :param parser: The command line parser.
       """
   
       parser.add_argument(
           "csv_file", help="The CSV file that you want to process."
       )
   
       parser.add_argument(
           "--s3_path", help="The S3 bucket and folder path for the images."
           " If not supplied, column 1 is assumed to include the S3 path.", required=False
       )
   
   
   def main():
   
       logging.basicConfig(level=logging.INFO,
                           format="%(levelname)s: %(message)s")
   
       try:
   
           # Get command line arguments
           parser = argparse.ArgumentParser(usage=argparse.SUPPRESS)
           add_arguments(parser)
           args = parser.parse_args()
   
           s3_path = args.s3_path
           if s3_path is None:
               s3_path = ''
   
           # Create file names.
           csv_file = args.csv_file
           file_name = os.path.splitext(csv_file)[0]
           manifest_file = f'{file_name}.manifest'
           duplicates_file = f'{file_name}-duplicates.csv'
           deduplicated_file = f'{file_name}-deduplicated.csv'
   
           # Create manifest file, if there are no duplicate images.
           if check_duplicates(csv_file, deduplicated_file, duplicates_file):
               print(f"Duplicates found. Use {duplicates_file} to view duplicates "
                     f"and then update {deduplicated_file}. ")
               print(f"{deduplicated_file} contains the first occurence of a duplicate. "
                     "Update as necessary with the correct label information.")
               print(f"Re-run the script with {deduplicated_file}")
           else:
               print("No duplicates found. Creating manifest file.")
   
               image_count, label_count = create_manifest_file(csv_file,
                                                               manifest_file,
                                                               s3_path)
   
               print(f"Finished creating manifest file: {manifest_file} \n"
                     f"Images: {image_count}\nLabels: {label_count}")
   
       except FileNotFoundError as err:
           logger.exception("File not found: %s", err)
           print(f"File not found: {err}. Check your input CSV file.")
   
   
   if __name__ == "__main__":
       main()
   ```

1. 如果您计划使用测试数据集，请重复步骤 1-3，以便为测试数据集创建清单文件。

1. 如有必要，请将图像复制到您在 CSV 文件第 1 列中指定的（或在 `--s3_path` 命令行中指定的）Amazon S3 存储桶路径。您可使用以下 AWS S3 命令。

   ```
   aws s3 cp --recursive your-local-folder s3://your-target-S3-location
   ```

1. [上传清单文件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)至要用于存储清单文件的 Amazon S3 存储桶。
**注意**  
确保 Amazon Rekognition Custom Labels 可以访问清单文件 JSON 行的 `source-ref` 字段中引用的 Amazon S3 存储桶。有关更多信息，请参阅 [访问外部 Amazon S3 存储桶](su-console-policy.md#su-external-buckets)。如果 Ground Truth 作业将图像存储在 Amazon Rekognition Custom Labels 控制台存储桶中，则无需添加权限。

1. 按照[使用 SageMaker AI Ground Truth 清单文件创建数据集（控制台）](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console)中的说明，使用上传的清单文件创建数据集。对于步骤 8，在 **.manifest 文件位置**中，请输入清单文件位置的 Amazon S3 URL。如果使用的是 AWS SDK，请执行[使用 SageMaker AI Ground Truth 清单文件 (SDK) 创建数据集](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk)。