Anleitung: Objekttabelle mit einer Remotefunktion analysieren

In dieser Anleitung erfahren Sie, wie Sie eine Objekttabelle auf Basis der Bilder aus dem Blumen-Dataset und eine Remotefunktion, die Bilder mit der Cloud Vision API mit Labels versieht, erstellen, um dann die Bilder in der Objekttabelle mit der Remotefunktion analysieren.

Erforderliche Berechtigungen

  • Zum Erstellen des Datasets benötigen Sie die Berechtigung bigquery.datasets.create.
  • Zum Erstellen der Verbindungsressource benötigen Sie die folgenden Berechtigungen:

    • bigquery.connections.create
    • bigquery.connections.get
  • Zum Erteilen von Berechtigungen für das Dienstkonto der Verbindung benötigen Sie die folgende Berechtigung:

    • resourcemanager.projects.setIamPolicy
  • Zum Erstellen der Objekttabelle benötigen Sie die folgenden Berechtigungen:

    • bigquery.tables.create
    • bigquery.tables.update
    • bigquery.connections.delegate
  • Zum Erstellen der Remote-Funktion benötigen Sie die Berechtigungen, die der Rolle Cloud Functions-Entwickler zugeordnet sind.

  • Zum Aufrufen der Remote-Funktion benötigen Sie die Rolle Cloud Run Invoker.

  • Zum Analysieren der Objekttabelle mit der Remote-Funktion benötigen Sie die bigquery.tables.getData-Berechtigung für die Objekttabelle.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

  • BigQuery: Für die Objekttabelle, die Sie in BigQuery erstellen, fallen Speicherkosten an.
  • Cloud Functions: Für das Aufrufen der Remote-Funktion und alle verwendeten Rechenressourcen fallen Kosten an, einschließlich der Aufrufe an die Cloud Vision API.

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Weitere Informationen zu den Preisen von Cloud Storage erhalten Sie auf der Seite Cloud Storage – Preise.

Weitere Informationen zu BigQuery-Speicherpreisen finden Sie unter Speicherpreise in der BigQuery-Dokumentation.

Weitere Informationen zu den Preisen von Cloud Functions finden Sie auf der Seite Preise für Cloud Functions.

Weitere Informationen zu den Preisen der Vision API finden Sie in der Vision-Dokumentation unter Cloud Vision-Preise.

Hinweis

  1. Melden Sie sich bei Ihrem Google Cloud-Konto an. Wenn Sie mit Google Cloud noch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  4. BigQuery, BigQuery Connection API, and Cloud Functions APIs aktivieren.

    Aktivieren Sie die APIs

  5. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  6. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  7. BigQuery, BigQuery Connection API, and Cloud Functions APIs aktivieren.

    Aktivieren Sie die APIs

Cloud Functions-Funktion erstellen

So erstellen Sie eine Funktion:

  1. Zur Seite "Cloud Functions"

    Zu Cloud Functions

  2. Klicken Sie auf Funktion erstellen.

  3. Wählen Sie für Umgebung 2. Generation aus.

  4. Geben Sie als Funktionsname vision-ai ein.

  5. Klicken Sie auf Next (Weiter).

  6. Wählen Sie als Laufzeit Python 3.9.

  7. Geben Sie als Einstiegspunkt label_detection ein.

  8. Wählen Sie main.py aus. Kopieren Sie folgenden Code und fügen Sie ihn ein:

    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. Wählen Sie requirements.txt aus. Kopieren Sie den folgenden Text und fügen Sie ihn ein:

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

  10. Klicken Sie auf Bereitstellen.

  11. Wenn die Bereitstellung der Funktion abgeschlossen ist, klicken Sie auf den Tab Trigger.

  12. Kopieren Sie den Wert für die Trigger-URL und speichern Sie ihn an einem beliebigen Ort. Sie benötigen diese Informationen, wenn Sie die Remote-Funktion erstellen.

Dataset erstellen

Erstellen Sie ein Dataset mit dem Namen remote_function_test:

SQL

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Führen Sie im Bereich Editor die folgende SQL-Anweisung aus:

    CREATE SCHEMA `PROJECT_ID.remote_function_test`;
    

    Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID.

