Video Intelligence API 可偵測、追蹤及辨識影片內容中超過 100,000 個品牌和標誌。
本頁說明如何使用 Video Intelligence API 辨識影片中的標誌。
為 Cloud Storage 中的影片加上註解
下列程式碼範例示範如何偵測 Cloud Storage 影片中的標誌。
REST
傳送處理要求
如要對本機影片檔案執行註解,請對影片檔案內容執行 base64 編碼。在要求的 inputContent
欄位中加入 Base64 編碼的內容。如要瞭解如何使用 base64 編碼影片檔案內容,請參閱「Base64 編碼」一文。
以下說明如何將 POST
要求傳送至 videos:annotate
方法。
範例中使用的存取憑證,屬於透過 Google Cloud CLI 建立的專案服務帳戶。如需安裝 Google Cloud CLI、使用服務帳戶建立專案,以及取得存取憑證的操作說明,請參閱 Video Intelligence 快速入門導覽課程。
使用任何要求資料之前,請先替換以下項目:
- INPUT_URI:包含要註解檔案的 Cloud Storage bucket,包括檔案名稱。開頭必須為
gs://
。
例如:
"inputUri": "gs://cloud-videointelligence-demo/assistant.mp4",
- PROJECT_NUMBER:專案的數值 ID Google Cloud
HTTP 方法和網址:
POST https://videointelligence.googleapis.com/v1/videos:annotate
JSON 要求主體:
{ "inputUri":"INPUT_URI", "features": ["LOGO_RECOGNITION"] }
如要傳送要求,請展開以下其中一個選項:
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。
- PROJECT_NUMBER:專案編號
- LOCATION_ID:應進行註解的雲端地區。支援的雲端區域包括:
us-east1
、us-west1
、europe-west1
、asia-east1
。如果沒有指定任何地區,則會依據影片檔案位置來決定地區。 - OPERATION_ID:為要求建立的長時間執行作業 ID,並在您開始作業時提供於回應中,例如
12345...
取得結果
如要取得要求結果,請使用從 videos:annotate
呼叫傳回的作業名稱,傳送 GET
要求,如下列範例所示。
使用任何要求資料之前,請先替換以下項目:
- OPERATION_NAME:Video Intelligence API 傳回的作業名稱。作業名稱的格式為
projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID
- PROJECT_NUMBER:專案的數值 ID Google Cloud
HTTP 方法和網址:
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 回應:
回應
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID", "metadata": { "@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress", "annotationProgress": [ { "inputUri": "/cloud-samples-data/video/googlework_short.mp4", "progressPercent": 100, "startTime": "2020-02-31T16:27:44.889439Z", "updateTime": "2020-02-31T16:27:56.526050Z" } ] }, "done": true, "response": { "@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse", "annotationResults": [ { "inputUri": "/cloud-samples-data/video/googlework_short.mp4", "segment": { "startTimeOffset": "0s", "endTimeOffset": "34.234200s" }, "logoRecognitionAnnotations": [{ "entity": { "entityId": "/m/045c7b", "description": "Google", "languageCode": "en-US" }, "tracks": [{ "segment": { "startTimeOffset": "10.543866s", "endTimeOffset": "12.345666s" }, "timestampedObjects": [{ "normalizedBoundingBox": { "left": 0.3912032, "top": 0.26212785, "right": 0.6469412, "bottom": 0.4434373 }, "timeOffset": "10.543866s" }, ... ], "confidence": 0.8588119 }, { "segment": { "startTimeOffset": "15.348666s", "endTimeOffset": "18.752066s" }, "timestampedObjects": [ { "normalizedBoundingBox": { "left": 0.69989866, "top": 0.79943377, "right": 0.76465744, "bottom": 0.9271479 }, "timeOffset": "15.348666s" }, { "normalizedBoundingBox": { "left": 0.68997324, "top": 0.78775305, "right": 0.75723547, "bottom": 0.91808647 }, "timeOffset": "15.448766s" }, ... } } ] } ] } }
下載註解結果
將註解從來源複製到目標值區:(請參閱「複製檔案和物件」)
gcloud storage cp gcs_uri gs://my-bucket
注意:如果輸出 GCS URI 是由使用者提供,註解就會儲存在該 GCS URI 中。
Go
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
import (
"context"
"fmt"
"io"
"time"
video "cloud.google.com/go/videointelligence/apiv1"
videopb "cloud.google.com/go/videointelligence/apiv1/videointelligencepb"
"github.com/golang/protobuf/ptypes"
)
// logoDetectionGCS analyzes a video and extracts logos with their bounding boxes.
func logoDetectionGCS(w io.Writer, gcsURI string) error {
// gcsURI := "gs://cloud-samples-data/video/googlework_tiny.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()
ctx, cancel := context.WithTimeout(ctx, time.Second*180)
defer cancel()
op, err := client.AnnotateVideo(ctx, &videopb.AnnotateVideoRequest{
InputUri: gcsURI,
Features: []videopb.Feature{
videopb.Feature_LOGO_RECOGNITION,
},
})
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]
// Annotations for list of logos detected, tracked and recognized in video.
for _, annotation := range result.LogoRecognitionAnnotations {
fmt.Fprintf(w, "Description: %q\n", annotation.Entity.GetDescription())
// Opaque entity ID. Some IDs may be available in Google Knowledge
// Graph Search API (https://developers.google.com/knowledge-graph/).
if len(annotation.Entity.EntityId) > 0 {
fmt.Fprintf(w, "\tEntity ID: %q\n", annotation.Entity.GetEntityId())
}
// All logo tracks where the recognized logo appears. Each track
// corresponds to one logo instance appearing in consecutive frames.
for _, track := range annotation.Tracks {
// Video segment of a track.
segment := track.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", track.GetConfidence())
// The object with timestamp and attributes per frame in the track.
for _, timestampedObject := range track.TimestampedObjects {
// Normalized Bounding box in a frame, where the object is
// located.
box := timestampedObject.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())
// Optional. The attributes of the object in the bounding box.
for _, attribute := range timestampedObject.Attributes {
fmt.Fprintf(w, "\t\t\tName: %q\n", attribute.GetName())
fmt.Fprintf(w, "\t\t\tConfidence: %f\n", attribute.GetConfidence())
fmt.Fprintf(w, "\t\t\tValue: %q\n", attribute.GetValue())
}
}
// Optional. Attributes in the track level.
for _, trackAttribute := range track.Attributes {
fmt.Fprintf(w, "\t\tName: %q\n", trackAttribute.GetName())
fmt.Fprintf(w, "\t\tConfidence: %f\n", trackAttribute.GetConfidence())
fmt.Fprintf(w, "\t\tValue: %q\n", trackAttribute.GetValue())
}
}
// All video segments where the recognized logo appears. There might be
// multiple instances of the same logo class appearing in one VideoSegment.
for _, segment := range annotation.Segments {
start, _ := ptypes.Duration(segment.GetStartTimeOffset())
end, _ := ptypes.Duration(segment.GetEndTimeOffset())
fmt.Fprintf(w, "\tSegment: %v to %v\n", start, end)
}
}
return nil
}
Java
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.videointelligence.v1.AnnotateVideoProgress;
import com.google.cloud.videointelligence.v1.AnnotateVideoRequest;
import com.google.cloud.videointelligence.v1.AnnotateVideoResponse;
import com.google.cloud.videointelligence.v1.DetectedAttribute;
import com.google.cloud.videointelligence.v1.Entity;
import com.google.cloud.videointelligence.v1.Feature;
import com.google.cloud.videointelligence.v1.LogoRecognitionAnnotation;
import com.google.cloud.videointelligence.v1.NormalizedBoundingBox;
import com.google.cloud.videointelligence.v1.TimestampedObject;
import com.google.cloud.videointelligence.v1.Track;
import com.google.cloud.videointelligence.v1.VideoAnnotationResults;
import com.google.cloud.videointelligence.v1.VideoIntelligenceServiceClient;
import com.google.cloud.videointelligence.v1.VideoSegment;
import com.google.protobuf.Duration;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class LogoDetectionGcs {
public static void detectLogoGcs() throws Exception {
// TODO(developer): Replace these variables before running the sample.
String gcsUri = "gs://YOUR_BUCKET_ID/path/to/your/video.mp4";
detectLogoGcs(gcsUri);
}
public static void detectLogoGcs(String inputUri)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (VideoIntelligenceServiceClient client = VideoIntelligenceServiceClient.create()) {
// Create the request
AnnotateVideoRequest request =
AnnotateVideoRequest.newBuilder()
.setInputUri(inputUri)
.addFeatures(Feature.LOGO_RECOGNITION)
.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(600, TimeUnit.SECONDS);
VideoAnnotationResults annotationResult = response.getAnnotationResults(0);
// Annotations for list of logos detected, tracked and recognized in video.
for (LogoRecognitionAnnotation logoRecognitionAnnotation :
annotationResult.getLogoRecognitionAnnotationsList()) {
Entity entity = logoRecognitionAnnotation.getEntity();
// Opaque entity ID. Some IDs may be available in
// [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
System.out.printf("Entity Id : %s\n", entity.getEntityId());
System.out.printf("Description : %s\n", entity.getDescription());
// All logo tracks where the recognized logo appears. Each track corresponds to one logo
// instance appearing in consecutive frames.
for (Track track : logoRecognitionAnnotation.getTracksList()) {
// Video segment of a track.
Duration startTimeOffset = track.getSegment().getStartTimeOffset();
System.out.printf(
"\n\tStart Time Offset: %s.%s\n",
startTimeOffset.getSeconds(), startTimeOffset.getNanos());
Duration endTimeOffset = track.getSegment().getEndTimeOffset();
System.out.printf(
"\tEnd Time Offset: %s.%s\n", endTimeOffset.getSeconds(), endTimeOffset.getNanos());
System.out.printf("\tConfidence: %s\n", track.getConfidence());
// The object with timestamp and attributes per frame in the track.
for (TimestampedObject timestampedObject : track.getTimestampedObjectsList()) {
// Normalized Bounding box in a frame, where the object is located.
NormalizedBoundingBox normalizedBoundingBox =
timestampedObject.getNormalizedBoundingBox();
System.out.printf("\n\t\tLeft: %s\n", normalizedBoundingBox.getLeft());
System.out.printf("\t\tTop: %s\n", normalizedBoundingBox.getTop());
System.out.printf("\t\tRight: %s\n", normalizedBoundingBox.getRight());
System.out.printf("\t\tBottom: %s\n", normalizedBoundingBox.getBottom());
// Optional. The attributes of the object in the bounding box.
for (DetectedAttribute attribute : timestampedObject.getAttributesList()) {
System.out.printf("\n\t\t\tName: %s\n", attribute.getName());
System.out.printf("\t\t\tConfidence: %s\n", attribute.getConfidence());
System.out.printf("\t\t\tValue: %s\n", attribute.getValue());
}
}
// Optional. Attributes in the track level.
for (DetectedAttribute trackAttribute : track.getAttributesList()) {
System.out.printf("\n\t\tName : %s\n", trackAttribute.getName());
System.out.printf("\t\tConfidence : %s\n", trackAttribute.getConfidence());
System.out.printf("\t\tValue : %s\n", trackAttribute.getValue());
}
}
// All video segments where the recognized logo appears. There might be multiple instances
// of the same logo class appearing in one VideoSegment.
for (VideoSegment segment : logoRecognitionAnnotation.getSegmentsList()) {
System.out.printf(
"\n\tStart Time Offset : %s.%s\n",
segment.getStartTimeOffset().getSeconds(), segment.getStartTimeOffset().getNanos());
System.out.printf(
"\tEnd Time Offset : %s.%s\n",
segment.getEndTimeOffset().getSeconds(), segment.getEndTimeOffset().getNanos());
}
}
}
}
}
Node.js
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const inputUri = 'gs://cloud-samples-data/video/googlework_short.mp4';
// Imports the Google Cloud client libraries
const Video = require('@google-cloud/video-intelligence');
// Instantiates a client
const client = new Video.VideoIntelligenceServiceClient();
// Performs asynchronous video annotation for logo recognition on a file hosted in GCS.
async function detectLogoGcs() {
// Build the request with the input uri and logo recognition feature.
const request = {
inputUri: inputUri,
features: ['LOGO_RECOGNITION'],
};
// Make the asynchronous request
const [operation] = await client.annotateVideo(request);
// Wait for the results
const [response] = await operation.promise();
// Get the first response, since we sent only one video.
const annotationResult = response.annotationResults[0];
for (const logoRecognitionAnnotation of annotationResult.logoRecognitionAnnotations) {
const entity = logoRecognitionAnnotation.entity;
// Opaque entity ID. Some IDs may be available in
// [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
console.log(`Entity Id: ${entity.entityId}`);
console.log(`Description: ${entity.description}`);
// All logo tracks where the recognized logo appears.
// Each track corresponds to one logo instance appearing in consecutive frames.
for (const track of logoRecognitionAnnotation.tracks) {
console.log(
`\n\tStart Time Offset: ${track.segment.startTimeOffset.seconds}.${track.segment.startTimeOffset.nanos}`
);
console.log(
`\tEnd Time Offset: ${track.segment.endTimeOffset.seconds}.${track.segment.endTimeOffset.nanos}`
);
console.log(`\tConfidence: ${track.confidence}`);
// The object with timestamp and attributes per frame in the track.
for (const timestampedObject of track.timestampedObjects) {
// Normalized Bounding box in a frame, where the object is located.
const normalizedBoundingBox = timestampedObject.normalizedBoundingBox;
console.log(`\n\t\tLeft: ${normalizedBoundingBox.left}`);
console.log(`\t\tTop: ${normalizedBoundingBox.top}`);
console.log(`\t\tRight: ${normalizedBoundingBox.right}`);
console.log(`\t\tBottom: ${normalizedBoundingBox.bottom}`);
// Optional. The attributes of the object in the bounding box.
for (const attribute of timestampedObject.attributes) {
console.log(`\n\t\t\tName: ${attribute.name}`);
console.log(`\t\t\tConfidence: ${attribute.confidence}`);
console.log(`\t\t\tValue: ${attribute.value}`);
}
}
// Optional. Attributes in the track level.
for (const trackAttribute of track.attributes) {
console.log(`\n\t\tName: ${trackAttribute.name}`);
console.log(`\t\tConfidence: ${trackAttribute.confidence}`);
console.log(`\t\tValue: ${trackAttribute.value}`);
}
}
// All video segments where the recognized logo appears.
// There might be multiple instances of the same logo class appearing in one VideoSegment.
for (const segment of logoRecognitionAnnotation.segments) {
console.log(
`\n\tStart Time Offset: ${segment.startTimeOffset.seconds}.${segment.startTimeOffset.nanos}`
);
console.log(
`\tEnd Time Offset: ${segment.endTimeOffset.seconds}.${segment.endTimeOffset.nanos}`
);
}
}
}
detectLogoGcs();
Python
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
from google.cloud import videointelligence
def detect_logo_gcs(input_uri="gs://YOUR_BUCKET_ID/path/to/your/file.mp4"):
client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.LOGO_RECOGNITION]
operation = client.annotate_video(
request={"features": features, "input_uri": input_uri}
)
print("Waiting for operation to complete...")
response = operation.result()
# Get the first response, since we sent only one video.
annotation_result = response.annotation_results[0]
# Annotations for list of logos detected, tracked and recognized in video.
for logo_recognition_annotation in annotation_result.logo_recognition_annotations:
entity = logo_recognition_annotation.entity
# Opaque entity ID. Some IDs may be available in [Google Knowledge Graph
# Search API](https://developers.google.com/knowledge-graph/).
print("Entity Id : {}".format(entity.entity_id))
print("Description : {}".format(entity.description))
# All logo tracks where the recognized logo appears. Each track corresponds
# to one logo instance appearing in consecutive frames.
for track in logo_recognition_annotation.tracks:
# Video segment of a track.
print(
"\n\tStart Time Offset : {}.{}".format(
track.segment.start_time_offset.seconds,
track.segment.start_time_offset.microseconds * 1000,
)
)
print(
"\tEnd Time Offset : {}.{}".format(
track.segment.end_time_offset.seconds,
track.segment.end_time_offset.microseconds * 1000,
)
)
print("\tConfidence : {}".format(track.confidence))
# The object with timestamp and attributes per frame in the track.
for timestamped_object in track.timestamped_objects:
# Normalized Bounding box in a frame, where the object is located.
normalized_bounding_box = timestamped_object.normalized_bounding_box
print("\n\t\tLeft : {}".format(normalized_bounding_box.left))
print("\t\tTop : {}".format(normalized_bounding_box.top))
print("\t\tRight : {}".format(normalized_bounding_box.right))
print("\t\tBottom : {}".format(normalized_bounding_box.bottom))
# Optional. The attributes of the object in the bounding box.
for attribute in timestamped_object.attributes:
print("\n\t\t\tName : {}".format(attribute.name))
print("\t\t\tConfidence : {}".format(attribute.confidence))
print("\t\t\tValue : {}".format(attribute.value))
# Optional. Attributes in the track level.
for track_attribute in track.attributes:
print("\n\t\tName : {}".format(track_attribute.name))
print("\t\tConfidence : {}".format(track_attribute.confidence))
print("\t\tValue : {}".format(track_attribute.value))
# All video segments where the recognized logo appears. There might be
# multiple instances of the same logo class appearing in one VideoSegment.
for segment in logo_recognition_annotation.segments:
print(
"\n\tStart Time Offset : {}.{}".format(
segment.start_time_offset.seconds,
segment.start_time_offset.microseconds * 1000,
)
)
print(
"\tEnd Time Offset : {}.{}".format(
segment.end_time_offset.seconds,
segment.end_time_offset.microseconds * 1000,
)
)
其他語言
C#: 請按照用戶端程式庫頁面上的 C# 設定說明操作, 然後參閱 .NET 適用的 Video Intelligence 參考說明文件。
PHP: 請按照用戶端程式庫頁面的 PHP 設定說明 操作,然後前往 PHP 適用的 Video Intelligence 參考文件。
Ruby: 請按照用戶端程式庫頁面的 Ruby 設定說明 操作,然後前往 Ruby 適用的 Video Intelligence 參考說明文件。
為本機影片加上註解
以下程式碼範例示範如何偵測本機影片檔中的標誌。
REST
傳送影片註解要求
如要對本機影片檔案執行註解,請務必對影片檔案的內容執行 base64 編碼。在要求的 inputContent
欄位中加入 Base64 編碼的內容。
如要瞭解如何對影片檔案內容進行 base64 編碼,請參閱「Base64 編碼」一文。
以下說明如何對 videos:annotate
方法傳送 POST 要求。範例中使用的存取憑證,屬於使用 Google Cloud CLI 建立的專案服務帳戶。如需安裝 Google Cloud CLI、使用服務帳戶建立專案,以及取得存取憑證的操作說明,請參閱 Video Intelligence API 快速入門導覽課程。
使用任何要求資料之前,請先替換以下項目:
- 「inputContent」:BASE64_ENCODED_CONTENT
例如:
"UklGRg41AwBBVkkgTElTVAwBAABoZHJsYXZpaDgAAAA1ggAAxPMBAAAAAAAQCAA..."
- LANGUAGE_CODE:[選用] 查看支援的語言
- PROJECT_NUMBER:專案的數值 ID Google Cloud
HTTP 方法和網址:
POST https://videointelligence.googleapis.com/v1/videos:annotate
JSON 要求主體:
{ "inputContent": "BASE64_ENCODED_CONTENT", "features": ["LOGO_RECOGNITION"], "videoContext": { } }
如要傳送要求,請展開以下其中一個選項:
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。
- OPERATION_ID:啟動作業時,回應中提供的 ID,例如
12345...
取得註解結果
如要擷取作業結果,請使用對 videos:annotate 的呼叫傳回的作業名稱,發出 GET 要求,如下列範例所示。
使用任何要求資料之前,請先替換以下項目:
- PROJECT_NUMBER:專案的數值 ID Google Cloud
HTTP 方法和網址:
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 回應:
回應
"name": "projects/512816187662/locations/us-east1/operations/8399514592783793684", "metadata": { "@type": "type.googleapis.com/google.cloud.videointelligence.v1p3beta1.AnnotateVideoProgress", "annotationProgress": [ { "inputUri": "/videointelligence-prober-videos/face.mkv", "progressPercent": 100, "startTime": "2020-03-18T19:45:17.725359Z", "updateTime": "2020-03-18T19:45:26.532315Z" } ] }, "done": true, "response": { "@type": "type.googleapis.com/google.cloud.videointelligence.v1p3beta1.AnnotateVideoResponse", "annotationResults": [ { "inputUri": "/videointelligence-prober-videos/face.mkv", "segment": { "startTimeOffset": "0s", "endTimeOffset": "10.010s" }, "logoRecognitionAnnotations": [ { "entity": { "entityId": "/m/02z_b", "description": "Fox News", "languageCode": "en-US" }, "tracks": [ { "segment": { "startTimeOffset": "0s", "endTimeOffset": "1.901900s" }, "timestampedObjects": [ { "normalizedBoundingBox": { "left": 0.032402553, "top": 0.73683465, "right": 0.16249886, "bottom": 0.8664769 }, "timeOffset": "0s" }, { "normalizedBoundingBox": { "left": 0.03267879, "top": 0.73522913, "right": 0.1627307, "bottom": 0.86775583 }, "timeOffset": "0.100100s" }, { "normalizedBoundingBox": { "left": 0.031819325, "top": 0.73514116, "right": 0.16305345, "bottom": 0.8677738 }, "timeOffset": "0.200200s" }, { "normalizedBoundingBox": { "left": 0.03155339, "top": 0.7349258, "right": 0.16275825, "bottom": 0.86660737 }, "timeOffset": "0.300300s" }, .... ] }
文字偵測註解會以 textAnnotations
清單傳回。
注意:只有在 done 欄位的值為 True 時,系統才會傳回這個欄位。
如果作業未完成,則回應不會含有這個欄位。
Go
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
import (
"context"
"fmt"
"io"
"os"
"time"
video "cloud.google.com/go/videointelligence/apiv1"
videopb "cloud.google.com/go/videointelligence/apiv1/videointelligencepb"
"github.com/golang/protobuf/ptypes"
)
// logoDetection analyzes a video and extracts logos with their bounding boxes.
func logoDetection(w io.Writer, filename string) error {
// filename := "../testdata/googlework_short.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()
ctx, cancel := context.WithTimeout(ctx, time.Second*180)
defer cancel()
fileBytes, err := os.ReadFile(filename)
if err != nil {
return fmt.Errorf("os.ReadFile: %w", err)
}
op, err := client.AnnotateVideo(ctx, &videopb.AnnotateVideoRequest{
InputContent: fileBytes,
Features: []videopb.Feature{
videopb.Feature_LOGO_RECOGNITION,
},
})
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]
// Annotations for list of logos detected, tracked and recognized in video.
for _, annotation := range result.LogoRecognitionAnnotations {
fmt.Fprintf(w, "Description: %q\n", annotation.Entity.GetDescription())
// Opaque entity ID. Some IDs may be available in Google Knowledge
// Graph Search API (https://developers.google.com/knowledge-graph/).
if len(annotation.Entity.EntityId) > 0 {
fmt.Fprintf(w, "\tEntity ID: %q\n", annotation.Entity.GetEntityId())
}
// All logo tracks where the recognized logo appears. Each track
// corresponds to one logo instance appearing in consecutive frames.
for _, track := range annotation.Tracks {
// Video segment of a track.
segment := track.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", track.GetConfidence())
// The object with timestamp and attributes per frame in the track.
for _, timestampedObject := range track.TimestampedObjects {
// Normalized Bounding box in a frame, where the object is
// located.
box := timestampedObject.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())
// Optional. The attributes of the object in the bounding box.
for _, attribute := range timestampedObject.Attributes {
fmt.Fprintf(w, "\t\t\tName: %q\n", attribute.GetName())
fmt.Fprintf(w, "\t\t\tConfidence: %f\n", attribute.GetConfidence())
fmt.Fprintf(w, "\t\t\tValue: %q\n", attribute.GetValue())
}
}
// Optional. Attributes in the track level.
for _, trackAttribute := range track.Attributes {
fmt.Fprintf(w, "\t\tName: %q\n", trackAttribute.GetName())
fmt.Fprintf(w, "\t\tConfidence: %f\n", trackAttribute.GetConfidence())
fmt.Fprintf(w, "\t\tValue: %q\n", trackAttribute.GetValue())
}
}
// All video segments where the recognized logo appears. There might be
// multiple instances of the same logo class appearing in one VideoSegment.
for _, segment := range annotation.Segments {
start, _ := ptypes.Duration(segment.GetStartTimeOffset())
end, _ := ptypes.Duration(segment.GetEndTimeOffset())
fmt.Fprintf(w, "\tSegment: %v to %v\n", start, end)
}
}
return nil
}
Java
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.videointelligence.v1.AnnotateVideoProgress;
import com.google.cloud.videointelligence.v1.AnnotateVideoRequest;
import com.google.cloud.videointelligence.v1.AnnotateVideoResponse;
import com.google.cloud.videointelligence.v1.DetectedAttribute;
import com.google.cloud.videointelligence.v1.Entity;
import com.google.cloud.videointelligence.v1.Feature;
import com.google.cloud.videointelligence.v1.LogoRecognitionAnnotation;
import com.google.cloud.videointelligence.v1.NormalizedBoundingBox;
import com.google.cloud.videointelligence.v1.TimestampedObject;
import com.google.cloud.videointelligence.v1.Track;
import com.google.cloud.videointelligence.v1.VideoAnnotationResults;
import com.google.cloud.videointelligence.v1.VideoIntelligenceServiceClient;
import com.google.cloud.videointelligence.v1.VideoSegment;
import com.google.protobuf.ByteString;
import com.google.protobuf.Duration;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class LogoDetection {
public static void detectLogo() throws Exception {
// TODO(developer): Replace these variables before running the sample.
String localFilePath = "path/to/your/video.mp4";
detectLogo(localFilePath);
}
public static void detectLogo(String filePath)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
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.LOGO_RECOGNITION)
.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(300, TimeUnit.SECONDS);
VideoAnnotationResults annotationResult = response.getAnnotationResults(0);
// Annotations for list of logos detected, tracked and recognized in video.
for (LogoRecognitionAnnotation logoRecognitionAnnotation :
annotationResult.getLogoRecognitionAnnotationsList()) {
Entity entity = logoRecognitionAnnotation.getEntity();
// Opaque entity ID. Some IDs may be available in
// [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
System.out.printf("Entity Id : %s\n", entity.getEntityId());
System.out.printf("Description : %s\n", entity.getDescription());
// All logo tracks where the recognized logo appears. Each track corresponds to one logo
// instance appearing in consecutive frames.
for (Track track : logoRecognitionAnnotation.getTracksList()) {
// Video segment of a track.
Duration startTimeOffset = track.getSegment().getStartTimeOffset();
System.out.printf(
"\n\tStart Time Offset: %s.%s\n",
startTimeOffset.getSeconds(), startTimeOffset.getNanos());
Duration endTimeOffset = track.getSegment().getEndTimeOffset();
System.out.printf(
"\tEnd Time Offset: %s.%s\n", endTimeOffset.getSeconds(), endTimeOffset.getNanos());
System.out.printf("\tConfidence: %s\n", track.getConfidence());
// The object with timestamp and attributes per frame in the track.
for (TimestampedObject timestampedObject : track.getTimestampedObjectsList()) {
// Normalized Bounding box in a frame, where the object is located.
NormalizedBoundingBox normalizedBoundingBox =
timestampedObject.getNormalizedBoundingBox();
System.out.printf("\n\t\tLeft: %s\n", normalizedBoundingBox.getLeft());
System.out.printf("\t\tTop: %s\n", normalizedBoundingBox.getTop());
System.out.printf("\t\tRight: %s\n", normalizedBoundingBox.getRight());
System.out.printf("\t\tBottom: %s\n", normalizedBoundingBox.getBottom());
// Optional. The attributes of the object in the bounding box.
for (DetectedAttribute attribute : timestampedObject.getAttributesList()) {
System.out.printf("\n\t\t\tName: %s\n", attribute.getName());
System.out.printf("\t\t\tConfidence: %s\n", attribute.getConfidence());
System.out.printf("\t\t\tValue: %s\n", attribute.getValue());
}
}
// Optional. Attributes in the track level.
for (DetectedAttribute trackAttribute : track.getAttributesList()) {
System.out.printf("\n\t\tName : %s\n", trackAttribute.getName());
System.out.printf("\t\tConfidence : %s\n", trackAttribute.getConfidence());
System.out.printf("\t\tValue : %s\n", trackAttribute.getValue());
}
}
// All video segments where the recognized logo appears. There might be multiple instances
// of the same logo class appearing in one VideoSegment.
for (VideoSegment segment : logoRecognitionAnnotation.getSegmentsList()) {
System.out.printf(
"\n\tStart Time Offset : %s.%s\n",
segment.getStartTimeOffset().getSeconds(), segment.getStartTimeOffset().getNanos());
System.out.printf(
"\tEnd Time Offset : %s.%s\n",
segment.getEndTimeOffset().getSeconds(), segment.getEndTimeOffset().getNanos());
}
}
}
}
}
Node.js
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const localFilePath = 'path/to/your/video.mp4'
// Imports the Google Cloud client libraries
const Video = require('@google-cloud/video-intelligence');
const fs = require('fs');
// Instantiates a client
const client = new Video.VideoIntelligenceServiceClient();
// Performs asynchronous video annotation for logo recognition on a file.
async function detectLogo() {
const inputContent = fs.readFileSync(localFilePath).toString('base64');
// Build the request with the input content and logo recognition feature.
const request = {
inputContent: inputContent,
features: ['LOGO_RECOGNITION'],
};
// Make the asynchronous request
const [operation] = await client.annotateVideo(request);
// Wait for the results
const [response] = await operation.promise();
// Get the first response, since we sent only one video.
const annotationResult = response.annotationResults[0];
for (const logoRecognitionAnnotation of annotationResult.logoRecognitionAnnotations) {
const entity = logoRecognitionAnnotation.entity;
// Opaque entity ID. Some IDs may be available in
// [Google Knowledge Graph Search API](https://developers.google.com/knowledge-graph/).
console.log(`Entity Id: ${entity.entityId}`);
console.log(`Description: ${entity.description}`);
// All logo tracks where the recognized logo appears.
// Each track corresponds to one logo instance appearing in consecutive frames.
for (const track of logoRecognitionAnnotation.tracks) {
console.log(
`\n\tStart Time Offset: ${track.segment.startTimeOffset.seconds}.${track.segment.startTimeOffset.nanos}`
);
console.log(
`\tEnd Time Offset: ${track.segment.endTimeOffset.seconds}.${track.segment.endTimeOffset.nanos}`
);
console.log(`\tConfidence: ${track.confidence}`);
// The object with timestamp and attributes per frame in the track.
for (const timestampedObject of track.timestampedObjects) {
// Normalized Bounding box in a frame, where the object is located.
const normalizedBoundingBox = timestampedObject.normalizedBoundingBox;
console.log(`\n\t\tLeft: ${normalizedBoundingBox.left}`);
console.log(`\t\tTop: ${normalizedBoundingBox.top}`);
console.log(`\t\tRight: ${normalizedBoundingBox.right}`);
console.log(`\t\tBottom: ${normalizedBoundingBox.bottom}`);
// Optional. The attributes of the object in the bounding box.
for (const attribute of timestampedObject.attributes) {
console.log(`\n\t\t\tName: ${attribute.name}`);
console.log(`\t\t\tConfidence: ${attribute.confidence}`);
console.log(`\t\t\tValue: ${attribute.value}`);
}
}
// Optional. Attributes in the track level.
for (const trackAttribute of track.attributes) {
console.log(`\n\t\tName: ${trackAttribute.name}`);
console.log(`\t\tConfidence: ${trackAttribute.confidence}`);
console.log(`\t\tValue: ${trackAttribute.value}`);
}
}
// All video segments where the recognized logo appears.
// There might be multiple instances of the same logo class appearing in one VideoSegment.
for (const segment of logoRecognitionAnnotation.segments) {
console.log(
`\n\tStart Time Offset: ${segment.startTimeOffset.seconds}.${segment.startTimeOffset.nanos}`
);
console.log(
`\tEnd Time Offset: ${segment.endTimeOffset.seconds}.${segment.endTimeOffset.nanos}`
);
}
}
}
detectLogo();
Python
如要向 Video Intelligence 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
import io
from google.cloud import videointelligence
def detect_logo(local_file_path="path/to/your/video.mp4"):
"""Performs asynchronous video annotation for logo recognition on a local file."""
client = videointelligence.VideoIntelligenceServiceClient()
with io.open(local_file_path, "rb") as f:
input_content = f.read()
features = [videointelligence.Feature.LOGO_RECOGNITION]
operation = client.annotate_video(
request={"features": features, "input_content": input_content}
)
print("Waiting for operation to complete...")
response = operation.result()
# Get the first response, since we sent only one video.
annotation_result = response.annotation_results[0]
# Annotations for list of logos detected, tracked and recognized in video.
for logo_recognition_annotation in annotation_result.logo_recognition_annotations:
entity = logo_recognition_annotation.entity
# Opaque entity ID. Some IDs may be available in [Google Knowledge Graph
# Search API](https://developers.google.com/knowledge-graph/).
print("Entity Id : {}".format(entity.entity_id))
print("Description : {}".format(entity.description))
# All logo tracks where the recognized logo appears. Each track corresponds
# to one logo instance appearing in consecutive frames.
for track in logo_recognition_annotation.tracks:
# Video segment of a track.
print(
"\n\tStart Time Offset : {}.{}".format(
track.segment.start_time_offset.seconds,
track.segment.start_time_offset.microseconds * 1000,
)
)
print(
"\tEnd Time Offset : {}.{}".format(
track.segment.end_time_offset.seconds,
track.segment.end_time_offset.microseconds * 1000,
)
)
print("\tConfidence : {}".format(track.confidence))
# The object with timestamp and attributes per frame in the track.
for timestamped_object in track.timestamped_objects:
# Normalized Bounding box in a frame, where the object is located.
normalized_bounding_box = timestamped_object.normalized_bounding_box
print("\n\t\tLeft : {}".format(normalized_bounding_box.left))
print("\t\tTop : {}".format(normalized_bounding_box.top))
print("\t\tRight : {}".format(normalized_bounding_box.right))
print("\t\tBottom : {}".format(normalized_bounding_box.bottom))
# Optional. The attributes of the object in the bounding box.
for attribute in timestamped_object.attributes:
print("\n\t\t\tName : {}".format(attribute.name))
print("\t\t\tConfidence : {}".format(attribute.confidence))
print("\t\t\tValue : {}".format(attribute.value))
# Optional. Attributes in the track level.
for track_attribute in track.attributes:
print("\n\t\tName : {}".format(track_attribute.name))
print("\t\tConfidence : {}".format(track_attribute.confidence))
print("\t\tValue : {}".format(track_attribute.value))
# All video segments where the recognized logo appears. There might be
# multiple instances of the same logo class appearing in one VideoSegment.
for segment in logo_recognition_annotation.segments:
print(
"\n\tStart Time Offset : {}.{}".format(
segment.start_time_offset.seconds,
segment.start_time_offset.microseconds * 1000,
)
)
print(
"\tEnd Time Offset : {}.{}".format(
segment.end_time_offset.seconds,
segment.end_time_offset.microseconds * 1000,
)
)
其他語言
C#: 請按照用戶端程式庫頁面上的 C# 設定說明操作, 然後參閱 .NET 適用的 Video Intelligence 參考說明文件。
PHP: 請按照用戶端程式庫頁面的 PHP 設定說明 操作,然後前往 PHP 適用的 Video Intelligence 參考文件。
Ruby: 請按照用戶端程式庫頁面的 Ruby 設定說明 操作,然後前往 Ruby 適用的 Video Intelligence 參考說明文件。