Como exportar dados rotulados

Quando a operação de rotulagem estiver concluída, será possível exportar o conjunto de dados anotado para o bucket do Google Cloud Storage chamando ExportData.

ExportData aceita retornar um arquivo .csv contendo uma linha para cada anotação ou item de dados. O primeiro campo indica a categoria de uso em ML dessa linha, que tem como padrão UNASSIGNED. ExportData também aceita um arquivo jsonl em que cada linha representa um exemplo que inclui um item de dados e todas as anotações. Veja abaixo exemplos para cada tipo.

Classificação de imagens

  • Linha csv:

    UNASSIGNED,image_url,label_1,label_2,...

  • Linha 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",
             }
          }
       }
    }
    ]
    }

Caixa delimitadora de imagens

  • Linha csv: cada linha contém informações sobre uma caixa delimitadora, usando coordenadas x,y para representar cada canto da caixa. Várias caixas para uma única imagem estão em linhas separadas. O formato da linha é UNASSIGNED, image_url, label, topleft_x, topleft_y, topright_x, topright_y, bottomright_x, bottomright_y, bottomleft_x, bottomleft_y. As coordenadas topright_x, topright_y, inferiorleft_x e inferiorleft_y podem ser strings vazias, porque fornecem informações redundantes.

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

  • Linha json: se uma coordenada em normalizedVertices não estiver definida, esse campo será 0 por padrão. Isso também se aplica a qualquer anotação baseada em coordenadas.

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

Polígono delimitador de imagem, caixa delimitadora orientada e polilinha

  • Linha csv: cada ponto na polígono/polilinha fechada é representado pelo ponto x,y separado por duas colunas csv vazias. O último par se conecta novamente ao primeiro par para polígono, enquanto não houver ciclo fechado para a polilinha. Cada linha representa um polígono/polilinha.

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

  • Linha 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
            }  ]
          }
       }
    }
    }
    ]
    }

Segmentação de imagens

Para segmentação de imagens, somente a saída jsonl é fornecida.

  • Linha json: o campo imageBytes em imageSegmentationAnnotation representa a máscara de segmentação dessa imagem. A cor de cada rótulo (isto é, cada cachorro e gato) é mostrada no campo 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"
       }
    }
    }
    ]
    }

Classificação de vídeo

  • Linha csv:

    UNASSIGNED,video_url,label,segment_start_time,segment_end_time

  • Linha 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"
          }
        }
      }
    } ]
    }

Detecção de objetos de vídeo

  • linha csv: os quatro pontos são superior esquerdo, superior direito, inferior direito, inferior esquerdo. O segundo e o quarto pontos são opcionais. Cada ponto é representado por x,y. Cada linha conterá uma caixa delimitadora.

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

  • Linha 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
          } ]
        },
      } ]
    }
    }
    }]}

Rastreamento de objeto em vídeos

  • linha csv: os quatro pontos são superior esquerdo, superior direito, inferior direito, inferior esquerdo. O segundo e o quarto pontos são opcionais. Cada ponto é representado por x,y. Cada linha conterá uma caixa delimitadora. Cada objeto no vídeo é representado por um instance_id exclusivo.

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

  • Linha 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
        }
      } ]
    }
    }
    }]}

Evento de vídeo

  • linha csv: os quatro pontos são superior esquerdo, superior direito, inferior direito, inferior esquerdo. O segundo e o quarto pontos são opcionais. Cada ponto é representado por x,y. Cada linha conterá uma caixa delimitadora. Cada objeto no vídeo é representado por um instance_id exclusivo.

    UNASSIGNED,video_url,label,segment_start_time,segment_end_time

  • Linha 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
            }
          }
        }
      }
     } ]
    }
    }
    }]}

Classificação de texto

  • Linha csv:

    UNASSIGNED,text_url,label_l

  • Linha 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"
            }
          }
        }
      } ],
    }

Extração de entidades de texto

Para a extração de entidade de texto, somente a saída jsonl é fornecida.

  • Linha 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 é uma operação de longa duração. A API retornará um código de operação. Use o código de operação para chamar GetOperation para ver o status dele mais tarde.

IU da Web

Siga estas etapas para exportar os dados rotulados usando a IU do Serviço de rotulagem de dados.

  1. Abra a IU de serviço de classificação de dados no console do Google Cloud.

    A página Conjuntos de dados mostra o status de conjuntos de dados criados anteriormente para o projeto atual.

  2. Clique no nome do conjunto de dados que quer exportar. Isso levará você à página Detalhes do conjunto de dados.

  3. Na seção Conjuntos de dados rotulados, clique em EXPORTAR na coluna Status da exportação.

  4. Na caixa de diálogo Exportar conjunto de dados rotulado, digite o caminho do Cloud Storage a ser usado para o arquivo de saída e selecione o formato de arquivo que quer.

  5. Clique em Exportar.

    A página Detalhes do conjunto de dados mostra um status em andamento enquanto seus dados estão sendo exportados. Depois de concluído, você poderá encontrar o arquivo de exportação no caminho do Cloud Storage especificado.

Linha de comando

Configure as variáveis de ambiente a seguir:

  1. Variável PROJECT_ID para o código do projeto do Google Cloud.
  2. Variável DATASET_ID para o ID do conjunto de dados, a partir da resposta de quando você criou o conjunto de dados. O código é exibido no fim do nome completo do conjunto de dados:

    projects/PROJECT_ID/locations/us-central1/datasets/DATASET_ID
  3. ANNOTATED_DATASET_ID para o código do nome do recurso de conjunto de dados anotado. O nome do recurso tem este formato:

    projects/PROJECT_ID/locations/us-central1/datasets/DATASET_ID/annotatedDatasets/ANNOTATED_DATASET_ID
  4. Variável STORAGE_URI para o URI do bucket do Cloud Storage em que você quer armazenar os resultados.

Para todas as solicitações de anotação, exceto a segmentação de imagens, a solicitação curl é semelhante à seguinte:

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"
       }
     }
   }'

Para exportar dados de segmentação de imagem, a solicitação curl tem a seguinte aparência:

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}"
       }
     }
   }'

A resposta será semelhante a esta:

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

Antes de executar este código de exemplo, você precisa instalar as bibliotecas de cliente do 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

Antes de executar este código de exemplo, é preciso instalar as bibliotecas de cliente do 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();
    }
  }
}