オブジェクト トラッキングは、入力された動画で検出されたオブジェクトを追跡します。オブジェクト トラッキング リクエストを行うには、annotate
メソッドを呼び出し、features
フィールドで OBJECT_TRACKING
を指定します。
動画または動画セグメントで検出されたエンティティと空いた場所の場合、オブジェクト トラッキング リクエストでは、これらのエンティティと空いた場所に対する適切なラベルで動画にアノテーションが付けられます。たとえば、信号を通過する車両の動画では、「car」、「truck」、「bike」、「tires」、「lights」、「window」などのラベルが生成されます。各ラベルには一連の境界ボックスがあり、各境界ボックスには時間セグメントが関連付けられています。時間セグメントには、動画の先頭からの時間を示す時間オフセットが含まれています。また、アノテーションには、追加のエンティティ情報も含まれます。たとえば、その情報を使用すると、Google Knowledge Graph Search API でエンティティの詳細を確認できる、エンティティ ID などがあります。
オブジェクト トラッキングとラベル検出
オブジェクト トラッキングとラベル検出は異なります。ラベル検出では、境界ボックスのないラベルが提供されるのに対し、オブジェクト トラッキングでは、動画上に存在する個々のオブジェクトのラベルに加え、各オブジェクト インスタンスの境界ボックスもタイムスタンプごとに表示されます。
同じオブジェクト タイプの複数のインスタンスが、ObjectTrackingAnnotation
メッセージの別々のインスタンスに割り当てられ、指定されたオブジェクト トラックのすべての出現が、ObjectTrackingAnnotation
のそれぞれ固有のインスタンスに保持されます。たとえば、動画内に赤い車と青い車の 5 秒間の表示がある場合、トラッキング リクエストにより、ObjectTrackingAnnotation
の 2 つのインスタンスが返されます。最初のインスタンスには赤と青の 2 台の車のいずれかの位置が含まれ、2 番目のインスタンスにはもう片方の車の位置が含まれます。
Cloud Storage 上の動画のオブジェクト トラッキングをリクエストする
次のサンプルは、Cloud Storage に存在するファイルのオブジェクト トラッキングを示しています。
REST
プロセス リクエストを送信する
POST
リクエストを annotate
メソッドに送信する方法を以下に示します。この例では、Google Cloud CLI を使用するプロジェクト用に設定されたサービス アカウントのアクセス トークンを使用します。Google Cloud CLI のインストール、サービス アカウントでのプロジェクトの設定、アクセス トークンの取得を行う手順については、Video Intelligence のクイックスタートをご覧ください。
リクエストのデータを使用する前に、次のように置き換えます。
- INPUT_URI: STORAGE_URI
次に例を示します。
"inputUri": "gs://cloud-videointelligence-demo/assistant.mp4",
- PROJECT_NUMBER: Google Cloud プロジェクトの数値識別子。
HTTP メソッドと URL:
POST https://videointelligence.googleapis.com/v1/videos:annotate
リクエストの本文(JSON):
{ "inputUri": "STORAGE_URI", "features": ["OBJECT_TRACKING"] }
リクエストを送信するには、次のいずれかのオプションを展開します。
curl(Linux、macOS、Cloud Shell)
リクエスト本文を request.json
という名前のファイルに保存して、次のコマンドを実行します。
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://videointelligence.googleapis.com/v1/videos:annotate"
PowerShell(Windows)
リクエスト本文を request.json
という名前のファイルに保存して、次のコマンドを実行します。
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://videointelligence.googleapis.com/v1/videos:annotate" | Select-Object -Expand Content
次のような JSON レスポンスが返されます。
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID" }
リクエストが成功すると、Video Intelligence API はオペレーションの name
を返します。上記はレスポンスの例です。PROJECT_NUMBER
はプロジェクトの番号、OPERATION_ID
はリクエストに対して作成された長時間実行オペレーションの ID です。
結果を取得する
リクエストの結果を取得するには、以下の例に示すように、videos:annotate
の呼び出しで返されたオペレーション名を使用して GET
を送信します。
リクエストのデータを使用する前に、次のように置き換えます。
- OPERATION_NAME: Video Intelligence API によって返されるオペレーションの名前。オペレーション名の形式は
projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID
です。 - PROJECT_NUMBER: Google Cloud プロジェクトの数値識別子。
HTTP メソッドと URL:
GET https://videointelligence.googleapis.com/v1/OPERATION_NAME
リクエストを送信するには、次のいずれかのオプションを展開します。
curl(Linux、macOS、Cloud Shell)
次のコマンドを実行します。
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
"https://videointelligence.googleapis.com/v1/OPERATION_NAME"
PowerShell(Windows)
次のコマンドを実行します。
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }
Invoke-WebRequest `
-Method GET `
-Headers $headers `
-Uri "https://videointelligence.googleapis.com/v1/OPERATION_NAME" | Select-Object -Expand Content
次のような JSON レスポンスが返されます。
レスポンス
// Object tracking annotations are returned as a objectAnnotations
list.
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress",
"annotationProgress": [
{
"inputUri": "/cloud-ml-sandbox/video/chicago.mp4",
"progressPercent": 100,
"startTime": "2019-12-21T16:56:46.755199Z",
"updateTime": "2019-12-21T16:59:17.911197Z"
}
]
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse",
"annotationResults": [
{
"inputUri": "/cloud-ml-sandbox/video/chicago.mp4",
"objectAnnotations": [
{
"entity": {
"entityId": "/m/0k4j",
"description": "car",
"languageCode": "en-US"
},
"frames": [
{
"normalizedBoundingBox": {
"left": 0.2672763,
"top": 0.5677657,
"right": 0.4388713,
"bottom": 0.7623171
},
"timeOffset": "0s"
},
{
"normalizedBoundingBox": {
"left": 0.26920167,
"top": 0.5659805,
"right": 0.44331276,
"bottom": 0.76780635
},
"timeOffset": "0.100495s"
},
...
{
"normalizedBoundingBox": {
"left": 0.83573246,
"top": 0.6645812,
"right": 1,
"bottom": 0.99865407
},
"timeOffset": "2.311402s"
}
],
"segment": {
"startTimeOffset": "0s",
"endTimeOffset": "2.311402s"
},
"confidence": 0.99488896
},
...
{
"entity": {
"entityId": "/m/0cgh4",
"description": "building",
"languageCode": "en-US"
},
"frames": [
{
"normalizedBoundingBox": {
"left": 0.12340179,
"top": 0.010383379,
"right": 0.21914443,
"bottom": 0.5591795
},
"timeOffset": "0s"
},
{
"normalizedBoundingBox": {
"left": 0.12340179,
"top": 0.009684974,
"right": 0.22915152,
"bottom": 0.56070584
},
"timeOffset": "0.100495s"
},
...
{
"normalizedBoundingBox": {
"left": 0.12340179,
"top": 0.008624528,
"right": 0.22723165,
"bottom": 0.56158626
},
"timeOffset": "0.401983s"
}
],
"segment": {
"startTimeOffset": "0s",
"endTimeOffset": "0.401983s"
},
"confidence": 0.33914912
},
...
{
"entity": {
"entityId": "/m/0cgh4",
"description": "building",
"languageCode": "en-US"
},
"frames": [
{
"normalizedBoundingBox": {
"left": 0.79324204,
"top": 0.0006896425,
"right": 0.99659824,
"bottom": 0.5324423
},
"timeOffset": "37.585421s"
},
{
"normalizedBoundingBox": {
"left": 0.78935236,
"top": 0.0011992548,
"right": 0.99659824,
"bottom": 0.5374946
},
"timeOffset": "37.685917s"
},
...
{
"normalizedBoundingBox": {
"left": 0.79404694,
"right": 0.99659824,
"bottom": 0.5280966
},
"timeOffset": "38.590379s"
}
],
"segment": {
"startTimeOffset": "37.585421s",
"endTimeOffset": "38.590379s"
},
"confidence": 0.3415429
}
]
}
]
}
}
アノテーションの結果をダウンロードする
アノテーションを、送信元バケットから送信先バケットにコピーします(ファイルとオブジェクトのコピーをご覧ください)。
gsutil cp gcs_uri gs://my-bucket
注: 出力 GCS URI がユーザーによって指定された場合、アノテーションはその GCS URI に格納されます。
Go
import (
"context"
"fmt"
"io"
video "cloud.google.com/go/videointelligence/apiv1"
videopb "cloud.google.com/go/videointelligence/apiv1/videointelligencepb"
"github.com/golang/protobuf/ptypes"
)
// objectTrackingGCS analyzes a video and extracts entities with their bounding boxes.
func objectTrackingGCS(w io.Writer, gcsURI string) error {
// gcsURI := "gs://cloud-samples-data/video/cat.mp4"
ctx := context.Background()
// Creates a client.
client, err := video.NewClient(ctx)
if err != nil {
return fmt.Errorf("video.NewClient: %w", err)
}
defer client.Close()
op, err := client.AnnotateVideo(ctx, &videopb.AnnotateVideoRequest{
InputUri: gcsURI,
Features: []videopb.Feature{
videopb.Feature_OBJECT_TRACKING,
},
})
if err != nil {
return fmt.Errorf("AnnotateVideo: %w", err)
}
resp, err := op.Wait(ctx)
if err != nil {
return fmt.Errorf("Wait: %w", err)
}
// Only one video was processed, so get the first result.
result := resp.GetAnnotationResults()[0]
for _, annotation := range result.ObjectAnnotations {
fmt.Fprintf(w, "Description: %q\n", annotation.Entity.GetDescription())
if len(annotation.Entity.EntityId) > 0 {
fmt.Fprintf(w, "\tEntity ID: %q\n", annotation.Entity.GetEntityId())
}
segment := annotation.GetSegment()
start, _ := ptypes.Duration(segment.GetStartTimeOffset())
end, _ := ptypes.Duration(segment.GetEndTimeOffset())
fmt.Fprintf(w, "\tSegment: %v to %v\n", start, end)
fmt.Fprintf(w, "\tConfidence: %f\n", annotation.GetConfidence())
// Here we print only the bounding box of the first frame in this segment.
frame := annotation.GetFrames()[0]
seconds := float32(frame.GetTimeOffset().GetSeconds())
nanos := float32(frame.GetTimeOffset().GetNanos())
fmt.Fprintf(w, "\tTime offset of the first frame: %fs\n", seconds+nanos/1e9)
box := frame.GetNormalizedBoundingBox()
fmt.Fprintf(w, "\tBounding box position:\n")
fmt.Fprintf(w, "\t\tleft : %f\n", box.GetLeft())
fmt.Fprintf(w, "\t\ttop : %f\n", box.GetTop())
fmt.Fprintf(w, "\t\tright : %f\n", box.GetRight())
fmt.Fprintf(w, "\t\tbottom: %f\n", box.GetBottom())
}
return nil
}
Java
/**
* Track objects in a video.
*
* @param gcsUri the path to the video file to analyze.
*/
public static VideoAnnotationResults trackObjectsGcs(String gcsUri) throws Exception {
try (VideoIntelligenceServiceClient client = VideoIntelligenceServiceClient.create()) {
// Create the request
AnnotateVideoRequest request =
AnnotateVideoRequest.newBuilder()
.setInputUri(gcsUri)
.addFeatures(Feature.OBJECT_TRACKING)
.setLocationId("us-east1")
.build();
// asynchronously perform object tracking on videos
OperationFuture<AnnotateVideoResponse, AnnotateVideoProgress> future =
client.annotateVideoAsync(request);
System.out.println("Waiting for operation to complete...");
// The first result is retrieved because a single video was processed.
AnnotateVideoResponse response = future.get(450, TimeUnit.SECONDS);
VideoAnnotationResults results = response.getAnnotationResults(0);
// Get only the first annotation for demo purposes.
ObjectTrackingAnnotation annotation = results.getObjectAnnotations(0);
System.out.println("Confidence: " + annotation.getConfidence());
if (annotation.hasEntity()) {
Entity entity = annotation.getEntity();
System.out.println("Entity description: " + entity.getDescription());
System.out.println("Entity id:: " + entity.getEntityId());
}
if (annotation.hasSegment()) {
VideoSegment videoSegment = annotation.getSegment();
Duration startTimeOffset = videoSegment.getStartTimeOffset();
Duration endTimeOffset = videoSegment.getEndTimeOffset();
// Display the segment time in seconds, 1e9 converts nanos to seconds
System.out.println(
String.format(
"Segment: %.2fs to %.2fs",
startTimeOffset.getSeconds() + startTimeOffset.getNanos() / 1e9,
endTimeOffset.getSeconds() + endTimeOffset.getNanos() / 1e9));
}
// Here we print only the bounding box of the first frame in this segment.
ObjectTrackingFrame frame = annotation.getFrames(0);
// Display the offset time in seconds, 1e9 converts nanos to seconds
Duration timeOffset = frame.getTimeOffset();
System.out.println(
String.format(
"Time offset of the first frame: %.2fs",
timeOffset.getSeconds() + timeOffset.getNanos() / 1e9));
// Display the bounding box of the detected object
NormalizedBoundingBox normalizedBoundingBox = frame.getNormalizedBoundingBox();
System.out.println("Bounding box position:");
System.out.println("\tleft: " + normalizedBoundingBox.getLeft());
System.out.println("\ttop: " + normalizedBoundingBox.getTop());
System.out.println("\tright: " + normalizedBoundingBox.getRight());
System.out.println("\tbottom: " + normalizedBoundingBox.getBottom());
return results;
}
}
Node.js
Video Intelligence への認証を行うには、アプリケーションのデフォルト認証情報を設定します。 詳細については、ローカル開発環境の認証の設定をご覧ください。
// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/video-intelligence');
// Creates a client
const video = new Video.VideoIntelligenceServiceClient();
/**
* TODO(developer): Uncomment the following line before running the sample.
*/
// const gcsUri = 'GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4';
const request = {
inputUri: gcsUri,
features: ['OBJECT_TRACKING'],
//recommended to use us-east1 for the best latency due to different types of processors used in this region and others
locationId: 'us-east1',
};
// Detects objects in a video
const [operation] = await video.annotateVideo(request);
const results = await operation.promise();
console.log('Waiting for operation to complete...');
//Gets annotations for video
const annotations = results[0].annotationResults[0];
const objects = annotations.objectAnnotations;
objects.forEach(object => {
console.log(`Entity description: ${object.entity.description}`);
console.log(`Entity id: ${object.entity.entityId}`);
const time = object.segment;
console.log(
`Segment: ${time.startTimeOffset.seconds || 0}` +
`.${(time.startTimeOffset.nanos / 1e6).toFixed(0)}s to ${
time.endTimeOffset.seconds || 0
}.` +
`${(time.endTimeOffset.nanos / 1e6).toFixed(0)}s`
);
console.log(`Confidence: ${object.confidence}`);
const frame = object.frames[0];
const box = frame.normalizedBoundingBox;
const timeOffset = frame.timeOffset;
console.log(
`Time offset for the first frame: ${timeOffset.seconds || 0}` +
`.${(timeOffset.nanos / 1e6).toFixed(0)}s`
);
console.log('Bounding box position:');
console.log(` left :${box.left}`);
console.log(` top :${box.top}`);
console.log(` right :${box.right}`);
console.log(` bottom :${box.bottom}`);
});
Python
"""Object tracking in a video stored on GCS."""
from google.cloud import videointelligence
video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.OBJECT_TRACKING]
operation = video_client.annotate_video(
request={"features": features, "input_uri": gcs_uri}
)
print("\nProcessing video for object annotations.")
result = operation.result(timeout=500)
print("\nFinished processing.\n")
# The first result is retrieved because a single video was processed.
object_annotations = result.annotation_results[0].object_annotations
for object_annotation in object_annotations:
print("Entity description: {}".format(object_annotation.entity.description))
if object_annotation.entity.entity_id:
print("Entity id: {}".format(object_annotation.entity.entity_id))
print(
"Segment: {}s to {}s".format(
object_annotation.segment.start_time_offset.seconds
+ object_annotation.segment.start_time_offset.microseconds / 1e6,
object_annotation.segment.end_time_offset.seconds
+ object_annotation.segment.end_time_offset.microseconds / 1e6,
)
)
print("Confidence: {}".format(object_annotation.confidence))
# Here we print only the bounding box of the first frame in the segment
frame = object_annotation.frames[0]
box = frame.normalized_bounding_box
print(
"Time offset of the first frame: {}s".format(
frame.time_offset.seconds + frame.time_offset.microseconds / 1e6
)
)
print("Bounding box position:")
print("\tleft : {}".format(box.left))
print("\ttop : {}".format(box.top))
print("\tright : {}".format(box.right))
print("\tbottom: {}".format(box.bottom))
print("\n")
その他の言語
C#: クライアント ライブラリ ページの C# の設定手順を実行してから、.NET の Video Intelligence のリファレンス ドキュメントをご覧ください。
PHP: クライアント ライブラリ ページのPHP の設定手順を実行してから、PHP の Video Intelligence のリファレンス ドキュメントをご覧ください。
Ruby: クライアント ライブラリ ページの Ruby の設定手順を実行してから、Ruby の Video Intelligence のリファレンス ドキュメントをご覧ください。
ローカル ファイルの動画に対するオブジェクト トラッキングをリクエストする
次のサンプルは、ローカルに保存されたファイルのオブジェクト トラッキングを示しています。
REST
プロセス リクエストを送信する
ローカル動画ファイルに対してアノテーションを付けるには、動画ファイルの内容を Base64 形式でエンコードします。リクエストの inputContent
フィールドに Base64 形式でエンコードされたコンテンツを格納します。
動画ファイルのコンテンツを Base64 形式でエンコードする方法については、Base64 エンコードをご覧ください。
POST
リクエストを videos:annotate
メソッドに送信する方法を以下に示します。この例では、Google Cloud CLI を使用するプロジェクト用に設定されたサービス アカウントのアクセス トークンを使用します。Google Cloud CLI のインストール、サービス アカウントでのプロジェクトの設定、アクセス トークンの取得を行う手順については、Video Intelligence のクイックスタートをご覧ください。
リクエストのデータを使用する前に、次のように置き換えます。
- inputContent: BASE64_ENCODED_CONTENT
次に例を示します。"UklGRg41AwBBVkkgTElTVAwBAABoZHJsYXZpaDgAAAA1ggAAxPMBAAAAAAAQCAA..."
- PROJECT_NUMBER: Google Cloud プロジェクトの数値識別子。
HTTP メソッドと URL:
POST https://videointelligence.googleapis.com/v1/videos:annotate
リクエストの本文(JSON):
{ "inputContent": "BASE64_ENCODED_CONTENT", "features": ["OBJECT_TRACKING"] }
リクエストを送信するには、次のいずれかのオプションを展開します。
curl(Linux、macOS、Cloud Shell)
リクエスト本文を request.json
という名前のファイルに保存して、次のコマンドを実行します。
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://videointelligence.googleapis.com/v1/videos:annotate"
PowerShell(Windows)
リクエスト本文を request.json
という名前のファイルに保存して、次のコマンドを実行します。
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://videointelligence.googleapis.com/v1/videos:annotate" | Select-Object -Expand Content
次のような JSON レスポンスが返されます。
レスポンス
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID" }
リクエストが成功すると、Video Intelligence がオペレーションの name
を返します。以下はレスポンスの例です。PROJECT_NUMBER
はプロジェクトの番号、OPERATION_ID
はリクエストに対して作成された長時間実行オペレーションの ID です。
結果を取得する
リクエストの結果を取得するには、以下の例に示すように、videos:annotate
の呼び出しで返されたオペレーション名を使用して GET
を送信します。
リクエストのデータを使用する前に、次のように置き換えます。
- OPERATION_NAME: Video Intelligence API によって返されるオペレーションの名前。オペレーション名の形式は
projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID
です。 - PROJECT_NUMBER: Google Cloud プロジェクトの数値識別子。
HTTP メソッドと URL:
GET https://videointelligence.googleapis.com/v1/OPERATION_NAME
リクエストを送信するには、次のいずれかのオプションを展開します。
curl(Linux、macOS、Cloud Shell)
次のコマンドを実行します。
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
"https://videointelligence.googleapis.com/v1/OPERATION_NAME"
PowerShell(Windows)
次のコマンドを実行します。
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }
Invoke-WebRequest `
-Method GET `
-Headers $headers `
-Uri "https://videointelligence.googleapis.com/v1/OPERATION_NAME" | Select-Object -Expand Content
次のような JSON レスポンスが返されます。
レスポンス
// Object tracking annotations are returned as a objectAnnotations
list.
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress",
"annotationProgress": [
{
"inputContent": "UklGRg41AwBBVkkgTElTVAwBAABoZHJsYXZpaDgAAAA1ggAAxPMBAAAAAAAQCAA...",
"progressPercent": 100,
"startTime": "2018-06-21T16:56:46.755199Z",
"updateTime": "2018-06-21T16:59:17.911197Z"
}
]
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse",
"annotationResults": [
{
"inputContent": "/cloud-ml-sandbox/video/chicago.mp4",
"objectAnnotations": [
{
"entity": {
"entityId": "/m/0k4j",
"description": "car",
"languageCode": "en-US"
},
"frames": [
{
"normalizedBoundingBox": {
"left": 0.2672763,
"top": 0.5677657,
"right": 0.4388713,
"bottom": 0.7623171
},
"timeOffset": "0s"
},
{
"normalizedBoundingBox": {
"left": 0.26920167,
"top": 0.5659805,
"right": 0.44331276,
"bottom": 0.76780635
},
"timeOffset": "0.100495s"
},
...
{
"normalizedBoundingBox": {
"left": 0.83573246,
"top": 0.6645812,
"right": 1,
"bottom": 0.99865407
},
"timeOffset": "2.311402s"
}
],
"segment": {
"startTimeOffset": "0s",
"endTimeOffset": "2.311402s"
},
"confidence": 0.99488896
},
...
{
"entity": {
"entityId": "/m/0cgh4",
"description": "building",
"languageCode": "en-US"
},
"frames": [
{
"normalizedBoundingBox": {
"left": 0.12340179,
"top": 0.010383379,
"right": 0.21914443,
"bottom": 0.5591795
},
"timeOffset": "0s"
},
{
"normalizedBoundingBox": {
"left": 0.12340179,
"top": 0.009684974,
"right": 0.22915152,
"bottom": 0.56070584
},
"timeOffset": "0.100495s"
},
...
{
"normalizedBoundingBox": {
"left": 0.12340179,
"top": 0.008624528,
"right": 0.22723165,
"bottom": 0.56158626
},
"timeOffset": "0.401983s"
}
],
"segment": {
"startTimeOffset": "0s",
"endTimeOffset": "0.401983s"
},
"confidence": 0.33914912
},
...
{
"entity": {
"entityId": "/m/0cgh4",
"description": "building",
"languageCode": "en-US"
},
"frames": [
{
"normalizedBoundingBox": {
"left": 0.79324204,
"top": 0.0006896425,
"right": 0.99659824,
"bottom": 0.5324423
},
"timeOffset": "37.585421s"
},
{
"normalizedBoundingBox": {
"left": 0.78935236,
"top": 0.0011992548,
"right": 0.99659824,
"bottom": 0.5374946
},
"timeOffset": "37.685917s"
},
...
{
"normalizedBoundingBox": {
"left": 0.79404694,
"right": 0.99659824,
"bottom": 0.5280966
},
"timeOffset": "38.590379s"
}
],
"segment": {
"startTimeOffset": "37.585421s",
"endTimeOffset": "38.590379s"
},
"confidence": 0.3415429
}
]
}
]
}
}
Go
import (
"context"
"fmt"
"io"
"io/ioutil"
video "cloud.google.com/go/videointelligence/apiv1"
videopb "cloud.google.com/go/videointelligence/apiv1/videointelligencepb"
"github.com/golang/protobuf/ptypes"
)
// objectTracking analyzes a video and extracts entities with their bounding boxes.
func objectTracking(w io.Writer, filename string) error {
// filename := "../testdata/cat.mp4"
ctx := context.Background()
// Creates a client.
client, err := video.NewClient(ctx)
if err != nil {
return fmt.Errorf("video.NewClient: %w", err)
}
defer client.Close()
fileBytes, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
op, err := client.AnnotateVideo(ctx, &videopb.AnnotateVideoRequest{
InputContent: fileBytes,
Features: []videopb.Feature{
videopb.Feature_OBJECT_TRACKING,
},
})
if err != nil {
return fmt.Errorf("AnnotateVideo: %w", err)
}
resp, err := op.Wait(ctx)
if err != nil {
return fmt.Errorf("Wait: %w", err)
}
// Only one video was processed, so get the first result.
result := resp.GetAnnotationResults()[0]
for _, annotation := range result.ObjectAnnotations {
fmt.Fprintf(w, "Description: %q\n", annotation.Entity.GetDescription())
if len(annotation.Entity.EntityId) > 0 {
fmt.Fprintf(w, "\tEntity ID: %q\n", annotation.Entity.GetEntityId())
}
segment := annotation.GetSegment()
start, _ := ptypes.Duration(segment.GetStartTimeOffset())
end, _ := ptypes.Duration(segment.GetEndTimeOffset())
fmt.Fprintf(w, "\tSegment: %v to %v\n", start, end)
fmt.Fprintf(w, "\tConfidence: %f\n", annotation.GetConfidence())
// Here we print only the bounding box of the first frame in this segment.
frame := annotation.GetFrames()[0]
seconds := float32(frame.GetTimeOffset().GetSeconds())
nanos := float32(frame.GetTimeOffset().GetNanos())
fmt.Fprintf(w, "\tTime offset of the first frame: %fs\n", seconds+nanos/1e9)
box := frame.GetNormalizedBoundingBox()
fmt.Fprintf(w, "\tBounding box position:\n")
fmt.Fprintf(w, "\t\tleft : %f\n", box.GetLeft())
fmt.Fprintf(w, "\t\ttop : %f\n", box.GetTop())
fmt.Fprintf(w, "\t\tright : %f\n", box.GetRight())
fmt.Fprintf(w, "\t\tbottom: %f\n", box.GetBottom())
}
return nil
}
Java
/**
* Track objects in a video.
*
* @param filePath the path to the video file to analyze.
*/
public static VideoAnnotationResults trackObjects(String filePath) throws Exception {
try (VideoIntelligenceServiceClient client = VideoIntelligenceServiceClient.create()) {
// Read file
Path path = Paths.get(filePath);
byte[] data = Files.readAllBytes(path);
// Create the request
AnnotateVideoRequest request =
AnnotateVideoRequest.newBuilder()
.setInputContent(ByteString.copyFrom(data))
.addFeatures(Feature.OBJECT_TRACKING)
.setLocationId("us-east1")
.build();
// asynchronously perform object tracking on videos
OperationFuture<AnnotateVideoResponse, AnnotateVideoProgress> future =
client.annotateVideoAsync(request);
System.out.println("Waiting for operation to complete...");
// The first result is retrieved because a single video was processed.
AnnotateVideoResponse response = future.get(450, TimeUnit.SECONDS);
VideoAnnotationResults results = response.getAnnotationResults(0);
// Get only the first annotation for demo purposes.
ObjectTrackingAnnotation annotation = results.getObjectAnnotations(0);
System.out.println("Confidence: " + annotation.getConfidence());
if (annotation.hasEntity()) {
Entity entity = annotation.getEntity();
System.out.println("Entity description: " + entity.getDescription());
System.out.println("Entity id:: " + entity.getEntityId());
}
if (annotation.hasSegment()) {
VideoSegment videoSegment = annotation.getSegment();
Duration startTimeOffset = videoSegment.getStartTimeOffset();
Duration endTimeOffset = videoSegment.getEndTimeOffset();
// Display the segment time in seconds, 1e9 converts nanos to seconds
System.out.println(
String.format(
"Segment: %.2fs to %.2fs",
startTimeOffset.getSeconds() + startTimeOffset.getNanos() / 1e9,
endTimeOffset.getSeconds() + endTimeOffset.getNanos() / 1e9));
}
// Here we print only the bounding box of the first frame in this segment.
ObjectTrackingFrame frame = annotation.getFrames(0);
// Display the offset time in seconds, 1e9 converts nanos to seconds
Duration timeOffset = frame.getTimeOffset();
System.out.println(
String.format(
"Time offset of the first frame: %.2fs",
timeOffset.getSeconds() + timeOffset.getNanos() / 1e9));
// Display the bounding box of the detected object
NormalizedBoundingBox normalizedBoundingBox = frame.getNormalizedBoundingBox();
System.out.println("Bounding box position:");
System.out.println("\tleft: " + normalizedBoundingBox.getLeft());
System.out.println("\ttop: " + normalizedBoundingBox.getTop());
System.out.println("\tright: " + normalizedBoundingBox.getRight());
System.out.println("\tbottom: " + normalizedBoundingBox.getBottom());
return results;
}
}
Node.js
Video Intelligence への認証を行うには、アプリケーションのデフォルト認証情報を設定します。 詳細については、ローカル開発環境の認証の設定をご覧ください。
// Imports the Google Cloud Video Intelligence library
const Video = require('@google-cloud/video-intelligence');
const fs = require('fs');
const util = require('util');
// Creates a client
const video = new Video.VideoIntelligenceServiceClient();
/**
* TODO(developer): Uncomment the following line before running the sample.
*/
// const path = 'Local file to analyze, e.g. ./my-file.mp4';
// Reads a local video file and converts it to base64
const file = await util.promisify(fs.readFile)(path);
const inputContent = file.toString('base64');
const request = {
inputContent: inputContent,
features: ['OBJECT_TRACKING'],
//recommended to use us-east1 for the best latency due to different types of processors used in this region and others
locationId: 'us-east1',
};
// Detects objects in a video
const [operation] = await video.annotateVideo(request);
const results = await operation.promise();
console.log('Waiting for operation to complete...');
//Gets annotations for video
const annotations = results[0].annotationResults[0];
const objects = annotations.objectAnnotations;
objects.forEach(object => {
console.log(`Entity description: ${object.entity.description}`);
console.log(`Entity id: ${object.entity.entityId}`);
const time = object.segment;
console.log(
`Segment: ${time.startTimeOffset.seconds || 0}` +
`.${(time.startTimeOffset.nanos / 1e6).toFixed(0)}s to ${
time.endTimeOffset.seconds || 0
}.` +
`${(time.endTimeOffset.nanos / 1e6).toFixed(0)}s`
);
console.log(`Confidence: ${object.confidence}`);
const frame = object.frames[0];
const box = frame.normalizedBoundingBox;
const timeOffset = frame.timeOffset;
console.log(
`Time offset for the first frame: ${timeOffset.seconds || 0}` +
`.${(timeOffset.nanos / 1e6).toFixed(0)}s`
);
console.log('Bounding box position:');
console.log(` left :${box.left}`);
console.log(` top :${box.top}`);
console.log(` right :${box.right}`);
console.log(` bottom :${box.bottom}`);
});
Python
"""Object tracking in a local video."""
from google.cloud import videointelligence
video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.OBJECT_TRACKING]
with io.open(path, "rb") as file:
input_content = file.read()
operation = video_client.annotate_video(
request={"features": features, "input_content": input_content}
)
print("\nProcessing video for object annotations.")
result = operation.result(timeout=500)
print("\nFinished processing.\n")
# The first result is retrieved because a single video was processed.
object_annotations = result.annotation_results[0].object_annotations
# Get only the first annotation for demo purposes.
object_annotation = object_annotations[0]
print("Entity description: {}".format(object_annotation.entity.description))
if object_annotation.entity.entity_id:
print("Entity id: {}".format(object_annotation.entity.entity_id))
print(
"Segment: {}s to {}s".format(
object_annotation.segment.start_time_offset.seconds
+ object_annotation.segment.start_time_offset.microseconds / 1e6,
object_annotation.segment.end_time_offset.seconds
+ object_annotation.segment.end_time_offset.microseconds / 1e6,
)
)
print("Confidence: {}".format(object_annotation.confidence))
# Here we print only the bounding box of the first frame in this segment
frame = object_annotation.frames[0]
box = frame.normalized_bounding_box
print(
"Time offset of the first frame: {}s".format(
frame.time_offset.seconds + frame.time_offset.microseconds / 1e6
)
)
print("Bounding box position:")
print("\tleft : {}".format(box.left))
print("\ttop : {}".format(box.top))
print("\tright : {}".format(box.right))
print("\tbottom: {}".format(box.bottom))
print("\n")
その他の言語
C#: クライアント ライブラリ ページの C# の設定手順を実行してから、.NET の Video Intelligence のリファレンス ドキュメントをご覧ください。
PHP: クライアント ライブラリ ページのPHP の設定手順を実行してから、PHP の Video Intelligence のリファレンス ドキュメントをご覧ください。
Ruby: クライアント ライブラリ ページの Ruby の設定手順を実行してから、Ruby の Video Intelligence のリファレンス ドキュメントをご覧ください。