Tutorial: analisar uma tabela de objetos usando uma função remota

Neste tutorial, mostramos como criar uma tabela de objetos com base nas imagens do conjunto de dados de flores, criar uma função remota que rotule imagens usando a API Cloud Vision e analisar as imagens na tabela de objetos usando a função remota.

Permissões necessárias

  • Para criar o conjunto de dados, é preciso ter a permissão bigquery.datasets.create.
  • Para criar o recurso de conexão, você precisa das seguintes permissões:

    • bigquery.connections.create
    • bigquery.connections.get
  • Para conceder permissões à conta de serviço da conexão, você precisa da seguinte permissão:

    • resourcemanager.projects.setIamPolicy
  • Para criar a tabela de objetos, é preciso ter as seguintes permissões:

    • bigquery.tables.create
    • bigquery.tables.update
    • bigquery.connections.delegate
  • Para criar a função remota, você precisa das permissões associadas ao papel de Desenvolvedor do Cloud Functions.

  • Para invocar a função remota, é necessário ter o papel Invocador do Cloud Run.

  • Para analisar a tabela de objetos com a função remota, você precisa da permissão bigquery.tables.getData na tabela de objetos.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

  • BigQuery: incorrem em custos de armazenamento para a tabela que você cria no BigQuery.
  • Cloud Functions: você gera custos para invocar a função remota e os recursos de computação usados, incluindo chamadas para a API Cloud Vision.

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Consulte a página de preços do Cloud Storage para mais informações.

Para mais informações sobre preços de armazenamento do BigQuery, consulte Preços de armazenamento na documentação do BigQuery.

Para mais informações sobre preços do Cloud Functions, consulte a página Preços do Cloud Functions.

Para mais informações sobre preços da API Vision, consulte preços do Cloud Vision na documentação do Vision.

Antes de começar

  1. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  4. Ative as APIs BigQuery, BigQuery Connection API, and Cloud Functions.

    Ative as APIs

  5. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  6. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  7. Ative as APIs BigQuery, BigQuery Connection API, and Cloud Functions.

    Ative as APIs

Criar uma função do Cloud Functions

Para criar um PersistentVolumeClaim, siga estas etapas.

  1. Acesse a página Cloud Functions.

    Acesse o Cloud Functions

  2. Clique em Criar função.

  3. Em Ambiente, selecione segunda geração.

  4. Em Nome da função, digite vision-ai.

  5. Clique em Next.

  6. Em Ambiente de execução, selecione Python 3.9.

  7. Em Ponto de entrada, digite label_detection.

  8. Selecione main.py. Copie e cole este código:

    Python

    import urllib.request
    
    import flask
    import functions_framework
    from google.cloud import vision
    
    @functions_framework.http
    def label_detection(request: flask.Request) -> flask.Response:
        """BigQuery remote function to label input images.
        Args:
            request: HTTP request from BigQuery
            https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#input_format
        Returns:
            HTTP response to BigQuery
            https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#output_format
        """
        try:
            client = vision.ImageAnnotatorClient()
            calls = request.get_json()["calls"]
            replies = []
            for call in calls:
                content = urllib.request.urlopen(call[0]).read()
                results = client.label_detection({"content": content})
                replies.append(vision.AnnotateImageResponse.to_dict(results))
            return flask.make_response(flask.jsonify({"replies": replies}))
        except Exception as e:
            return flask.make_response(flask.jsonify({"errorMessage": str(e)}), 400)
    
    

  9. Selecione requirements.txt. Copie e cole na consulta a seguir:

    Flask==2.2.2
    functions-framework==3.3.0
    google-cloud-vision==3.4.2
    Werkzeug==2.3.7
    

  10. Selecione Implantar.

  11. Quando a implantação da função terminar, clique na guia Gatilho.

  12. Copie o valor de URL do gatilho e salve-o em algum lugar. Você vai precisar dessas informações ao criar a função remota.

crie um conjunto de dados

Crie um conjunto de dados chamado remote_function_test:

SQL

  1. Acessar a página do BigQuery.

    Ir para o BigQuery

  2. No painel Editor, execute a seguinte instrução SQL:

    CREATE SCHEMA `PROJECT_ID.remote_function_test`;
    

    Substitua PROJECT_ID pela ID do seu projeto.

bq

  1. No Console do Google Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

  2. Execute o comando bq mk para criar o usuário.

      bq mk --dataset --location=us PROJECT_ID:remote_function_test
      

    Substitua PROJECT_ID pela ID do seu projeto.

Crie uma conexão

Crie uma conexão chamada lake-connection:

