Skip to content

Commit 71fe4a5

Browse files
telpirionAhrar Monsur
authored andcommitted
feat: face and person detection samples (#362)
Adds the following region tags: video_detect_person_beta video_detect_person_gcs_beta video_detect_faces_beta video_detect_faces_gcs_beta
1 parent 20ce848 commit 71fe4a5

File tree

2 files changed

+411
-0
lines changed

2 files changed

+411
-0
lines changed
Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
async function detectPerson(path) {
18+
//[START video_detect_person_beta]
19+
// Imports the Google Cloud Video Intelligence library + Node's fs library
20+
const Video = require('@google-cloud/video-intelligence').v1p3beta1;
21+
const fs = require('fs');
22+
// Creates a client
23+
const video = new Video.VideoIntelligenceServiceClient();
24+
25+
/**
26+
* TODO(developer): Uncomment the following line before running the sample.
27+
*/
28+
// const path = 'Local file to analyze, e.g. ./my-file.mp4';
29+
30+
// Reads a local video file and converts it to base64
31+
const file = fs.readFileSync(path);
32+
const inputContent = file.toString('base64');
33+
34+
const request = {
35+
inputContent: inputContent,
36+
features: ['PERSON_DETECTION'],
37+
videoContext: {
38+
personDetectionConfig: {
39+
// Must set includeBoundingBoxes to true to get poses and attributes.
40+
includeBoundingBoxes: true,
41+
includePoseLandmarks: true,
42+
includeAttributes: true,
43+
},
44+
},
45+
};
46+
// Detects people in a video
47+
const [operation] = await video.annotateVideo(request);
48+
const results = await operation.promise();
49+
console.log('Waiting for operation to complete...');
50+
51+
// Gets annotations for video
52+
const personAnnotations =
53+
results[0].annotationResults[0].personDetectionAnnotations;
54+
55+
for (const {tracks} of personAnnotations) {
56+
console.log('Person detected:');
57+
for (const {segment, timestampedObjects} of tracks) {
58+
if (segment.startTimeOffset.seconds === undefined) {
59+
segment.startTimeOffset.seconds = 0;
60+
}
61+
if (segment.startTimeOffset.nanos === undefined) {
62+
segment.startTimeOffset.nanos = 0;
63+
}
64+
if (segment.endTimeOffset.seconds === undefined) {
65+
segment.endTimeOffset.seconds = 0;
66+
}
67+
if (segment.endTimeOffset.nanos === undefined) {
68+
segment.endTimeOffset.nanos = 0;
69+
}
70+
console.log(
71+
`\tStart: ${segment.startTimeOffset.seconds}.` +
72+
`${(segment.startTimeOffset.nanos / 1e6).toFixed(0)}s`
73+
);
74+
console.log(
75+
`\tEnd: ${segment.endTimeOffset.seconds}.` +
76+
`${(segment.endTimeOffset.nanos / 1e6).toFixed(0)}s`
77+
);
78+
79+
// Each segment includes timestamped objects that
80+
// include characteristic--e.g. clothes, posture
81+
// of the person detected.
82+
const [firstTimestampedObject] = timestampedObjects;
83+
84+
// Attributes include unique pieces of clothing,
85+
// poses, or hair color.
86+
for (const {name, value} of firstTimestampedObject.attributes) {
87+
console.log(`\tAttribute: ${name}; ` + `Value: ${value}`);
88+
}
89+
90+
// Landmarks in person detection include body parts.
91+
for (const {name, point} of firstTimestampedObject.landmarks) {
92+
console.log(`\tLandmark: ${name}; Vertex: ${point.x}, ${point.y}`);
93+
}
94+
}
95+
}
96+
// [END video_detect_person_beta]
97+
}
98+
async function detectPersonGCS(gcsUri) {
99+
//[START video_detect_person_gcs_beta]
100+
// Imports the Google Cloud Video Intelligence library
101+
const Video = require('@google-cloud/video-intelligence').v1p3beta1;
102+
// Creates a client
103+
const video = new Video.VideoIntelligenceServiceClient();
104+
105+
/**
106+
* TODO(developer): Uncomment the following line before running the sample.
107+
*/
108+
// const gcsUri = 'GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4';
109+
110+
const request = {
111+
inputUri: gcsUri,
112+
features: ['PERSON_DETECTION'],
113+
videoContext: {
114+
personDetectionConfig: {
115+
// Must set includeBoundingBoxes to true to get poses and attributes.
116+
includeBoundingBoxes: true,
117+
includePoseLandmarks: true,
118+
includeAttributes: true,
119+
},
120+
},
121+
};
122+
// Detects people in a video
123+
const [operation] = await video.annotateVideo(request);
124+
const results = await operation.promise();
125+
console.log('Waiting for operation to complete...');
126+
127+
// Gets annotations for video
128+
const personAnnotations =
129+
results[0].annotationResults[0].personDetectionAnnotations;
130+
131+
for (const {tracks} of personAnnotations) {
132+
console.log('Person detected:');
133+
134+
for (const {segment, timestampedObjects} of tracks) {
135+
if (segment.startTimeOffset.seconds === undefined) {
136+
segment.startTimeOffset.seconds = 0;
137+
}
138+
if (segment.startTimeOffset.nanos === undefined) {
139+
segment.startTimeOffset.nanos = 0;
140+
}
141+
if (segment.endTimeOffset.seconds === undefined) {
142+
segment.endTimeOffset.seconds = 0;
143+
}
144+
if (segment.endTimeOffset.nanos === undefined) {
145+
segment.endTimeOffset.nanos = 0;
146+
}
147+
console.log(
148+
`\tStart: ${segment.startTimeOffset.seconds}` +
149+
`.${(segment.startTimeOffset.nanos / 1e6).toFixed(0)}s`
150+
);
151+
console.log(
152+
`\tEnd: ${segment.endTimeOffset.seconds}.` +
153+
`${(segment.endTimeOffset.nanos / 1e6).toFixed(0)}s`
154+
);
155+
156+
// Each segment includes timestamped objects that
157+
// include characteristic--e.g. clothes, posture
158+
// of the person detected.
159+
const [firstTimestampedObject] = timestampedObjects;
160+
161+
// Attributes include unique pieces of clothing,
162+
// poses, or hair color.
163+
for (const {name, value} of firstTimestampedObject.attributes) {
164+
console.log(`\tAttribute: ${name}; ` + `Value: ${value}`);
165+
}
166+
167+
// Landmarks in person detection include body parts.
168+
for (const {name, point} of firstTimestampedObject.landmarks) {
169+
console.log(`\tLandmark: ${name}; Vertex: ${point.x}, ${point.y}`);
170+
}
171+
}
172+
}
173+
// [END video_detect_person_beta]
174+
}
175+
async function detectFaces(path) {
176+
//[START video_detect_faces_beta]
177+
// Imports the Google Cloud Video Intelligence library + Node's fs library
178+
const Video = require('@google-cloud/video-intelligence').v1p3beta1;
179+
const fs = require('fs');
180+
// Creates a client
181+
const video = new Video.VideoIntelligenceServiceClient();
182+
183+
/**
184+
* TODO(developer): Uncomment the following line before running the sample.
185+
*/
186+
// const path = 'Local file to analyze, e.g. ./my-file.mp4';
187+
188+
// Reads a local video file and converts it to base64
189+
const file = fs.readFileSync(path);
190+
const inputContent = file.toString('base64');
191+
192+
const request = {
193+
inputContent: inputContent,
194+
features: ['FACE_DETECTION'],
195+
videoContext: {
196+
faceDetectionConfig: {
197+
// Must set includeBoundingBoxes to true to get facial attributes.
198+
includeBoundingBoxes: true,
199+
includeAttributes: true,
200+
},
201+
},
202+
};
203+
// Detects faces in a video
204+
const [operation] = await video.annotateVideo(request);
205+
const results = await operation.promise();
206+
console.log('Waiting for operation to complete...');
207+
208+
// Gets annotations for video
209+
const faceAnnotations =
210+
results[0].annotationResults[0].faceDetectionAnnotations;
211+
212+
for (const {tracks} of faceAnnotations) {
213+
console.log('Face detected:');
214+
for (const {segment, timestampedObjects} of tracks) {
215+
if (segment.startTimeOffset.seconds === undefined) {
216+
segment.startTimeOffset.seconds = 0;
217+
}
218+
if (segment.startTimeOffset.nanos === undefined) {
219+
segment.startTimeOffset.nanos = 0;
220+
}
221+
if (segment.endTimeOffset.seconds === undefined) {
222+
segment.endTimeOffset.seconds = 0;
223+
}
224+
if (segment.endTimeOffset.nanos === undefined) {
225+
segment.endTimeOffset.nanos = 0;
226+
}
227+
console.log(
228+
`\tStart: ${segment.startTimeOffset.seconds}` +
229+
`.${(segment.startTimeOffset.nanos / 1e6).toFixed(0)}s`
230+
);
231+
console.log(
232+
`\tEnd: ${segment.endTimeOffset.seconds}.` +
233+
`${(segment.endTimeOffset.nanos / 1e6).toFixed(0)}s`
234+
);
235+
236+
// Each segment includes timestamped objects that
237+
// include characteristics of the face detected.
238+
const [firstTimestapedObject] = timestampedObjects;
239+
240+
for (const {name} of firstTimestapedObject.attributes) {
241+
// Attributes include unique pieces of clothing, like glasses,
242+
// poses, or hair color.
243+
console.log(`\tAttribute: ${name}; `);
244+
}
245+
}
246+
}
247+
}
248+
async function detectFacesGCS(gcsUri) {
249+
//[START video_detect_faces_gcs_beta]
250+
// Imports the Google Cloud Video Intelligence library
251+
const Video = require('@google-cloud/video-intelligence').v1p3beta1;
252+
// Creates a client
253+
const video = new Video.VideoIntelligenceServiceClient();
254+
255+
/**
256+
* TODO(developer): Uncomment the following line before running the sample.
257+
*/
258+
// const gcsUri = 'GCS URI of the video to analyze, e.g. gs://my-bucket/my-video.mp4';
259+
260+
const request = {
261+
inputUri: gcsUri,
262+
features: ['FACE_DETECTION'],
263+
videoContext: {
264+
faceDetectionConfig: {
265+
// Must set includeBoundingBoxes to true to get facial attributes.
266+
includeBoundingBoxes: true,
267+
includeAttributes: true,
268+
},
269+
},
270+
};
271+
// Detects faces in a video
272+
const [operation] = await video.annotateVideo(request);
273+
const results = await operation.promise();
274+
console.log('Waiting for operation to complete...');
275+
276+
// Gets annotations for video
277+
const faceAnnotations =
278+
results[0].annotationResults[0].faceDetectionAnnotations;
279+
280+
for (const {tracks} of faceAnnotations) {
281+
console.log('Face detected:');
282+
283+
for (const {segment, timestampedObjects} of tracks) {
284+
if (segment.startTimeOffset.seconds === undefined) {
285+
segment.startTimeOffset.seconds = 0;
286+
}
287+
if (segment.startTimeOffset.nanos === undefined) {
288+
segment.startTimeOffset.nanos = 0;
289+
}
290+
if (segment.endTimeOffset.seconds === undefined) {
291+
segment.endTimeOffset.seconds = 0;
292+
}
293+
if (segment.endTimeOffset.nanos === undefined) {
294+
segment.endTimeOffset.nanos = 0;
295+
}
296+
console.log(
297+
`\tStart: ${segment.startTimeOffset.seconds}.` +
298+
`${(segment.startTimeOffset.nanos / 1e6).toFixed(0)}s`
299+
);
300+
console.log(
301+
`\tEnd: ${segment.endTimeOffset.seconds}.` +
302+
`${(segment.endTimeOffset.nanos / 1e6).toFixed(0)}s`
303+
);
304+
305+
// Each segment includes timestamped objects that
306+
// include characteristics of the face detected.
307+
const [firstTimestapedObject] = timestampedObjects;
308+
309+
for (const {name} of firstTimestapedObject.attributes) {
310+
// Attributes include unique pieces of clothing, like glasses,
311+
// poses, or hair color.
312+
console.log(`\tAttribute: ${name}; `);
313+
}
314+
}
315+
}
316+
}
317+
318+
async function main() {
319+
require(`yargs`)
320+
.demand(1)
321+
.command(
322+
`video-person-gcs <gcsUri>`,
323+
`Detects people in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
324+
{},
325+
opts => detectPersonGCS(opts.gcsUri)
326+
)
327+
.command(
328+
`video-person <path>`,
329+
`Detects people in a video stored in a local file using the Cloud Video Intelligence API.`,
330+
{},
331+
opts => detectPerson(opts.path)
332+
)
333+
.command(
334+
`video-faces-gcs <gcsUri>`,
335+
`Detects faces in a video stored in Google Cloud Storage using the Cloud Video Intelligence API.`,
336+
{},
337+
opts => detectFacesGCS(opts.gcsUri)
338+
)
339+
.command(
340+
`video-faces <path>`,
341+
`Detects faces in a video stored in a local file using the Cloud Video Intelligence API.`,
342+
{},
343+
opts => detectFaces(opts.path)
344+
)
345+
.example(`node $0 video-person ./resources/googlework_short.mp4`)
346+
.example(
347+
`node $0 video-person-gcs gs://cloud-samples-data/video/googlework_short.mp4`
348+
)
349+
.example(`node $0 video-faces ./resources/googlework_short.mp4`)
350+
.example(
351+
`node $0 video-faces-gcs gs://cloud-samples-data/video/googlework_short.mp4`
352+
)
353+
.wrap(120)
354+
.recommendCommands()
355+
.epilogue(
356+
`For more information, see https://cloud.google.com/video-intelligence/docs`
357+
)
358+
.help()
359+
.strict().argv;
360+
}
361+
362+
main().catch(console.error);

0 commit comments

Comments
 (0)