bq

  1. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

  2. Erstellen Sie das Dataset mit dem Befehl bq mk.

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

    Ersetzen Sie PROJECT_ID durch Ihre Projekt-ID.

Verbindung herstellen

Erstellen Sie eine Verbindung mit dem Namen lake-connection:

Console

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Klicken Sie auf Daten hinzufügen und dann auf Externe Datenquelle.

  3. Wählen Sie in der Liste Verbindungstyp die Option BigLake und Remotefunktionen (Cloud Resource) aus.

  4. Geben Sie im Feld Verbindungs-ID lake-connection ein.

  5. Klicken Sie auf Verbindung erstellen.

  6. Kopieren Sie im Bereich Verbindungsinformationen den Wert aus dem Feld Dienstkonto-ID und speichern Sie ihn an einem beliebigen Ort. Sie benötigen diese Informationen, um dem Dienstkonto der Verbindung Berechtigungen zu erteilen.

bq

  1. Führen Sie in Cloud Shell den bq mk-Befehl aus, um die Verbindung zu erstellen:

    bq mk --connection --location=us --connection_type=CLOUD_RESOURCE \
    lake-connection
    
  2. Führen Sie den bq show-Befehl aus, um Informationen über die Verbindung abzurufen:

    bq show --connection us.lake-connection
    
  3. Kopieren Sie aus der properties-Spalte den Wert des serviceAccountId-Attributs und speichern Sie ihn an einem beliebigen Ort. Sie benötigen diese Informationen, um dem Dienstkonto der Verbindung Berechtigungen zu erteilen.

Cloud Storage-Bucket erstellen

Erstellen Sie einen Cloud Storage-Bucket für das Blumen-Dataset.

Dem Dienstkonto der Verbindung Berechtigungen gewähren

So gewähren Sie dem Dienstkonto Berechtigungen:

  1. Zur Seite IAM & Verwaltung.

    IAM & Verwaltung aufrufen

  2. Klicken Sie auf Zugriff erlauben.

    Das Dialogfeld Principals hinzufügen wird geöffnet.

  3. Geben Sie im Feld Neue Hauptkonten die Dienstkonto-ID ein, die Sie zuvor kopiert haben.

  4. Wählen Sie im Feld Rolle auswählen Cloud Run und dann Cloud Run Invoker aus.

  5. Klicken Sie auf Weitere Rolle hinzufügen.

  6. Wählen Sie im Feld Rolle auswählen die Option Cloud Storage und dann Storage-Objekt-Betrachter aus.

  7. Klicken Sie auf Speichern.

Dataset in Cloud Storage hochladen

Rufen Sie die Dataset-Dateien ab und stellen Sie sie in Cloud Storage bereit:

  1. Laden Sie das Blumen-Dataset auf Ihren lokalen Computer herunter.
  2. Laden Sie das Dataset in den zuvor erstellten Bucket hoch.

Objekttabelle erstellen

Erstellen Sie eine Objekttabelle mit dem Namen sample_images anhand des hochgeladenen Blumen-Datasets:

SQL

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Führen Sie im Bereich Editor die folgende SQL-Anweisung aus:

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

    Ersetzen Sie BUCKET_NAME durch den Namen des Buckets, den Sie zuvor erstellt haben.

bq

Führen Sie in Cloud Shell den bq mk-Befehl aus, um die Verbindung zu erstellen:

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

Ersetzen Sie BUCKET_NAME durch den Namen des Buckets, den Sie zuvor erstellt haben.

BigQuery-Remote-Funktion erstellen

Erstellen Sie eine Remote-Funktion mit dem Namen label_detection:

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Führen Sie im Bereich Editor die folgende SQL-Anweisung aus:

    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
    );
    

    Ersetzen Sie TRIGGER_URL durch die zuvor gespeicherte Trigger-URL. Die URL sollte in etwa so aussehen: https://vision-ai-1abcd2efgh-uc.a.run.app.

Remote-Funktion aufrufen

Rufen Sie die Remote-Funktion label_detection auf der sample_images-Objekttabelle auf:

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Führen Sie im Bereich Editor die folgende SQL-Anweisung aus:

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

    Die Antwort sollte in etwa so aussehen:

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | 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":[]}                                                                  |
    —------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------
    
    

Bereinigen

  1. Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.

    Zur Seite „Ressourcen verwalten“

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.