Console

  1. Acessar a página do BigQuery.

    Ir para o BigQuery

  2. Clique em Adicionar dados e em Fonte de dados externa.

  3. Na lista Tipo de conexão, selecione BigLake e funções remotas (Recurso do Cloud).

  4. No campo ID da conexão, digite lake-connection.

  5. Clique em Criar conexão.

  6. No painel Informações da conexão, copie o valor do campo ID da conta de serviço e salve-o em algum lugar. Você precisa dessas informações para conceder permissões à conta de serviço da conexão.

bq

  1. No Cloud Shell, execute o comando bq mk para criar a conexão:

    bq mk --connection --location=us --connection_type=CLOUD_RESOURCE \
    lake-connection
    
  2. Execute o comando bq show para recuperar informações sobre a conexão:

    bq show --connection us.lake-connection
    
  3. Na coluna properties, copie o valor da propriedade serviceAccountId e salve-o em algum lugars Você precisa dessas informações para conceder permissões à conta de serviço da conexão.

Crie um bucket do Cloud Storage

Crie um bucket do Cloud Storage para conter o conjunto de dados de flores.

Conceder permissões para a conta de serviço do portal

Para conceder permissões à conta de serviço, siga estas etapas:

  1. Acessar a página AM e administrador

    Acessar IAM e administrador

  2. Clique em Conceder acesso.

    A caixa de diálogo Adicionar principais é aberta.

  3. No campo Novos principais, digite o ID da conta de serviço que você copiou anteriormente.

  4. No campo Selecionar papel, selecione Cloud Run e, em seguida, Invocador do Cloud Run.

  5. Clique em Adicionar outro papel.

  6. No campo Selecionar papel, escolha Cloud Storage e, em seguida, Visualizador de objetos do Storage.

  7. Clique em Save.

Fazer o upload do conjunto de dados para o Cloud Storage

Consiga os arquivos de conjunto de dados e disponibilize-os no Cloud Storage:

  1. Faça o download do conjunto de dados de flores na sua máquina local.
  2. Faça o upload do conjunto de dados para o bucket criado anteriormente.

Criar uma tabela de objetos

Crie uma tabela de objetos chamada sample_images com base no conjunto de dados de flores enviado:

SQL

  1. Acessar a página do BigQuery.

    Ir para o BigQuery

  2. No painel Editor, execute a seguinte instrução SQL:

    CREATE EXTERNAL TABLE remote_function_test.sample_images
    WITH CONNECTION `us.lake-connection`
    OPTIONS(
      object_metadata = 'SIMPLE',
      uris = ['gs://BUCKET_NAME/*']);
    

    Substitua BUCKET_NAME pelo nome do bucket que você acabou de criar.

bq

No Cloud Shell, execute o comando bq mk para criar a conexão:

bq mk --table \
--external_table_definition=gs:"//BUCKET_NAME/*@us.lake-connection" \
--object_metadata=SIMPLE \
remote_function_test.sample_images

Substitua BUCKET_NAME pelo nome do bucket que você acabou de criar.

Criar a função remota do BigQuery

Crie uma função remota chamada label_detection:

  1. Acessar a página do BigQuery.

    Ir para o BigQuery

  2. No painel Editor, execute a seguinte instrução SQL:

    CREATE OR REPLACE FUNCTION `remote_function_test.label_detection` (signed_url_ STRING) RETURNS JSON
    REMOTE WITH CONNECTION `us.lake-connection`
    OPTIONS(
    endpoint = 'TRIGGER_URL',
    max_batching_rows = 1
    );
    

    Substitua TRIGGER_URL pelo URL do gatilho que você salvou anteriormente. O URL precisa ser semelhante a https://vision-ai-1abcd2efgh-uc.a.run.app.

Chamar a função remota

