1. Descripción general

La API de Video Intelligence te permite usar la tecnología de análisis de videos de Google como parte de tus aplicaciones.
En este lab, te enfocarás en usar la API de Video Intelligence con Python.
Qué aprenderás
- Cómo configurar tu entorno
- Cómo configurar Python
- Cómo detectar cambios de toma
- Cómo detectar etiquetas
- Cómo detectar contenido explícito
- Cómo transcribir voz
- Cómo detectar y hacer un seguimiento del texto
- Cómo detectar objetos y hacerles seguimiento
- Cómo detectar y hacer un seguimiento de los logotipos
Requisitos
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia con los servicios de Google Cloud?
2. Configuración y requisitos
Configuración del entorno de autoaprendizaje
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.



- El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla cuando quieras.
- El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID de tu proyecto (suele identificarse como
PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usa el mismo durante todo el proyecto. - Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no costará mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de $300.
Inicia Cloud Shell
Si bien Google Cloud se puede operar de manera remota desde tu laptop, en este codelab usarás Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.
Activar Cloud Shell
- En la consola de Cloud, haz clic en Activar Cloud Shell
.

Si es la primera vez que inicias Cloud Shell, aparecerá una pantalla intermedia en la que se describirá qué es. Si apareció una pantalla intermedia, haz clic en Continuar.

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.
Una vez que te conectes a Cloud Shell, deberías ver que te autenticaste y que el proyecto se configuró con tu ID del proyecto.
- En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
gcloud auth list
Resultado del comando
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando gcloud conoce tu proyecto:
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
De lo contrario, puedes configurarlo con el siguiente comando:
gcloud config set project <PROJECT_ID>
Resultado del comando
Updated property [core/project].
3. Configuración del entorno
Antes de comenzar a usar la API de Video Intelligence, ejecuta el siguiente comando en Cloud Shell para habilitarla:
gcloud services enable videointelligence.googleapis.com
Deberías ver algo como esto:
Operation "operations/..." finished successfully.
Ahora puedes usar la API de Video Intelligence.
Navega a tu directorio principal:
cd ~
Crea un entorno virtual de Python para aislar las dependencias:
virtualenv venv-videointel
Activa el entorno virtual:
source venv-videointel/bin/activate
Instala IPython y la biblioteca cliente de la API de Video Intelligence:
pip install ipython google-cloud-videointelligence
Deberías ver algo como esto:
... Installing collected packages: ..., ipython, google-cloud-videointelligence Successfully installed ... google-cloud-videointelligence-2.11.0 ...
Ya está todo listo para usar la biblioteca cliente de la API de Video Intelligence.
En los siguientes pasos, usarás un intérprete de Python interactivo llamado IPython, que instalaste en el paso anterior. Inicia una sesión ejecutando ipython en Cloud Shell:
ipython
Deberías ver algo como esto:
Python 3.9.2 (default, Feb 28 2021, 17:03:44) Type 'copyright', 'credits' or 'license' for more information IPython 8.12.0 -- An enhanced Interactive Python. Type '?' for help. In [1]:
4. Video de muestra
Puedes usar la API de Video Intelligence para anotar videos almacenados en Cloud Storage o proporcionados como bytes de datos.
En los próximos pasos, usarás un video de muestra almacenado en Cloud Storage. Mira el video en tu navegador.

¡Preparados, listos, ya!
5. Detecta cambios de toma
Puedes usar la API de Video Intelligence para detectar cambios de toma en un video. Una toma es un segmento del video, una serie de fotogramas con continuidad visual.
Copia el siguiente código en tu sesión de IPython:
from typing import cast
from google.cloud import videointelligence_v1 as vi
def detect_shot_changes(video_uri: str) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.SHOT_CHANGE_DETECTION]
request = vi.AnnotateVideoRequest(input_uri=video_uri, features=features)
print(f'Processing video: "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Tómate un momento para estudiar el código y ver cómo usa el método de la biblioteca cliente annotate_video con el parámetro SHOT_CHANGE_DETECTION para analizar un video y detectar cambios de toma.
Llama a la función para analizar el video:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
results = detect_shot_changes(video_uri)
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir las tomas de video:
def print_video_shots(results: vi.VideoAnnotationResults):
shots = results.shot_annotations
print(f" Video shots: {len(shots)} ".center(40, "-"))
for i, shot in enumerate(shots):
t1 = shot.start_time_offset.total_seconds()
t2 = shot.end_time_offset.total_seconds()
print(f"{i+1:>3} | {t1:7.3f} | {t2:7.3f}")
Llama a la función:
print_video_shots(results)
Deberías ver algo como esto:
----------- Video shots: 34 ------------ 1 | 0.000 | 12.880 2 | 12.920 | 21.680 3 | 21.720 | 27.880 ... 32 | 135.160 | 138.320 33 | 138.360 | 146.200 34 | 146.240 | 162.520
Si extraes el fotograma central de cada toma y los organizas en una pared de fotogramas, puedes generar un resumen visual del video:

Resumen
En este paso, pudiste realizar la detección de cambios de toma en un video con la API de Video Intelligence. Puedes obtener más información para detectar cambios de toma.
6. Detectar etiquetas
Puedes usar la API de Video Intelligence para detectar etiquetas en un video. Las etiquetas describen el video según su contenido visual.
Copia el siguiente código en tu sesión de IPython:
from datetime import timedelta
from typing import Optional, Sequence, cast
from google.cloud import videointelligence_v1 as vi
def detect_labels(
video_uri: str,
mode: vi.LabelDetectionMode,
segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.LABEL_DETECTION]
config = vi.LabelDetectionConfig(label_detection_mode=mode)
context = vi.VideoContext(segments=segments, label_detection_config=config)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
print(f'Processing video "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Dedica un momento a estudiar el código y observa cómo usa el método de la biblioteca cliente annotate_video con el parámetro LABEL_DETECTION para analizar un video y detectar etiquetas.
Llama a la función para analizar los primeros 37 segundos del video:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
mode = vi.LabelDetectionMode.SHOT_MODE
segment = vi.VideoSegment(
start_time_offset=timedelta(seconds=0),
end_time_offset=timedelta(seconds=37),
)
results = detect_labels(video_uri, mode, [segment])
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir las etiquetas a nivel del video:
def print_video_labels(results: vi.VideoAnnotationResults):
labels = sorted_by_first_segment_confidence(results.segment_label_annotations)
print(f" Video labels: {len(labels)} ".center(80, "-"))
for label in labels:
categories = category_entities_to_str(label.category_entities)
for segment in label.segments:
confidence = segment.confidence
t1 = segment.segment.start_time_offset.total_seconds()
t2 = segment.segment.end_time_offset.total_seconds()
print(
f"{confidence:4.0%}",
f"{t1:7.3f}",
f"{t2:7.3f}",
f"{label.entity.description}{categories}",
sep=" | ",
)
def sorted_by_first_segment_confidence(
labels: Sequence[vi.LabelAnnotation],
) -> Sequence[vi.LabelAnnotation]:
def first_segment_confidence(label: vi.LabelAnnotation) -> float:
return label.segments[0].confidence
return sorted(labels, key=first_segment_confidence, reverse=True)
def category_entities_to_str(category_entities: Sequence[vi.Entity]) -> str:
if not category_entities:
return ""
entities = ", ".join([e.description for e in category_entities])
return f" ({entities})"
Llama a la función:
print_video_labels(results)
Deberías ver algo como esto:
------------------------------- Video labels: 10 ------------------------------- 96% | 0.000 | 36.960 | nature 74% | 0.000 | 36.960 | vegetation 59% | 0.000 | 36.960 | tree (plant) 56% | 0.000 | 36.960 | forest (geographical feature) 49% | 0.000 | 36.960 | leaf (plant) 43% | 0.000 | 36.960 | flora (plant) 38% | 0.000 | 36.960 | nature reserve (geographical feature) 38% | 0.000 | 36.960 | woodland (forest) 35% | 0.000 | 36.960 | water resources (water) 32% | 0.000 | 36.960 | sunlight (light)
Gracias a estas etiquetas a nivel del video, puedes comprender que el comienzo del video se centra principalmente en la naturaleza y la vegetación.
Agrega esta función para imprimir las etiquetas a nivel de la toma:
def print_shot_labels(results: vi.VideoAnnotationResults):
labels = sorted_by_first_segment_start_and_confidence(
results.shot_label_annotations
)
print(f" Shot labels: {len(labels)} ".center(80, "-"))
for label in labels:
categories = category_entities_to_str(label.category_entities)
print(f"{label.entity.description}{categories}")
for segment in label.segments:
confidence = segment.confidence
t1 = segment.segment.start_time_offset.total_seconds()
t2 = segment.segment.end_time_offset.total_seconds()
print(f"{confidence:4.0%} | {t1:7.3f} | {t2:7.3f}")
def sorted_by_first_segment_start_and_confidence(
labels: Sequence[vi.LabelAnnotation],
) -> Sequence[vi.LabelAnnotation]:
def first_segment_start_and_confidence(label: vi.LabelAnnotation):
first_segment = label.segments[0]
ms = first_segment.segment.start_time_offset.total_seconds()
return (ms, -first_segment.confidence)
return sorted(labels, key=first_segment_start_and_confidence)
Llama a la función:
print_shot_labels(results)
Deberías ver algo como esto:
------------------------------- Shot labels: 29 -------------------------------- planet (astronomical object) 83% | 0.000 | 12.880 earth (planet) 53% | 0.000 | 12.880 water resources (water) 43% | 0.000 | 12.880 aerial photography (photography) 43% | 0.000 | 12.880 vegetation 32% | 0.000 | 12.880 92% | 12.920 | 21.680 83% | 21.720 | 27.880 77% | 27.920 | 31.800 76% | 31.840 | 34.720 ... butterfly (insect, animal) 84% | 34.760 | 36.960 ...
Gracias a estas etiquetas a nivel de la toma, puedes comprender que el video comienza con una toma de un planeta (probablemente la Tierra), que hay una mariposa en la toma de 34.760-36.960s…
Resumen
En este paso, pudiste realizar la detección de etiquetas en un video con la API de Video Intelligence. Puedes obtener más información para detectar etiquetas.
7. Detecta contenido explícito
Puedes usar la API de Video Intelligence para detectar contenido explícito en un video. El contenido explícito es contenido para adultos que, por lo general, es inapropiado para menores de 18 años e incluye, entre otros, imágenes de desnudos, actividades sexuales y pornografía. La detección se realiza solo en función de los indicadores visuales por fotograma (no se usa el audio). La respuesta incluye valores de probabilidad que van de VERY_UNLIKELY a VERY_LIKELY.
Copia el siguiente código en tu sesión de IPython:
from datetime import timedelta
from typing import Optional, Sequence, cast
from google.cloud import videointelligence_v1 as vi
def detect_explicit_content(
video_uri: str,
segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.EXPLICIT_CONTENT_DETECTION]
context = vi.VideoContext(segments=segments)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
print(f'Processing video "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Dedica un momento a estudiar el código y observa cómo usa el método de la biblioteca cliente annotate_video con el parámetro EXPLICIT_CONTENT_DETECTION para analizar un video y detectar contenido explícito.
Llama a la función para analizar los primeros 10 segundos del video:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
start_time_offset=timedelta(seconds=0),
end_time_offset=timedelta(seconds=10),
)
results = detect_explicit_content(video_uri, [segment])
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir los diferentes recuentos de verosimilitud:
def print_explicit_content(results: vi.VideoAnnotationResults):
from collections import Counter
frames = results.explicit_annotation.frames
likelihood_counts = Counter([f.pornography_likelihood for f in frames])
print(f" Explicit content frames: {len(frames)} ".center(40, "-"))
for likelihood in vi.Likelihood:
print(f"{likelihood.name:<22}: {likelihood_counts[likelihood]:>3}")
Llama a la función:
print_explicit_content(results)
Deberías ver algo como esto:
----- Explicit content frames: 10 ------ LIKELIHOOD_UNSPECIFIED: 0 VERY_UNLIKELY : 10 UNLIKELY : 0 POSSIBLE : 0 LIKELY : 0 VERY_LIKELY : 0
Agrega esta función para imprimir los detalles del fotograma:
def print_frames(results: vi.VideoAnnotationResults, likelihood: vi.Likelihood):
frames = results.explicit_annotation.frames
frames = [f for f in frames if f.pornography_likelihood == likelihood]
print(f" {likelihood.name} frames: {len(frames)} ".center(40, "-"))
for frame in frames:
print(frame.time_offset)
Llama a la función:
print_frames(results, vi.Likelihood.VERY_UNLIKELY)
Deberías ver algo como esto:
------- VERY_UNLIKELY frames: 10 ------- 0:00:00.365992 0:00:01.279206 0:00:02.268336 0:00:03.289253 0:00:04.400163 0:00:05.291547 0:00:06.449558 0:00:07.452751 0:00:08.577405 0:00:09.554514
Resumen
En este paso, pudiste realizar la detección de contenido explícito en un video con la API de Video Intelligence. Puedes obtener más información para detectar contenido explícito.
8. Transcribir voz
Puedes usar la API de Video Intelligence para transcribir el audio de un video a texto.
Copia el siguiente código en tu sesión de IPython:
from datetime import timedelta
from typing import Optional, Sequence, cast
from google.cloud import videointelligence_v1 as vi
def transcribe_speech(
video_uri: str,
language_code: str,
segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.SPEECH_TRANSCRIPTION]
config = vi.SpeechTranscriptionConfig(
language_code=language_code,
enable_automatic_punctuation=True,
)
context = vi.VideoContext(
segments=segments,
speech_transcription_config=config,
)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
print(f'Processing video "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Dedica un momento a estudiar el código y observa cómo usa el método de la biblioteca cliente annotate_video con el parámetro SPEECH_TRANSCRIPTION para analizar un video y transcribir el discurso.
Llama a la función para analizar el video desde el segundo 55 hasta el 80:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
language_code = "en-GB"
segment = vi.VideoSegment(
start_time_offset=timedelta(seconds=55),
end_time_offset=timedelta(seconds=80),
)
results = transcribe_speech(video_uri, language_code, [segment])
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir el discurso transcrito:
def print_video_speech(results: vi.VideoAnnotationResults, min_confidence: float = 0.8):
def keep_transcription(transcription: vi.SpeechTranscription) -> bool:
return min_confidence <= transcription.alternatives[0].confidence
transcriptions = results.speech_transcriptions
transcriptions = [t for t in transcriptions if keep_transcription(t)]
print(f" Speech transcriptions: {len(transcriptions)} ".center(80, "-"))
for transcription in transcriptions:
first_alternative = transcription.alternatives[0]
confidence = first_alternative.confidence
transcript = first_alternative.transcript
print(f" {confidence:4.0%} | {transcript.strip()}")
Llama a la función:
print_video_speech(results)
Deberías ver algo como esto:
--------------------------- Speech transcriptions: 2 --------------------------- 91% | I was keenly aware of secret movements in the trees. 92% | I looked into his large and lustrous eyes. They seem somehow to express his entire personality.
Agrega esta función para imprimir la lista de palabras detectadas y sus marcas de tiempo:
def print_word_timestamps(
results: vi.VideoAnnotationResults,
min_confidence: float = 0.8,
):
def keep_transcription(transcription: vi.SpeechTranscription) -> bool:
return min_confidence <= transcription.alternatives[0].confidence
transcriptions = results.speech_transcriptions
transcriptions = [t for t in transcriptions if keep_transcription(t)]
print(" Word timestamps ".center(80, "-"))
for transcription in transcriptions:
first_alternative = transcription.alternatives[0]
confidence = first_alternative.confidence
for word in first_alternative.words:
t1 = word.start_time.total_seconds()
t2 = word.end_time.total_seconds()
word = word.word
print(f"{confidence:4.0%} | {t1:7.3f} | {t2:7.3f} | {word}")
Llama a la función:
print_word_timestamps(results)
Deberías ver algo como esto:
------------------------------- Word timestamps -------------------------------- 93% | 55.000 | 55.700 | I 93% | 55.700 | 55.900 | was 93% | 55.900 | 56.300 | keenly 93% | 56.300 | 56.700 | aware 93% | 56.700 | 56.900 | of ... 94% | 76.900 | 77.400 | express 94% | 77.400 | 77.600 | his 94% | 77.600 | 78.200 | entire 94% | 78.200 | 78.500 | personality.
Resumen
En este paso, pudiste realizar la transcripción de voz en un video con la API de Video Intelligence. Obtén más información para transcribir audio.
9. Detecta y hace un seguimiento del texto
Puedes usar la API de Video Intelligence para detectar y hacer un seguimiento del texto en un video.
Copia el siguiente código en tu sesión de IPython:
from datetime import timedelta
from typing import Optional, Sequence, cast
from google.cloud import videointelligence_v1 as vi
def detect_text(
video_uri: str,
language_hints: Optional[Sequence[str]] = None,
segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.TEXT_DETECTION]
config = vi.TextDetectionConfig(
language_hints=language_hints,
)
context = vi.VideoContext(
segments=segments,
text_detection_config=config,
)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
print(f'Processing video "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Dedica un momento a estudiar el código y observa cómo usa el método de la biblioteca cliente annotate_video con el parámetro TEXT_DETECTION para analizar un video y detectar texto.
Llama a la función para analizar el video desde el segundo 13 hasta el 27:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
start_time_offset=timedelta(seconds=13),
end_time_offset=timedelta(seconds=27),
)
results = detect_text(video_uri, segments=[segment])
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir el texto detectado:
def print_video_text(results: vi.VideoAnnotationResults, min_frames: int = 15):
annotations = sorted_by_first_segment_end(results.text_annotations)
print(" Detected text ".center(80, "-"))
for annotation in annotations:
for text_segment in annotation.segments:
frames = len(text_segment.frames)
if frames < min_frames:
continue
text = annotation.text
confidence = text_segment.confidence
start = text_segment.segment.start_time_offset
seconds = segment_seconds(text_segment.segment)
print(text)
print(f" {confidence:4.0%} | {start} + {seconds:.1f}s | {frames} fr.")
def sorted_by_first_segment_end(
annotations: Sequence[vi.TextAnnotation],
) -> Sequence[vi.TextAnnotation]:
def first_segment_end(annotation: vi.TextAnnotation) -> int:
return annotation.segments[0].segment.end_time_offset.total_seconds()
return sorted(annotations, key=first_segment_end)
def segment_seconds(segment: vi.VideoSegment) -> float:
t1 = segment.start_time_offset.total_seconds()
t2 = segment.end_time_offset.total_seconds()
return t2 - t1
Llama a la función:
print_video_text(results)
Deberías ver algo como esto:
-------------------------------- Detected text --------------------------------- GOMBE NATIONAL PARK 99% | 0:00:15.760000 + 1.7s | 15 fr. TANZANIA 100% | 0:00:15.760000 + 4.8s | 39 fr. With words and narration by 100% | 0:00:23.200000 + 3.6s | 31 fr. Jane Goodall 99% | 0:00:23.080000 + 3.8s | 33 fr.
Agrega esta función para imprimir la lista de los cuadros delimitadores y los fotogramas de texto detectados:
def print_text_frames(results: vi.VideoAnnotationResults, contained_text: str):
# Vertex order: top-left, top-right, bottom-right, bottom-left
def box_top_left(box: vi.NormalizedBoundingPoly) -> str:
tl = box.vertices[0]
return f"({tl.x:.5f}, {tl.y:.5f})"
def box_bottom_right(box: vi.NormalizedBoundingPoly) -> str:
br = box.vertices[2]
return f"({br.x:.5f}, {br.y:.5f})"
annotations = results.text_annotations
annotations = [a for a in annotations if contained_text in a.text]
for annotation in annotations:
print(f" {annotation.text} ".center(80, "-"))
for text_segment in annotation.segments:
for frame in text_segment.frames:
frame_ms = frame.time_offset.total_seconds()
box = frame.rotated_bounding_box
print(
f"{frame_ms:>7.3f}",
box_top_left(box),
box_bottom_right(box),
sep=" | ",
)
Llama a la función para verificar qué fotogramas muestran el nombre del narrador:
contained_text = "Goodall"
print_text_frames(results, contained_text)
Deberías ver algo como esto:
--------------------------------- Jane Goodall --------------------------------- 23.080 | (0.39922, 0.49861) | (0.62752, 0.55888) 23.200 | (0.38750, 0.49028) | (0.62692, 0.56306) ... 26.800 | (0.36016, 0.49583) | (0.61094, 0.56048) 26.920 | (0.45859, 0.49583) | (0.60365, 0.56174)
Si dibujas los cuadros de límite sobre los fotogramas correspondientes, obtendrás lo siguiente:

Resumen
En este paso, pudiste realizar la detección y el seguimiento de texto en un video con la API de Video Intelligence. Puedes obtener más información para detectar y hacer un seguimiento del texto.
10. Detecta y hace un seguimiento de los objetos
Puedes usar la API de Video Intelligence para detectar objetos y hacerles seguimiento en un video.
Copia el siguiente código en tu sesión de IPython:
from datetime import timedelta
from typing import Optional, Sequence, cast
from google.cloud import videointelligence_v1 as vi
def track_objects(
video_uri: str, segments: Optional[Sequence[vi.VideoSegment]] = None
) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.OBJECT_TRACKING]
context = vi.VideoContext(segments=segments)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
print(f'Processing video "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Dedica un momento a estudiar el código y observa cómo usa el método de la biblioteca cliente annotate_video con el parámetro OBJECT_TRACKING para analizar un video y detectar objetos.
Llama a la función para analizar el video desde el segundo 98 hasta el 112:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
start_time_offset=timedelta(seconds=98),
end_time_offset=timedelta(seconds=112),
)
results = track_objects(video_uri, [segment])
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir la lista de objetos detectados:
def print_detected_objects(
results: vi.VideoAnnotationResults,
min_confidence: float = 0.7,
):
annotations = results.object_annotations
annotations = [a for a in annotations if min_confidence <= a.confidence]
print(
f" Detected objects: {len(annotations)}"
f" ({min_confidence:.0%} <= confidence) ".center(80, "-")
)
for annotation in annotations:
entity = annotation.entity
description = entity.description
entity_id = entity.entity_id
confidence = annotation.confidence
t1 = annotation.segment.start_time_offset.total_seconds()
t2 = annotation.segment.end_time_offset.total_seconds()
frames = len(annotation.frames)
print(
f"{description:<22}",
f"{entity_id:<10}",
f"{confidence:4.0%}",
f"{t1:>7.3f}",
f"{t2:>7.3f}",
f"{frames:>2} fr.",
sep=" | ",
)
Llama a la función:
print_detected_objects(results)
Deberías ver algo como esto:
------------------- Detected objects: 3 (70% <= confidence) -------------------- insect | /m/03vt0 | 87% | 98.840 | 101.720 | 25 fr. insect | /m/03vt0 | 71% | 108.440 | 111.080 | 23 fr. butterfly | /m/0cyf8 | 91% | 111.200 | 111.920 | 7 fr.
Agrega esta función para imprimir la lista de fotogramas de objetos detectados y cuadros delimitadores:
def print_object_frames(
results: vi.VideoAnnotationResults,
entity_id: str,
min_confidence: float = 0.7,
):
def keep_annotation(annotation: vi.ObjectTrackingAnnotation) -> bool:
return (
annotation.entity.entity_id == entity_id
and min_confidence <= annotation.confidence
)
annotations = results.object_annotations
annotations = [a for a in annotations if keep_annotation(a)]
for annotation in annotations:
description = annotation.entity.description
confidence = annotation.confidence
print(
f" {description},"
f" confidence: {confidence:.0%},"
f" frames: {len(annotation.frames)} ".center(80, "-")
)
for frame in annotation.frames:
t = frame.time_offset.total_seconds()
box = frame.normalized_bounding_box
print(
f"{t:>7.3f}",
f"({box.left:.5f}, {box.top:.5f})",
f"({box.right:.5f}, {box.bottom:.5f})",
sep=" | ",
)
Llama a la función con el ID de entidad para insectos:
insect_entity_id = "/m/03vt0"
print_object_frames(results, insect_entity_id)
Deberías ver algo como esto:
--------------------- insect, confidence: 87%, frames: 25 ---------------------- 98.840 | (0.49327, 0.19617) | (0.69905, 0.69633) 98.960 | (0.49559, 0.19308) | (0.70631, 0.69671) ... 101.600 | (0.46668, 0.19776) | (0.76619, 0.69371) 101.720 | (0.46805, 0.20053) | (0.76447, 0.68703) --------------------- insect, confidence: 71%, frames: 23 ---------------------- 108.440 | (0.47343, 0.10694) | (0.63821, 0.98332) 108.560 | (0.46960, 0.10206) | (0.63033, 0.98285) ... 110.960 | (0.49466, 0.05102) | (0.65941, 0.99357) 111.080 | (0.49572, 0.04728) | (0.65762, 0.99868)
Si dibujas los cuadros de límite sobre los fotogramas correspondientes, obtendrás lo siguiente:


Resumen
En este paso, pudiste realizar la detección y el seguimiento de objetos en un video con la API de Video Intelligence. Puedes obtener más información para detectar y hacer un seguimiento de objetos.
11. Detecta y hace un seguimiento de los logotipos
Puedes usar la API de Video Intelligence para detectar y hacer un seguimiento de los logotipos en un video. Se pueden detectar más de 100,000 marcas y logotipos.
Copia el siguiente código en tu sesión de IPython:
from datetime import timedelta
from typing import Optional, Sequence, cast
from google.cloud import videointelligence_v1 as vi
def detect_logos(
video_uri: str, segments: Optional[Sequence[vi.VideoSegment]] = None
) -> vi.VideoAnnotationResults:
video_client = vi.VideoIntelligenceServiceClient()
features = [vi.Feature.LOGO_RECOGNITION]
context = vi.VideoContext(segments=segments)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
print(f'Processing video "{video_uri}"...')
operation = video_client.annotate_video(request)
# Wait for operation to complete
response = cast(vi.AnnotateVideoResponse, operation.result())
# A single video is processed
results = response.annotation_results[0]
return results
Dedica un momento a estudiar el código y observa cómo usa el método de la biblioteca cliente annotate_video con el parámetro LOGO_RECOGNITION para analizar un video y detectar logotipos.
Llama a la función para analizar la penúltima secuencia del video:
video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
start_time_offset=timedelta(seconds=146),
end_time_offset=timedelta(seconds=156),
)
results = detect_logos(video_uri, [segment])
Espera a que se procese el video:
Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...
Agrega esta función para imprimir la lista de logotipos detectados:
def print_detected_logos(results: vi.VideoAnnotationResults):
annotations = results.logo_recognition_annotations
print(f" Detected logos: {len(annotations)} ".center(80, "-"))
for annotation in annotations:
entity = annotation.entity
entity_id = entity.entity_id
description = entity.description
for track in annotation.tracks:
confidence = track.confidence
t1 = track.segment.start_time_offset.total_seconds()
t2 = track.segment.end_time_offset.total_seconds()
logo_frames = len(track.timestamped_objects)
print(
f"{confidence:4.0%}",
f"{t1:>7.3f}",
f"{t2:>7.3f}",
f"{logo_frames:>3} fr.",
f"{entity_id:<15}",
f"{description}",
sep=" | ",
)
Llama a la función:
print_detected_logos(results)
Deberías ver algo como esto:
------------------------------ Detected logos: 1 ------------------------------- 92% | 150.680 | 155.720 | 43 fr. | /m/055t58 | Google Maps
Agrega esta función para imprimir la lista de fotogramas y cuadros delimitadores de logotipos detectados:
def print_logo_frames(results: vi.VideoAnnotationResults, entity_id: str):
def keep_annotation(annotation: vi.LogoRecognitionAnnotation) -> bool:
return annotation.entity.entity_id == entity_id
annotations = results.logo_recognition_annotations
annotations = [a for a in annotations if keep_annotation(a)]
for annotation in annotations:
description = annotation.entity.description
for track in annotation.tracks:
confidence = track.confidence
print(
f" {description},"
f" confidence: {confidence:.0%},"
f" frames: {len(track.timestamped_objects)} ".center(80, "-")
)
for timestamped_object in track.timestamped_objects:
t = timestamped_object.time_offset.total_seconds()
box = timestamped_object.normalized_bounding_box
print(
f"{t:>7.3f}",
f"({box.left:.5f}, {box.top:.5f})",
f"({box.right:.5f}, {box.bottom:.5f})",
sep=" | ",
)
Llama a la función con el ID de entidad del logotipo de Google Maps:
maps_entity_id = "/m/055t58"
print_logo_frames(results, maps_entity_id)
Deberías ver algo como esto:
------------------- Google Maps, confidence: 92%, frames: 43 ------------------- 150.680 | (0.42024, 0.28633) | (0.58192, 0.64220) 150.800 | (0.41713, 0.27822) | (0.58318, 0.63556) ... 155.600 | (0.41775, 0.27701) | (0.58372, 0.63986) 155.720 | (0.41688, 0.28005) | (0.58335, 0.63954)
Si dibujas los cuadros de límite sobre los fotogramas correspondientes, obtendrás lo siguiente:

Resumen
En este paso, pudiste realizar la detección y el seguimiento de logotipos en un video con la API de Video Intelligence. Puedes obtener más información para detectar y hacer un seguimiento de los logotipos.
12. Detecta varias características
Aquí se muestra el tipo de solicitud que puedes hacer para obtener todas las estadísticas de una vez:
from google.cloud import videointelligence_v1 as vi
video_client = vi.VideoIntelligenceServiceClient()
video_uri = "gs://..."
features = [
vi.Feature.SHOT_CHANGE_DETECTION,
vi.Feature.LABEL_DETECTION,
vi.Feature.EXPLICIT_CONTENT_DETECTION,
vi.Feature.SPEECH_TRANSCRIPTION,
vi.Feature.TEXT_DETECTION,
vi.Feature.OBJECT_TRACKING,
vi.Feature.LOGO_RECOGNITION,
vi.Feature.FACE_DETECTION, # NEW
vi.Feature.PERSON_DETECTION, # NEW
]
context = vi.VideoContext(
segments=...,
shot_change_detection_config=...,
label_detection_config=...,
explicit_content_detection_config=...,
speech_transcription_config=...,
text_detection_config=...,
object_tracking_config=...,
face_detection_config=..., # NEW
person_detection_config=..., # NEW
)
request = vi.AnnotateVideoRequest(
input_uri=video_uri,
features=features,
video_context=context,
)
# video_client.annotate_video(request)
13. ¡Felicitaciones!

Aprendiste a usar la API de Video Intelligence con Python.
Limpia
Para limpiar tu entorno de desarrollo, sigue estos pasos desde Cloud Shell:
- Si aún estás en tu sesión de IPython, vuelve a la shell:
exit - Deja de usar el entorno virtual de Python:
deactivate - Borra la carpeta del entorno virtual:
cd ~ ; rm -rf ./venv-videointel
Para borrar tu proyecto de Google Cloud, desde Cloud Shell, haz lo siguiente:
- Recupera el ID del proyecto actual:
PROJECT_ID=$(gcloud config get-value core/project) - Asegúrate de que este sea el proyecto que quieres borrar:
echo $PROJECT_ID - Borra el proyecto:
gcloud projects delete $PROJECT_ID
Más información
- Prueba la demostración en tu navegador: https://zackakil.github.io/video-intelligence-api-visualiser
- Documentación de Video Intelligence: https://cloud.google.com/video-intelligence/docs
- Funciones en versión beta: https://cloud.google.com/video-intelligence/docs/beta
- Python en Google Cloud: https://cloud.google.com/python
- Bibliotecas cliente de Cloud para Python: https://github.com/googleapis/google-cloud-python
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.