Exporter des données étiquetées

Une fois l'opération d'ajout d'étiquettes terminée, vous pouvez exporter l'ensemble de données annoté vers votre bucket Google Cloud Storage en appelant ExportData.

ExportData permet de renvoyer un fichier .csv contenant une ligne pour chaque annotation ou élément de données. Le premier champ indique la catégorie d'utilisation ML de cette ligne, définie par défaut sur UNASSIGNED. ExportData accepte également un fichier jsonl dans lequel chaque ligne représente un exemple incluant un élément de données et toutes les annotations. Vous trouverez ci-dessous des exemples pour chaque type.

Classification d'images

  • Ligne csv :

    UNASSIGNED,image_url,label_1,label_2,...

  • Ligne json :

    {
    "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "imagePayload":{
    "mimeType":"IMAGE_PNG",
    "imageUri":"gs://sample_bucket/image.png"
    },
    "annotations":[
    {
         "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
       "annotationValue":{
          "imageClassificationAnnotation":{
           "annotationSpec":{
                "displayName":"tulip",
             }
          }
       }
    }
    ]
    }

Cadre de délimitation d'image

  • Ligne CSV : chaque ligne contient des informations sur un cadre de délimitation, en utilisant les coordonnées X et Y pour représenter chaque angle de la zone. Lorsqu'une seule image comprend plusieurs cadres, ils se trouvent sur des lignes distinctes. Le format de ligne est UNASSIGNED, image_url, label, topleft_x, topleft_y, topright_x, topright_y, bottomright_x, bottomright_y, bottomleft_x, bottomleft_y. Les coordonnées topright_x, topright_y, bottomleft_x et bottomleft_y peuvent être des chaînes vides, car elles fournissent des informations redondantes.

    UNASSIGNED,image_url,label,0.1,0.1,,,0.3,0.3,,

  • Ligne json : si aucune des coordonnées de normalizedVertices n'est définie, ce champ est défini par défaut sur 0. Cela s'applique également aux annotations basées sur des coordonnées.

    {
     "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
     "imagePayload":{
        "mimeType":"IMAGE_PNG",
        "imageUri":"gs://sample_bucket/image.png"
     },
     "annotations":[
        {
             "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
           "annotationValue":{
             "image_bounding_poly_annotation": {
              "annotationSpec": {
                "displayName": "tulip"
              },
              "normalizedBoundingPoly": {
              "normalizedVertices": [ {
                  "x": 0.1,
                  "y": 0.2
                }, {
                  "x": 0.9,
                  "y": 0.9
                } ]
              }
           }
        }
      }
     ]
    }

Polygone de délimitation d'image, cadre de délimitation orienté et polyligne

  • Ligne csv : chaque point du polygone/de la polyligne fermé(e) est représenté par le point x,y, séparé par deux colonnes csv vides. La dernière paire se reconnecte à la première paire en ce qui concerne le polygone, tandis que la polyligne ne comprend pas de cycle fermé. Chaque ligne représente un polygone/une polyligne.

    UNASSIGNED,image_url,label,0.1,0.1,,,0.3,0.3,,,0.6,0.6,,...

  • Ligne json :

    {
    "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "imagePayload":{
    "mimeType":"IMAGE_PNG",
    "imageUri":"gs://sample_bucket/image.png"
    },
    "annotations":[
    {
         "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
       "annotationValue":{
         "image_bounding_poly_annotation": {
          "annotationSpec": {
            "displayName": "tulip"
          },
          "normalizedBoundingPoly": {
            "normalizedVertices": [ {
              "x": 0.1,
              "y": 0.1
            }, {
              "x": 0.1,
              "y": 0.2
            }, {
              "x": 0.2,
              "y": 0.3
            }  ]
          }
       }
    }
    }
    ]
    }

Segmentation d'image

Pour la segmentation d'image, seule la sortie jsonl est fournie.

  • Ligne json : le champ imageBytes de l'imageSegmentationAnnotation représente le masque de segmentation de cette image. La couleur de chaque libellé (c'est-à-dire chaque chien et chat) est indiquée dans le champ annotationColors.
    {
    "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "imagePayload":{
    "mimeType":"IMAGE_PNG",
    "imageUri":"gs://sample_bucket/image.png"
    },
    "annotations":[
    {
         "name":"projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
       "annotationValue":{
         "imageSegmentationAnnotation": {
            "annotationColors": [ {
              "key": "rgb(0,0,255)",
              "value": {
                "display_name": "dog"
              }
            }, {
              "key": "rgb(0,255,0)",
              "value": {
                "display_name": "cat"
              }
            } ],
            "mimeType": "IMAGE_JPEG",
            "imageBytes": "/9j/4AAQSkZJRgABAQAAAQABAAD/2"
       }
    }
    }
    ]
    }