Chame a função remota label_detection na tabela de objetos sample_images:

  1. Acessar a página do BigQuery.

    Ir para o BigQuery

  2. No painel Editor, execute a seguinte instrução SQL:

    SELECT uri, remote_function_test.label_detection(signed_url)
    FROM EXTERNAL_OBJECT_TRANSFORM(
    TABLE remote_function_test.sample_images,
    ["SIGNED_URL"]
    )
    LIMIT 100;
    

    A resposta deve ficar assim:

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | uri                                                           | f0_                                                                                                            |
    —---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    |  gs://bq_huron_demo/flowers/daisy/100080576_f52e8ee070_n.jpg  |  {"face_annotations":[],"label_annotations":[{"confidence":0.0,"description":"Flower",                         |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0c9ph5","properties":[],"score":0.9785631,"topicality":0.9785631},       |
    |                                                               |  {"confidence":0.0,"description":"Plant","locale":"","locations":[],"mid":"/m/05s2s","properties":[],          |
    |                                                               |  "Score":0.9635679,"topicality":0.9635679},{"confidence":0.0,"description":"camomile","locale":"",             |
    |                                                               |  "locations":[],"mid":"/m/011bc8hg","properties":[],"score":0.9110366,"topicality":0.9110366},                 |
    |                                                               |  {"confidence":0.0,"description":"Petal","locale":"","locations":[],"mid":"/m/016q19","properties":[],         |
    |                                                               |  "score":0.8927441,"topicality":0.8927441},{"confidence":0.0,"description":"Chamaemelum nobile","locale":"",   |
    |                                                               |  "locations":[],"mid":"/m/05cmcg","properties":[],"score":0.8460995,"topicality":0.8460995},                   |
    |                                                               |   {"confidence":0.0,"description":"Flowering plant","locale":"","locations":[],"mid":"/m/04sjm",               |
    |                                                               |  "properties":[],"score":0.7642974,"topicality":0.7642974},{"confidence":0.0,"description":"Annual plant",     |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0jqb","properties":[],"score":0.7478164,                                 |
    |                                                               |  "topicality":0.7478164},{"confidence":0.0,"description":"Close-up","locale":"","locations":[],                |
    |                                                               |  "mid":"/m/02cqfm","properties":[],"score":0.7207553,"topicality":0.7207553},{"confidence":0.0,                |
    |                                                               |  "description":"Oxeye daisy","locale":"","locations":[],"mid":"/m/02qvnf","properties":[],                     |
    |                                                               |  "score":0.71786934,"topicality":0.71786934},{"confidence":0.0,"description":"Daisy family","locale":"",       |
    |                                                               |  "locations":[],"mid":"/m/0l5r","properties":[],"score":0.7164383,"topicality":0.7164383}],                    |
    |                                                               |  "landmark_annotations":[],"localized_object_annotations":[],"logo_annotations":[],"text_annotations":[]}      |
    —---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | gs://bq_huron_demo/flowers/daisy/10140303196_b88d3d6cec.jpg   |  {"face_annotations":[],"label_annotations":[{"confidence":0.0,"description":"Flower","locale":"",             |
    |                                                               |  "locations":[],"mid":"/m/0c9ph5","properties":[],"score":0.9770426,"topicality":0.9770426},                   |
    |                                                               |  {"confidence":0.0,"description":"Plant","locale":"","locations":[],"mid":"/m/05s2s",                          |
    |                                                               |  "Properties":[],"score":0.95798975,"topicality":0.95798975},{"confidence":0.0,                                |
    |                                                               |  "description":"Petal","locale":"","locations":[],"mid":"/m/016q19","properties":[],                           |
    |                                                               |  "score":0.88984144,"topicality":0.88984144},{"confidence":0.0,"description":"Yellow",                         |
    |                                                               |  "locale":"","locations":[],"mid":"/m/088fh","properties":[],"score":0.84456813,                               |
    |                                                               |  "Topicality":0.84456813},{"confidence":0.0,"description":"camomile","locale":"",                              |
    |                                                               |  "locations":[],"mid":"/m/011bc8hg","properties":[],"score":0.7926449, "topicality":0.7926449},                |
    |                                                               |  {"confidence":0.0,"description":"Annual plant","locale":"","locations":[],"mid":"/m/0jqb",                    |
    |                                                               |  "Properties":[],"score":0.75020844, "topicality":0.75020844},{"confidence":0.0,                               |
    |                                                               |  "description":"Flowering plant","locale":"","locations":[],"mid":"/m/04sjm",                                  |
    |                                                               |  "Properties":[],"score":0.7403478,"topicality":0.7403478},{"confidence":0.0,                                  |
    |                                                               |  "description":"Chamaemelum nobile","locale":"","locations":[],"mid":"/m/05cmcg",                              |
    |                                                               |  "Properties":[],"score":0.7264577,"topicality":0.7264577},{"confidence":0.0,                                  |
    |                                                               |  "description":"Close-up","locale":"","locations":[],"mid":"/m/02cqfm","properties":[],                        |
    |                                                               |  "score":0.721242,"topicality":0.721242},{"confidence":0.0,"description":"Daisy family",                       |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0l5r","properties":[],"score":0.7012979,                                 |
    |                                                               |  "Topicality":0.7012979}],"landmark_annotations":[],"localized_object_annotations":[],                         |
    |                                                               |  "logo_annotations":[],"text_annotations":[]}                                                                  |
    —------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------
    
    

Limpar

  1. No Console do Google Cloud, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.