Comprensione dei video negli agenti
Estrazione dei fotogrammi, sintesi dei video e ragionamento temporale sulle clip.
Comprensione dei video negli agenti è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.
Comprensione dei video per gli agenti
La maggior parte degli LLM non è in grado di elaborare direttamente i file video, ma gli agenti possono analizzare un video estraendo fotogrammi rappresentativi e inviandoli come immagini. L'agente ragiona quindi sulla sequenza visiva per rilevare eventi, cambiamenti e schemi nel tempo.
Installazione di OpenCV per l'estrazione dei fotogrammi
OpenCV (cv2) è la libreria standard per l'elaborazione video in Python. Consente di aprire file video, leggerne i metadati (frequenza dei fotogrammi, risoluzione, numero di fotogrammi) ed estrarre singoli fotogrammi come array NumPy.
# pip install opencv-python-headless
import cv2
def get_video_metadata(video_path: str) -> dict:
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise IOError(f'Cannot open video: {video_path}')
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
duration_s = frame_count / fps if fps > 0 else 0
cap.release()
return {
'fps': round(fps, 2),
'frame_count': frame_count,
'width': width,
'height': height,
'duration_seconds': round(duration_s, 2)
}
meta = get_video_metadata('recording.mp4')
print(meta)Estrazione dei fotogrammi ogni N secondi
Per la maggior parte delle attività di comprensione dei video, non è necessario utilizzare ogni fotogramma. Campionare un fotogramma ogni N secondi fornisce un riepilogo rappresentativo del contenuto del video. A 1 fotogramma al secondo, un video di 60 secondi produce 60 fotogrammi.
import cv2
import os
def extract_frames(
video_path: str,
output_dir: str,
every_n_seconds: float = 5.0
) -> list:
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
frame_interval = int(fps * every_n_seconds)
os.makedirs(output_dir, exist_ok=True)
saved_frames = []
frame_idx = 0
while True:
ret, frame = cap.read()
if not ret:
break
if frame_idx % frame_interval == 0:
timestamp = round(frame_idx / fps, 2)
fname = f'{output_dir}/frame_{frame_idx:06d}_{timestamp}s.jpg'
cv2.imwrite(fname, frame)
saved_frames.append({'path': fname, 'timestamp': timestamp})
frame_idx += 1
cap.release()
print(f'Extracted {len(saved_frames)} frames')
return saved_framesRilevamento dei cambiamenti di scena
Invece di effettuare un campionamento uniforme, estragga i fotogrammi in corrispondenza dei confini delle scene, cioè nei momenti in cui il contenuto visivo cambia significativamente. In questo modo si ottengono fotogrammi più informativi per ogni chiamata API. Utilizzi la differenza tra fotogrammi: se la differenza assoluta media tra fotogrammi consecutivi supera una soglia, si è verificato un cambiamento di scena.
import cv2
import numpy as np
def extract_scene_change_frames(
video_path: str,
output_dir: str,
diff_threshold: float = 30.0
) -> list:
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
os.makedirs(output_dir, exist_ok=True)
prev_gray = None
saved = []
frame_idx = 0
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if prev_gray is not None:
diff = np.mean(np.abs(gray.astype(float) - prev_gray.astype(float)))
if diff > diff_threshold:
ts = round(frame_idx / fps, 2)
fname = f'{output_dir}/scene_{frame_idx:06d}_{ts}s.jpg'
cv2.imwrite(fname, frame)
saved.append({'path': fname, 'timestamp': ts, 'diff': round(diff, 2)})
prev_gray = gray
frame_idx += 1
cap.release()
return savedInvio di una sequenza di fotogrammi all'API di visione
Invii più fotogrammi estratti all'API di visione in un unico messaggio. Includa il timestamp di ciascun fotogramma, affinché il modello possa ragionare sull'ordine temporale e sulla durata. Nel prompt, chieda esplicitamente di applicare il ragionamento temporale.
import base64
import anthropic
def describe_video_frames(frame_info_list: list, query: str) -> str:
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
content = []
for fi in frame_info_list:
with open(fi['path'], 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
content.append({
'type': 'text',
'text': f'Frame at {fi["timestamp"]}s:'
})
content.append({
'type': 'image',
'source': {'type': 'base64', 'media_type': 'image/jpeg', 'data': b64}
})
content.append({'type': 'text', 'text': query})
response = client.messages.create(
model='claude-opus-4-5',
max_tokens=1024,
messages=[{'role': 'user', 'content': content}]
)
return response.content[0].textPrompt per il ragionamento temporale
Il ragionamento temporale richiede una formulazione specifica del prompt. Chieda al modello di confrontare esplicitamente i fotogrammi, indicare che cosa è cambiato, stimare la durata delle attività e identificare i rapporti causali tra i fotogrammi.
TEMPORAL_QUERY = (
'You are analysing a video sequence. The frames above are in chronological order '
'with their timestamps shown. Please:\n'
'1. Describe what changed between the first and last frame\n'
'2. Identify any notable events and when they occurred (timestamp)\n'
'3. Summarise the overall activity shown in the video\n'
'4. Estimate the total duration of the main activity\n'
'Be specific about timestamps.'
)
# More targeted temporal query:
CHANGE_DETECTION_QUERY = (
'Compare frame at {start_ts}s and frame at {end_ts}s. '
'List all visible differences in bullet points. '
'Categorise each change as: object_moved, object_added, '
'object_removed, lighting_change, or camera_move.'
)
# Usage:
query = CHANGE_DETECTION_QUERY.format(start_ts=0.0, end_ts=20.0)
if __name__ == '__main__':
print('Temporal reasoning query:')
print(TEMPORAL_QUERY)
print()
print('Change detection query:')
print(query)
Pipeline di riepilogo video
Una pipeline completa per il riepilogo video segue questi passaggi: estrarre i fotogrammi → inviarli al modello di visione in batch → raccogliere i riepiloghi per batch → sintetizzare il riepilogo finale. L'elaborazione in batch evita di superare il limite della finestra di contesto.
def summarise_video(
video_path: str,
every_n_seconds: float = 10.0,
batch_size: int = 5
) -> str:
import anthropic
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
# Extract frames
frames = extract_frames(video_path, '/tmp/video_frames', every_n_seconds)
# Process in batches
batch_summaries = []
for i in range(0, len(frames), batch_size):
batch = frames[i:i + batch_size]
ts_range = f'{batch[0]["timestamp"]}s - {batch[-1]["timestamp"]}s'
query = f'Summarise what happens in this video segment ({ts_range}).'
summary = describe_video_frames(batch, query)
batch_summaries.append(f'[{ts_range}] {summary}')
# Synthesise
all_summaries = '\n\n'.join(batch_summaries)
result = client.messages.create(
model='claude-opus-4-5',
max_tokens=512,
messages=[{'role': 'user', 'content':
f'Here are segment-level video summaries:\n\n{all_summaries}\n\n'
'Write a single coherent summary of the entire video.'
}]
)
return result.content[0].textTracking degli oggetti tra i fotogrammi
Chieda al modello di visione di seguire oggetti specifici attraverso una sequenza di fotogrammi. Ad esempio: 'In ogni fotogramma, descriva la posizione dell'auto rossa: in alto a sinistra, in alto a destra, al centro, in basso a sinistra, in basso a destra.' In questo modo si crea una traiettoria di movimento approssimativa senza ricorrere ad algoritmi di tracciamento della computer vision.
def track_object_across_frames(
frames: list,
object_description: str
) -> list:
import anthropic, base64
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
trajectory = []
for fi in frames:
with open(fi['path'], 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
response = client.messages.create(
model='claude-opus-4-5',
max_tokens=128,
messages=[{
'role': 'user',
'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text':
f'Where is the {object_description} in this frame? '
'Answer with one of: top-left, top-right, centre, '
'bottom-left, bottom-right, not-visible.'}
]
}]
)
trajectory.append({
'timestamp': fi['timestamp'],
'position': response.content[0].text.strip()
})
return trajectoryGestione dei limiti sul numero di fotogrammi
Le finestre di contesto delle API di visione limitano il numero di immagini che è possibile inviare per richiesta (in genere da 5 a 20 immagini). Per i video lunghi, utilizzi un approccio gerarchico: analizzi i segmenti indipendentemente, quindi unisca i riepiloghi dei segmenti in un riepilogo finale tramite una seconda chiamata LLM.
MAX_FRAMES_PER_REQUEST = 8
def hierarchical_video_analysis(frames: list, final_query: str) -> str:
import anthropic
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
# Level 1: analyse each chunk
chunk_summaries = []
for i in range(0, len(frames), MAX_FRAMES_PER_REQUEST):
chunk = frames[i:i + MAX_FRAMES_PER_REQUEST]
ts = f'{chunk[0]["timestamp"]}s-{chunk[-1]["timestamp"]}s'
summary = describe_video_frames(
chunk, f'What happens in this segment ({ts})?'
)
chunk_summaries.append(f'Segment {ts}: {summary}')
# Level 2: synthesise all chunk summaries
combined = '\n'.join(chunk_summaries)
result = client.messages.create(
model='claude-opus-4-5',
max_tokens=512,
messages=[{
'role': 'user',
'content': f'Video segments:\n{combined}\n\n{final_query}'
}]
)
return result.content[0].textCombinazione dell'analisi audio e video
Per ottenere la comprensione più completa, combini l'analisi visiva a livello di fotogramma con la trascrizione audio di Whisper. L'agente può correlare ciò che viene visto con ciò che viene detto a ogni timestamp, abilitando attività efficaci come l'analisi di riunioni o l'indicizzazione di tutorial.
def full_video_analysis(video_path: str) -> dict:
import subprocess
# Step 1: Extract audio track
audio_path = '/tmp/video_audio.mp3'
subprocess.run([
'ffmpeg', '-i', video_path, '-q:a', '0', '-map', 'a',
audio_path, '-y'
], capture_output=True)
# Step 2: Transcribe audio
transcript_data = transcribe_with_timestamps(audio_path)
# Step 3: Extract key frames
frames = extract_frames(video_path, '/tmp/key_frames', every_n_seconds=15.0)
# Step 4: Visual summary
visual_summary = hierarchical_video_analysis(
frames, 'Summarise the visual content.'
)
return {
'transcript': transcript_data['full_text'],
'transcript_segments': transcript_data['segments'],
'visual_summary': visual_summary,
'frame_count': len(frames)
}Pulizia e gestione dei fotogrammi
I fotogrammi estratti possono accumularsi rapidamente. Elimini sempre i file temporanei dei fotogrammi dopo l'elaborazione e implementi una cache dei fotogrammi basata sull'hash di (video_path, frame_rate), per evitare di estrarre nuovamente i fotogrammi quando si analizza più volte lo stesso video.
import os
import shutil
import hashlib
FRAME_CACHE_DIR = '/tmp/frame_cache'
def get_cache_key(video_path: str, every_n_seconds: float) -> str:
content = f'{video_path}:{every_n_seconds}'
return hashlib.md5(content.encode()).hexdigest()[:12]
def get_or_extract_frames(video_path: str, every_n_seconds: float) -> list:
key = get_cache_key(video_path, every_n_seconds)
cache_dir = os.path.join(FRAME_CACHE_DIR, key)
if os.path.exists(cache_dir):
print(f'Cache hit: {key}')
files = sorted(os.listdir(cache_dir))
return [
{'path': os.path.join(cache_dir, f),
'timestamp': float(f.split('_')[-1].replace('s.jpg', ''))}
for f in files if f.endswith('.jpg')
]
return extract_frames(video_path, cache_dir, every_n_seconds)
def clear_frame_cache():
if os.path.exists(FRAME_CACHE_DIR):
shutil.rmtree(FRAME_CACHE_DIR)
print('Frame cache cleared')Verifica delle conoscenze
Perché il rilevamento dei cambiamenti di scena è preferibile al campionamento uniforme dei fotogrammi nell'analisi video?
Riepilogo: comprensione dei video negli agenti
Ottimo lavoro! Punti chiave di questa lezione:
- OpenCV: estragga i fotogrammi con
cap.read(); campioni ogni N secondi o in corrispondenza dei cambiamenti di scena - Sequenze di fotogrammi: le invii in ordine cronologico con i timestamp per fornire il contesto temporale
- Analisi gerarchica: suddivida in batch → riepiloghi dei segmenti → sintesi finale
- Analisi combinata: ffmpeg estrae l'audio; Whisper lo trascrive; effettui un confronto incrociato con i fotogrammi visivi
- Cache dei fotogrammi: eviti estrazioni ridondanti con una directory di cache basata su chiavi hash
Prossimo argomento: ragionamento cross-modale — quando il testo dice una cosa e l'immagine ne mostra un'altra.
Impara AI Agents con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 60
- Lezioni
- 239
Domande Frequenti
La lezione «Comprensione dei video negli agenti» è gratuita?
Sì — il testo completo di «Comprensione dei video negli agenti» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.
Cosa imparerò in «Comprensione dei video negli agenti»?
Estrazione dei fotogrammi, sintesi dei video e ragionamento temporale sulle clip. Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Agents?
Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Comprensione dei video negli agenti»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Agents?
Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Agenti multimodali di immagini e testo con Claude Vision e GPT-4V
- Workflow per agenti audio e testo
- Comprensione dei video negli agenti
- Pattern di ragionamento cross-modale