標籤偵測教學課程

目標對象

本教學課程旨在協助您使用 Video Intelligence API 開始探索及開發應用程式。本課程旨在協助對 Python 有基本瞭解的使用者。即使您對程式設計只有粗淺的認識,也應能跟得上課程。完成本教學課程後,您應能使用參考資料說明文件建立自己的基本應用程式。

本教學課程採用 Python 程式碼逐步操作 Video Intelligence API 應用程式。本文目的並非提供 Python 用戶端程式庫的相關說明,而是解釋如何使用影片標籤偵測功能呼叫 Video Intelligence API。Java 和 Node.js 的應用程式大致類似。

如果您要尋找只有程式碼的範例或其他程式語言的範例,請參閱隨附的教學指南

必要條件

本教學課程的必備條件如下:

使用標籤偵測為影片加上註解

本教學課程會透過 LABEL_DETECTION 要求逐步引導您操作基本的 Video API 應用程式。LABEL_DETECTION 要求會使用依據圖片內容選取的標籤 (或「標記」) 為影片加上註解。例如,平交道上的火車影片可能產生「火車」、「運輸」、「鐵路平交道」等的標籤。

以下是本教學課程所需的完整程式碼。我們已從這段程式碼中移除大部分的註解,以凸顯程式碼的簡潔性。稍後我們會在檢閱程式碼時提供註解。

import argparse

from google.cloud import videointelligence



def analyze_labels(path):
    """Detects labels given a GCS path."""
    video_client = videointelligence.VideoIntelligenceServiceClient()
    features = [videointelligence.Feature.LABEL_DETECTION]
    operation = video_client.annotate_video(
        request={"features": features, "input_uri": path}
    )
    print("\nProcessing video for label annotations:")

    result = operation.result(timeout=90)
    print("\nFinished processing.")

    segment_labels = result.annotation_results[0].segment_label_annotations
    for i, segment_label in enumerate(segment_labels):
        print("Video label description: {}".format(segment_label.entity.description))
        for category_entity in segment_label.category_entities:
            print(
                "\tLabel category description: {}".format(category_entity.description)
            )

        for i, segment in enumerate(segment_label.segments):
            start_time = (
                segment.segment.start_time_offset.seconds
                + segment.segment.start_time_offset.microseconds / 1e6
            )
            end_time = (
                segment.segment.end_time_offset.seconds
                + segment.segment.end_time_offset.microseconds / 1e6
            )
            positions = "{}s to {}s".format(start_time, end_time)
            confidence = segment.confidence
            print("\tSegment {}: {}".format(i, positions))
            print("\tConfidence: {}".format(confidence))
        print("\n")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("path", help="GCS file path for label detection.")
    args = parser.parse_args()

    analyze_labels(args.path)

此簡易應用程式會執行下列工作:

  1. 匯入執行應用程式時需要的程式庫。
  2. 使用儲存在 Cloud Storage URI 的影片檔做為引數,並傳送至 main() 函式。
  3. 取得執行 Video Intelligence API 服務的憑證。
  4. 建立要傳送至影片服務的影片註解要求。
  5. 傳送要求並傳回長時間執行作業。
  6. 循環執行長時間執行的作業,直到影片處理完成並傳回可用的值。
  7. 剖析服務回應,並向使用者顯示回應。

匯入程式庫

import argparse

from google.cloud import videointelligence

我們匯入了一些標準程式庫:argparse,允許應用程式接受輸入檔案名稱做為引數,而 sys 可在等待 API 回應時格式化輸出。匯入 time 套件以執行一些簡單的等待迴圈。

使用 Video Intelligence API 時,您也必須匯入 google.cloud.videointelligence_v1 及其列舉類別,其中含有我們的 API 呼叫目錄。

執行應用程式

parser = argparse.ArgumentParser(
    description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("path", help="GCS file path for label detection.")
args = parser.parse_args()

analyze_labels(args.path)

在這裡,系統會針對影片檔案名稱的 Cloud Storage URI 剖析傳遞的引數,然後將該引數傳遞至 main() 函式。

向 API 進行驗證

與 Video Intelligence API 服務通訊之前,您必須使用之前取得的憑證驗證服務。要在應用程式中取得憑證,最簡單的方式是使用應用程式預設憑證 (ADC)。根據預設,ADC 會嘗試從 GOOGLE_APPLICATION_CREDENTIALS 環境檔案取得憑證,憑證應設定為指向服務帳戶的 JSON 金鑰檔案。(您應該已在快速入門中設定使用 ADC 的服務帳戶與環境。

建立要求

video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.LABEL_DETECTION]
operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)

