

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Création d’un fichier manifeste à partir d’un fichier CSV
<a name="ex-csv-manifest"></a>

Cet exemple de script Python simplifie la création d’un fichier manifeste en utilisant un fichier CSV pour étiqueter les images. C’est vous qui créez le fichier CSV. Le fichier manifeste convient à la [classification d’images à plusieurs étiquettes](getting-started.md#gs-multi-label-image-classification-example) ou [Classification des images à plusieurs étiquettes](getting-started.md#gs-multi-label-image-classification-example). Pour plus d’informations, consultez [Recherche d’objets, de scènes et de concepts](understanding-custom-labels.md#tm-classification). 

**Note**  
Ce script ne crée pas de fichier manifeste adapté à la [recherche des emplacements d’objets](understanding-custom-labels.md#tm-object-localization) ni à la [recherche des marques](understanding-custom-labels.md#tm-brand-detection-localization).

Un fichier manifeste décrit les images utilisées pour entraîner un modèle (par exemple, les emplacements des images et les étiquettes attribuées aux images). Un fichier manifeste est composé d’une ou plusieurs lignes JSON. Chaque ligne JSON décrit une seule image. Pour plus d’informations, consultez [Importation d'étiquettes au niveau de l'image dans des fichiers manifestes](md-create-manifest-file-classification.md).

Un fichier CSV représente des données tabulaires réparties sur plusieurs lignes d’un fichier texte. Les champs sur une ligne sont séparés par une virgule. Pour plus d’informations, consultez la section [Valeurs séparées par des virgules](https://en.wikipedia.org/wiki/Comma-separated_values). Pour ce script, chaque ligne du fichier CSV représente une image unique et correspond à une ligne JSON dans le fichier manifeste. Pour créer un fichier CSV pour un fichier manifeste prenant en charge la [classification d’images à plusieurs étiquettes](getting-started.md#gs-multi-label-image-classification-example), vous devez ajouter une ou plusieurs étiquettes au niveau de l’image à chaque ligne. Pour créer un fichier manifeste adapté à la [Classification d’images](getting-started.md#gs-image-classification-example), vous devez ajouter une seule étiquette au niveau de l’image à chaque ligne.

Par exemple, le fichier CSV suivant décrit les images du projet de *mise en route* [Classification des images à plusieurs étiquettes](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
```

Le script génère des lignes JSON pour chaque ligne. Par exemple, voici la ligne JSON pour la première ligne (`camellia1.jpg,camellia,with_leaves`).

```
{"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"}}
```

Dans l’exemple de fichier CSV, le chemin Amazon S3 vers l’image n’est pas présent. Si le fichier CSV n’inclut pas le chemin Amazon S3 des images, utilisez l’argument de ligne de commande `--s3_path` pour spécifier cette information pour l’image. 

Le script enregistre la première entrée pour chaque image dans un fichier image CSV dédupliqué. Le fichier image CSV dédupliqué contient une seule instance de chaque image trouvée dans le fichier CSV d’entrée. Les autres occurrences d’une image dans le fichier CSV d’entrée sont enregistrées dans un fichier image CSV dupliqué. Si le script détecte des images dupliquées, examinez le fichier image CSV dupliqué et mettez à jour le fichier image CSV dédupliqué si nécessaire. Réexécutez le script avec le fichier dédupliqué. Si aucun doublon n'est détecté dans le fichier CSV d'entrée, le script supprime le fichier image CSV dédupliqué et l'image dupliquée CSVfile, car ils sont vides. 

 Dans cette procédure, c’est vous qui créez le fichier CSV et qui exécutez le script Python pour créer le fichier manifeste. 

**Pour créer un fichier manifeste à partir d’un fichier CSV**

1. Créez un fichier CSV avec les champs suivants dans chaque ligne (une ligne par image). N’ajoutez pas de ligne d’en-tête au fichier CSV.    
[See the AWS documentation website for more details](http://docs.aws.amazon.com/fr_fr/rekognition/latest/customlabels-dg/ex-csv-manifest.html)

   Par exemple : `camellia1.jpg,camellia,with_leaves` ou `s3://my-bucket/flowers/train/camellia1.jpg,camellia,with_leaves` 

1. Enregistrez le fichier CSV.

1. Exécutez le script Python suivant. Fournissez les arguments suivants :
   + `csv_file` : fichier CSV que vous avez créé à l’étape 1. 
   + `manifest_file` : nom du fichier manifeste que vous souhaitez créer.
   + (Facultatif) `--s3_path {{s3://path_to_folder/}}` : chemin Amazon S3 à ajouter aux noms de fichiers image (champ 1). Utilisez `--s3_path` si les images du champ 1 ne contiennent pas déjà de chemin S3.

   ```
   # 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. Si vous prévoyez d’utiliser un jeu de données de test, répétez les étapes 1 à 3 afin de créer un fichier manifeste pour le jeu de données de test.

1. Si nécessaire, copiez les images dans le chemin du compartiment Amazon S3 que vous avez spécifié dans la colonne 1 du fichier CSV (ou dans la ligne de commande `--s3_path`). Vous pouvez utiliser la commande S3 AWS suivante :

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

1. [Chargez les fichiers manifestes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html) dans le compartiment Amazon S3 que vous souhaitez utiliser pour stocker ce type de fichier.
**Note**  
Assurez-vous qu’Étiquettes personnalisées Amazon Rekognition a accès au compartiment Amazon S3 référencé dans le champ `source-ref` des lignes JSON du fichier manifeste. Pour plus d’informations, consultez [Accès à des compartiments Amazon S3 externes](su-console-policy.md#su-external-buckets). Si la tâche Ground Truth stocke des images dans le compartiment de la console Étiquettes personnalisées Amazon Rekognition, vous n’avez pas besoin d’ajouter d’autorisations.

1. Suivez les instructions sous [Création d'un ensemble de données à l'aide d'un fichier manifeste SageMaker AI Ground Truth (console)](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-console) pour créer un jeu de données avec le fichier manifeste chargé. Pour l’étape 8, dans **Emplacement du fichier .manifest**, entrez l’URL Amazon S3 correspondant à l’emplacement du fichier manifeste. Si vous utilisez le kit AWS SDK, effectuez les actions indiquées dans [Création d'un ensemble de données à l'aide d'un fichier manifeste (SDK) SageMaker AI Ground Truth](md-create-dataset-ground-truth.md#md-create-dataset-ground-truth-sdk).