Classification de vidéos

  • Ligne csv :

    UNASSIGNED,video_url,label,segment_start_time,segment_end_time

  • Ligne json :

    {
    "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "videoPayload": {
      "mimeType": "VIDEO_MP4",
      "resolution": {
        width: 720,
        height: 360
      }
      "frameRate": 24
    },
    "annotations": [ {
      "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
      "annotationSource": 3,
      "annotationValue": {
        "videoClassificationAnnotation": {
          "timeSegment": {
            "startTimeOffset": {
              "seconds": 10
            },
            "endTimeOffset": {
              "seconds": 20
            }
          },
          "annotationSpec": {
            "displayName": "dog"
          }
        }
      }
    } ]
    }

Détection d'objet vidéo

  • Ligne csv : les quatre points se situent en haut à gauche, en haut à droite, en bas à droite et en bas à gauche. Les deuxième et quatrième points sont facultatifs. Chaque point est représenté par x,y. Chaque ligne contiendra un cadre de délimitation.

    UNASSIGNED,video_url,label,timestamp,0.1,0.1,,,0.3,0.3,,

  • Ligne json :

    {
    "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "videoPayload": {
      "mimeType": "VIDEO_MP4",
      "resolution": {
        width: 720,
        height: 360
      }
      "frameRate": 24
    },
    "annotations": [ {
      "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
      "annotationSource": 3,
      "annotationValue": {
        "videoObjectTrackingAnnotation": {
      "annotationSpec": {
        "displayName": "tulip"
      },
      "timeSegment": {
        "startTimeOffset": {
          "seconds": 10
        },
        "endTimeOffset": {
          "seconds": 10
        }
      },
      "objectTrackingFrames": [ {
        "normalizedBoundingPoly": {
          "normalizedVertices": [ {
            "x": 0.2,
            "y": 0.3
          }, {
            "x": 0.9,
            "y": 0.5
          } ]
        },
      }, {
        "normalizedBoundingPoly": {
          "normalizedVertices": [ {
            "x": 0.3,
            "y": 0.3
          }, {
            "x": 0.5,
            "y": 0.7
          } ]
        },
      } ]
    }
    }
    }]}

Suivi des objets vidéo

  • Ligne csv : les quatre points se situent en haut à gauche, en haut à droite, en bas à droite et en bas à gauche. Les deuxième et quatrième points sont facultatifs. Chaque point est représenté par x,y. Chaque ligne contiendra un cadre de délimitation. Chaque objet de la vidéo est représenté par un ID d'instance (instance_id) unique.

    UNASSIGNED,video_url,label,instance_id,timestamp,0.1,0.1,,,0.3,0.3,,

  • Ligne json :

    {
    "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "videoPayload": {
      "mimeType": "VIDEO_MP4",
      "resolution": {
        width: 720,
        height: 360
      }
      "frameRate": 24
    },
    "annotations": [ {
      "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
      "annotationSource": 3,
      "annotationValue": {
        "videoObjectTrackingAnnotation": {
      "annotationSpec": {
        "displayName": "tulip"
      },
      "timeSegment": {
        "startTimeOffset": {
          "seconds": 10
        },
        "endTimeOffset": {
          "seconds": 20
        }
      },
      "objectTrackingFrames": [ {
        "normalizedBoundingPoly": {
          "normalizedVertices": [ {
            "x": 0.2,
            "y": 0.3
          }, {
            "x": 0.9,
            "y": 0.5
          } ]
        },
        "timeOffset": {
          "nanos": 1000000
        }
      }, {
        "normalizedBoundingPoly": {
          "normalizedVertices": [ {
            "x": 0.3,
            "y": 0.3
          }, {
            "x": 0.5,
            "y": 0.7
          } ]
        },
        "timeOffset": {
          "nanos": 84000000
        }
      } ]
    }
    }
    }]}

Événement vidéo

  • Ligne csv : les quatre points se situent en haut à gauche, en haut à droite, en bas à droite et en bas à gauche. Les deuxième et quatrième points sont facultatifs. Chaque point est représenté par x,y. Chaque ligne contiendra un cadre de délimitation. Chaque objet de la vidéo est représenté par un ID d'instance (instance_id) unique.

    UNASSIGNED,video_url,label,segment_start_time,segment_end_time

  • Ligne json :

    {
    "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
    "videoPayload": {
      "mimeType": "VIDEO_MP4",
      "resolution": {
        width: 720,
        height: 360
      }
      "frameRate": 24
    },
    "annotations": [ {
      "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/annotation_id",
      "annotationValue": {
        "videoEventAnnotation": {
          "annotationSpec": {
            "displayName": "Callie"
          },
          "timeSegment": {
            "startTimeOffset": {
              "seconds": 123
            },
            "endTimeOffset": {
              "seconds": 150
            }
          }
        }
      }
     } ]
    }
    }
    }]}