在 Video Intelligence API 服務準備就緒後,即可建立要對這項服務發出的要求。系統會以 JSON 物件的形式將要求提供給 Video Intelligence API。如需這類要求的特定結構完整資訊,請參閱 Video Intelligence API 參考資料

這個程式碼片段會執行下列工作:

  1. 建立 POST 要求的 JSON 以傳送至 annotate_video() 方法。
  2. 將傳遞的影片檔案名稱所在的 Cloud Storage 位置插入要求中。
  3. 指出 annotate 方法應執行 LABEL_DETECTION

檢查作業

result = operation.result(timeout=90)
print("\nFinished processing.")

透過現有作業的現有作業要求,建立 while 迴圈以定期檢查這項作業的狀態。只要作業指出作業狀態為 done 時,系統就會剖析回應。

剖析回應

segment_labels = result.annotation_results[0].segment_label_annotations
for i, segment_label in enumerate(segment_labels):
    print("Video label description: {}".format(segment_label.entity.description))
    for category_entity in segment_label.category_entities:
        print(
            "\tLabel category description: {}".format(category_entity.description)
        )

    for i, segment in enumerate(segment_label.segments):
        start_time = (
            segment.segment.start_time_offset.seconds
            + segment.segment.start_time_offset.microseconds / 1e6
        )
        end_time = (
            segment.segment.end_time_offset.seconds
            + segment.segment.end_time_offset.microseconds / 1e6
        )
        positions = "{}s to {}s".format(start_time, end_time)
        confidence = segment.confidence
        print("\tSegment {}: {}".format(i, positions))
        print("\tConfidence: {}".format(confidence))
    print("\n")

作業完成後,回應會在 AnnotateVideoResponse 中包含結果,其中包含 annotationResults 清單,每個 annotationResults 代表要求中傳送的一部影片。因為要求中只傳送了一部影片,所以會採取結果的第一個 segmentLabelAnnotations,並循環處理 segmentLabelAnnotations 中的所有標籤。本教學課程只使用 segmentLabelAnnotations,因此只會顯示影片層級的註解。每個 segment_label 都包含說明 (segment_label.description)、實體類別清單 (segment_label.category_entities),以及片段清單,用於標示影片中標籤出現的開始/結束時間 (在 segment_label_annotations 的情況下,應為跨越整部影片的一個片段或影片片段)。

{
   "name":"us-west1.12089999971048628582",
   "metadata":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress",
      "annotationProgress":[
         {
            "inputUri":"gs://YOUR_BUCKET/YOUR_OBJECT",
            "updateTime":"2020-01-31T01:49:52.498015Z",
            "startTime":"2020-01-31T01:49:43.056481Z"
         }
      ]
   },
   "done": true,
   "response":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse",
      "annotationResults":[
         {
            "inputUri":"gs://YOUR_BUCKET/YOUR_OBJECT",
            "segmentLabelAnnotations": [
              {
                "entity": {
                  "entityId": "/m/01yrx",
                  "languageCode": "en-US"
                },
                "segments": [
                  {
                    "segment": {
                      "startTimeOffset": "0s",
                      "endTimeOffset": "14.833664s"
                    },
                    "confidence": 0.98509187
                  }
                ]
              },
               ...
            ]
         }
      ]
   }
}

因為要求中只傳送了一部影片,所以會列印第一個結果的第一個 description

執行應用程式

如要執行您的應用程式,只要將影片的 Cloud Storage URI 傳送給該應用程式即可:

$ python labels.py gs://YOUR_BUCKET/YOUR_OBJECT
Operation us-west1.4757250774497581229 started: 2020-01-30T01:46:30.158989Z
Operation processing ...
The video has been successfully processed.

Video label description: urban area
        Label category description: city
        Segment 0: 0.0s to 38.752016s
        Confidence: 0.946980476379


Video label description: traffic
        Segment 0: 0.0s to 38.752016s
        Confidence: 0.94105899334


Video label description: vehicle
        Segment 0: 0.0s to 38.752016s
        Confidence: 0.919958174229
...
 

輸出

以下是可能的輸出內容範例。

Processing video for label annotations:

Finished processing. Video label description: crowd Label category description: people Segment 0: 0.0s to 60.24s Confidence: 0.527720749378

Video label description: official Label category description: person Segment 0: 0.0s to 60.24s Confidence: 0.372822880745

Video label description: audience Label category description: people Segment 0: 0.0s to 60.24s Confidence: 0.501719772816

Video label description: news Segment 0: 0.0s to 60.24s Confidence: 0.867252230644

Video label description: people Label category description: person Segment 0: 0.0s to 60.24s Confidence: 0.46747264266

Video label description: politics Segment 0: 0.0s to 60.24s Confidence: 0.319397002459

恭喜!您已透過 Video Intelligence API 完成了註解工作!