标签检测教程

受众

本教程旨在帮助您开始使用 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 服务已准备就绪,您可以构建要发送至该服务的请求。向 Video Intelligence API 发出的请求是作为 JSON 对象提供的。如需全面了解此类请求的具体结构,请参阅 Video Intelligence API 参考

此代码段执行以下任务:

  1. 为发送到 annotate_video() 方法的 POST 请求构造 JSON。
  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 列表,在请求中发送的每个视频各有一个结果)。由于请求中仅发送了一个视频,因此系统会选取结果的第一个 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 执行了注释任务!