Classifier du texte

  • Ligne csv :

    UNASSIGNED,text_url,label_l

  • Ligne json :

    {
      "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
      "textPayload": {
        "textContent": "dummy_text_content",
        "textUri": "gs://test_bucket/file.txt",
        "wordCount": 1
      }
      "annotations": [ {
        "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/fake_annotation_id",
        "annotationValue": {
          "textClassificationAnnotation": {
            "annotationSpec": {
              "displayName": "news"
            }
          }
        }
      } ],
    }

Extraction d'entités textuelles

Pour l'extraction d'entités textuelles, seule la sortie jsonl est fournie.

  • Ligne json :
    {
        "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id",
        "textPayload": {
          "textContent": "dummy_text_content",
          "textUri": "gs://test_bucket/file.txt",
          "wordCount": 1
        }
        "annotations": [ {
          "name": "projects/project_id/datasets/dataset_id/annotatedDatasets/annotated_dataset_id/examples/example_id/annotations/fake_annotation_id",
          "annotationValue": {
            "textEntityExtractionAnnotation": {
              "annotationSpec": {
                "displayName": "equations"
              },
              "textSegment": {
                "startOffset": 10,
                "endOffset": 20
              }
            }
          }
        } ],
      }

ExportData est une opération de longue durée. L'API renverra un ID d'opération. Vous pouvez ultérieurement appeler GetOperation à l'aide de l'ID d'opération pour connaître son état.

UI Web

Procédez comme suit pour exporter les données étiquetées à l'aide de l'interface utilisateur du service d'ajout d'étiquettes aux données.

  1. Ouvrez l'interface utilisateur du service d'ajout d'étiquettes aux données dans Google Cloud Console.

    La page Ensembles de données indique l'état des ensembles de données créés précédemment pour le projet en cours.

  2. Cliquez sur le nom de l'ensemble de données à exporter. Vous êtes redirigé vers la page Informations sur l'ensemble de données.

  3. Dans la section Ensembles de données avec étiquette, cliquez sur EXPORTER dans la colonne État de l'exportation.

  4. Dans la boîte de dialogue Exporter un ensemble de données étiqueté, saisissez le chemin d'accès Cloud Storage à utiliser pour le fichier de sortie, puis sélectionnez le format de fichier souhaité.

  5. Cliquez sur EXPORTER.

    La page Informations sur l'ensemble de données affiche un état "en cours" lors de l'exportation des données. Une fois l'opération terminée, vous trouverez le fichier d'exportation dans le répertoire Cloud Storage que vous avez spécifié.

Ligne de commande

Définissez les variables d'environnement suivantes :

  1. La variable PROJECT_ID à votre ID de projet Google Cloud
  2. La variable DATASET_ID à l'ID de votre ensemble de données, issue de la réponse obtenue lorsque vous avez créé l'ensemble de données. L'ID apparaît à la fin du nom complet de l'ensemble de données :

    projects/PROJECT_ID/locations/us-central1/datasets/DATASET_ID
  3. la variable ANNOTATED_DATASET_ID à l'ID du nom de ressource de votre ensemble de données annoté. Le nom de la ressource est au format suivant :

    projects/PROJECT_ID/locations/us-central1/datasets/DATASET_ID/annotatedDatasets/ANNOTATED_DATASET_ID
  4. La variable STORAGE_URI à l'URI du bucket Cloud Storage dans lequel vous souhaitez stocker les résultats

Pour toutes les demandes d'annotation, à l'exception de la segmentation d'image, la requête curl se présente comme suit :

curl -X POST \
   -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
   -H "Content-Type: application/json" \
   https://datalabeling.googleapis.com/v1beta1/projects/${PROJECT_ID}/datasets/${DATASET_ID}:exportData \
   -d '{
     "annotatedDataset": "${ANNOTATED_DATASET_ID}",
     "outputConfig": {
       "gcsDestination": {
           "output_uri": "${STORAGE_URI}",
           "mimeType": "text/csv"
       }
     }
   }'

Pour l'exportation de données de segmentation d’image, la demande curl se présente comme suit :

curl -X POST \
   -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
   -H "Content-Type: application/json" \
   https://datalabeling.googleapis.com/v1beta1/projects/${PROJECT_ID}/datasets/${DATASET_ID}:exportData \
   -d '{
     "annotatedDataset": "${ANNOTATED_DATASET_ID}",
     "outputConfig": {
       "gcsFolderDestination": {
         "output_folder_uri": "${STORAGE_URI}"
       }
     }
   }'

La sortie obtenue doit ressembler à ceci :

{
  "name": "projects/data-labeling-codelab/operations/5c73dd6b_0000_2b34_a920_883d24fa2064",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.data-labeling.v1beta1.ExportDataOperationResponse",
    "dataset": "projects/data-labeling-codelab/datasets/5c73db3d_0000_23e0_a25b_94eb2c119c4c"
  }
}

Python

Avant de pouvoir exécuter cet exemple de code, vous devez installer les bibliothèques clientes Python.

def export_data(dataset_resource_name, annotated_dataset_resource_name, export_gcs_uri):
    """Exports a dataset from the given Google Cloud project."""
    from google.cloud import datalabeling_v1beta1 as datalabeling

    client = datalabeling.DataLabelingServiceClient()

    gcs_destination = datalabeling.GcsDestination(
        output_uri=export_gcs_uri, mime_type="text/csv"
    )

    output_config = datalabeling.OutputConfig(gcs_destination=gcs_destination)

    response = client.export_data(
        request={
            "name": dataset_resource_name,
            "annotated_dataset": annotated_dataset_resource_name,
            "output_config": output_config,
        }
    )

    print(f"Dataset ID: {response.result().dataset}\n")
    print("Output config:")
    print("\tGcs destination:")
    print(
        "\t\tOutput URI: {}\n".format(
            response.result().output_config.gcs_destination.output_uri
        )
    )

Java

Avant de pouvoir exécuter cet exemple de code, vous devez installer les bibliothèques clientes Java.
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.datalabeling.v1beta1.DataLabelingServiceClient;
import com.google.cloud.datalabeling.v1beta1.DataLabelingServiceSettings;
import com.google.cloud.datalabeling.v1beta1.ExportDataOperationMetadata;
import com.google.cloud.datalabeling.v1beta1.ExportDataOperationResponse;
import com.google.cloud.datalabeling.v1beta1.ExportDataRequest;
import com.google.cloud.datalabeling.v1beta1.GcsDestination;
import com.google.cloud.datalabeling.v1beta1.LabelStats;
import com.google.cloud.datalabeling.v1beta1.OutputConfig;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutionException;

class ExportData {

  // Export data from an annotated dataset.
  static void exportData(String datasetName, String annotatedDatasetName, String gcsOutputUri)
      throws IOException {
    // String datasetName = DataLabelingServiceClient.formatDatasetName(
    //     "YOUR_PROJECT_ID", "YOUR_DATASETS_UUID");
    // String annotatedDatasetName = DataLabelingServiceClient.formatAnnotatedDatasetName(
    //     "YOUR_PROJECT_ID",
    //     "YOUR_DATASET_UUID",
    //     "YOUR_ANNOTATED_DATASET_UUID");
    // String gcsOutputUri = "gs://YOUR_BUCKET_ID/export_path";


    DataLabelingServiceSettings settings =
        DataLabelingServiceSettings.newBuilder()
            .build();
    try (DataLabelingServiceClient dataLabelingServiceClient =
        DataLabelingServiceClient.create(settings)) {
      GcsDestination gcsDestination =
          GcsDestination.newBuilder().setOutputUri(gcsOutputUri).setMimeType("text/csv").build();

      OutputConfig outputConfig =
          OutputConfig.newBuilder().setGcsDestination(gcsDestination).build();

      ExportDataRequest exportDataRequest =
          ExportDataRequest.newBuilder()
              .setName(datasetName)
              .setOutputConfig(outputConfig)
              .setAnnotatedDataset(annotatedDatasetName)
              .build();

      OperationFuture<ExportDataOperationResponse, ExportDataOperationMetadata> operation =
          dataLabelingServiceClient.exportDataAsync(exportDataRequest);

      ExportDataOperationResponse response = operation.get();

      System.out.format("Exported item count: %d\n", response.getExportCount());
      LabelStats labelStats = response.getLabelStats();
      Set<Entry<String, Long>> entries = labelStats.getExampleCountMap().entrySet();
      for (Entry<String, Long> entry : entries) {
        System.out.format("\tLabel: %s\n", entry.getKey());
        System.out.format("\tCount: %d\n\n", entry.getValue());
      }
    } catch (IOException | InterruptedException | ExecutionException e) {
      e.printStackTrace();
    }
  }
}