본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 6장: 비디오 이해와 분석
2026년 2월 17일·AI / ML·

6장: 비디오 이해와 분석

멀티모달 AI를 활용한 비디오 이해 기법 — 프레임 추출 전략, 시간적 추론, 영상 요약, 그리고 실시간 비디오 분석 파이프라인 설계를 다룹니다.

12분577자6개 섹션
llmmultimodalembedding
공유
multimodal-ai6 / 11
1234567891011
이전5장: 음성 AI — STT, TTS, 실시간 음성 대화다음7장: 멀티모달 임베딩과 크로스모달 검색

5장에서 음성 AI를 다뤘습니다. 이 장에서는 멀티모달 AI의 시간적 차원인 비디오 이해를 다룹니다. 비디오는 이미지(시각)와 음성(청각)이 시간 축을 따라 결합된 가장 풍부한 멀티모달 데이터입니다. VLM을 활용한 프레임 분석, 시간적 추론, 영상 요약 기법을 살펴봅니다.

비디오 이해의 접근 방식

프레임 기반 접근

대부분의 현재 VLM은 비디오를 네이티브로 처리하지 않습니다(Gemini 제외). 대신 핵심 프레임을 추출하여 이미지로 분석하는 접근을 사용합니다.

비디오 → [프레임 추출] → 핵심 프레임 N개 → [VLM] → 분석 결과
        + [음성 추출] → [STT] → 자막/텍스트 ↗

네이티브 비디오 입력

Gemini 2.0은 비디오를 직접 입력으로 받을 수 있으며, 최대 1시간 분량의 영상을 처리합니다. 이 경우 별도의 프레임 추출 없이 시간적 맥락을 자연스럽게 이해합니다.

프레임 추출 전략

균일 샘플링

가장 단순한 방법으로, 일정 간격으로 프레임을 추출합니다.

균일 프레임 샘플링
python
import cv2
from pathlib import Path
 
def extract_frames_uniform(
    video_path: str,
    num_frames: int = 10,
    output_dir: str = "/tmp/frames"
) -> list[str]:
    """비디오에서 균일 간격으로 프레임 추출"""
    Path(output_dir).mkdir(parents=True, exist_ok=True)
 
    cap = cv2.VideoCapture(video_path)
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    fps = cap.get(cv2.CAP_PROP_FPS)
    duration = total_frames / fps
 
    # 균일 간격 계산
    interval = total_frames // num_frames
    frame_paths = []
 
    for i in range(num_frames):
        frame_idx = i * interval
        cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx)
        ret, frame = cap.read()
        if ret:
            timestamp = frame_idx / fps
            path = f"{output_dir}/frame_{i:03d}_{timestamp:.1f}s.jpg"
            cv2.imwrite(path, frame)
            frame_paths.append(path)
 
    cap.release()
    return frame_paths

장면 전환 기반 추출

영상의 시각적 변화가 큰 지점에서 프레임을 추출합니다.

장면 전환 감지
python
import numpy as np
 
def extract_scene_changes(
    video_path: str,
    threshold: float = 30.0,
    max_frames: int = 20
) -> list[tuple[int, float]]:
    """장면 전환 지점에서 프레임 추출"""
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    scene_frames = []
    prev_frame = None
 
    frame_idx = 0
    while True:
        ret, frame = cap.read()
        if not ret:
            break
 
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
        if prev_frame is not None:
            # 프레임 간 차이 계산
            diff = cv2.absdiff(prev_frame, gray)
            mean_diff = np.mean(diff)
 
            if mean_diff > threshold:
                timestamp = frame_idx / fps
                scene_frames.append((frame_idx, timestamp))
 
        prev_frame = gray
        frame_idx += 1
 
    cap.release()
 
    # 최대 프레임 수 제한
    if len(scene_frames) > max_frames:
        indices = np.linspace(0, len(scene_frames) - 1, max_frames, dtype=int)
        scene_frames = [scene_frames[i] for i in indices]
 
    return scene_frames
Tip

프레임 추출 전략의 선택은 비디오의 성격에 따라 달라집니다. 강의 영상은 슬라이드 전환 감지가 효과적이고, 뉴스/대화는 균일 샘플링이 적합하며, 스포츠/액션은 움직임 기반 추출이 좋습니다. 대부분의 경우, 균일 샘플링으로 시작하여 필요에 따라 전략을 조정하는 것이 실용적입니다.

VLM을 활용한 비디오 분석

다중 프레임 분석

프레임 시퀀스 분석
python
import anthropic
import base64
 
client = anthropic.Anthropic()
 
def analyze_video_frames(frame_paths: list[str], question: str) -> str:
    """추출된 프레임으로 비디오 분석"""
    content = []
 
    for i, path in enumerate(frame_paths):
        # 타임스탬프 추출 (파일명에서)
        timestamp = path.split("_")[-1].replace("s.jpg", "")
 
        with open(path, "rb") as f:
            img_data = base64.standard_b64encode(f.read()).decode("utf-8")
 
        content.append({
            "type": "text",
            "text": f"[프레임 {i+1} — {timestamp}초]",
        })
        content.append({
            "type": "image",
            "source": {"type": "base64", "media_type": "image/jpeg", "data": img_data},
        })
 
    content.append({
        "type": "text",
        "text": f"""위 프레임들은 하나의 비디오에서 시간순으로 추출된 것입니다.
 
질문: {question}
 
비디오의 시간적 흐름을 고려하여 답변해주세요.""",
    })
 
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=4096,
        messages=[{"role": "user", "content": content}],
    )
    return response.content[0].text

영상 + 자막 결합 분석

비디오 + 자막 통합 분석
python
def analyze_video_with_transcript(
    frame_paths: list[str],
    transcript: str,
    task: str
) -> str:
    """프레임과 자막을 결합한 분석"""
    content = []
 
    # 프레임 추가
    for path in frame_paths:
        with open(path, "rb") as f:
            img_data = base64.standard_b64encode(f.read()).decode("utf-8")
        content.append({
            "type": "image",
            "source": {"type": "base64", "media_type": "image/jpeg", "data": img_data},
        })
 
    # 자막과 분석 지시 추가
    content.append({
        "type": "text",
        "text": f"""위 이미지들은 비디오의 핵심 프레임입니다.
 
아래는 비디오의 음성 자막입니다:
---
{transcript}
---
 
작업: {task}
 
시각적 정보와 음성 내용을 모두 활용하여 분석해주세요.""",
    })
 
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=4096,
        messages=[{"role": "user", "content": content}],
    )
    return response.content[0].text

활용 패턴

강의 영상 요약

강의 요약 파이프라인
python
async def summarize_lecture(video_path: str) -> dict:
    """강의 영상 자동 요약"""
    # 1. 음성 추출 및 STT
    transcript = await transcribe_audio(video_path)
 
    # 2. 슬라이드 전환 지점에서 프레임 추출
    frames = extract_scene_changes(video_path, threshold=25.0, max_frames=15)
    frame_paths = save_frames(video_path, frames)
 
    # 3. 프레임 + 자막으로 종합 분석
    summary = analyze_video_with_transcript(
        frame_paths,
        transcript,
        task="""이 강의를 분석하여 다음을 작성해주세요:
 
1. 강의 주제와 목표
2. 핵심 개념별 요약 (슬라이드 기반)
3. 주요 코드 예제나 수식 (있다면)
4. 핵심 요약 (500자 이내)
5. Q&A나 토론 내용 (있다면)"""
    )
 
    return {
        "transcript": transcript,
        "frame_count": len(frame_paths),
        "summary": summary,
    }

제품 데모 분석

제품 데모 분석
python
demo_analysis_prompt = """이 제품 데모 비디오를 분석해주세요.
 
1. **제품 개요**: 어떤 제품/서비스인지
2. **핵심 기능**: 시연된 주요 기능 (시간순)
3. **UI/UX 인상**: 인터페이스 디자인 평가
4. **기술 스택 추정**: 화면에서 파악 가능한 기술
5. **경쟁 우위**: 차별화 포인트
6. **개선 제안**: 발견된 이슈나 개선점"""

CCTV/보안 영상 분석

보안 영상 모니터링
python
def analyze_security_footage(
    frame_paths: list[str],
    context: str = "사무실 입구"
) -> dict:
    """보안 영상에서 이상 상황 감지"""
    response = analyze_video_frames(
        frame_paths,
        question=f"""이 {context} 보안 카메라 영상을 분석하여:
 
1. 감지된 인원 수와 대략적인 시간대
2. 비정상적인 행동이나 이벤트
3. 출입 패턴 요약
4. 보안 관점에서의 주의사항
 
개인 식별 정보는 포함하지 마세요."""
    )
    return {"analysis": response, "frame_count": len(frame_paths)}

비디오 처리 최적화

토큰 비용 관리

비디오 분석은 다수의 이미지를 입력하므로 토큰 비용이 높아질 수 있습니다.

비용 효율적 비디오 분석
python
def optimize_frame_selection(
    video_path: str,
    budget_frames: int = 8,
) -> list[str]:
    """비용 예산에 맞는 프레임 선택"""
    # 1. 많은 프레임을 저해상도로 추출
    all_frames = extract_frames_uniform(video_path, num_frames=50)
 
    # 2. 프레임 간 유사도 계산하여 중복 제거
    unique_frames = remove_similar_frames(all_frames, similarity_threshold=0.9)
 
    # 3. 예산에 맞게 균일 샘플링
    if len(unique_frames) > budget_frames:
        indices = np.linspace(0, len(unique_frames) - 1, budget_frames, dtype=int)
        unique_frames = [unique_frames[i] for i in indices]
 
    # 4. 선택된 프레임만 고해상도로 추출
    return extract_high_res_frames(video_path, unique_frames)
Warning

비디오 분석의 주요 비용 요소는 프레임 수 x 프레임 해상도입니다. 10분 영상을 초당 1프레임으로 추출하면 600장의 이미지가 되며, 이를 모두 VLM에 전달하는 것은 비현실적입니다. 핵심 프레임 8~15장을 선별하여 분석하는 것이 실용적이며, 음성 자막을 보조 정보로 활용하면 적은 프레임으로도 높은 이해도를 달성할 수 있습니다.

정리

비디오 이해는 프레임 추출, 음성 인식, VLM 분석을 결합한 복합 파이프라인입니다. 장면 전환 감지와 균일 샘플링을 통해 핵심 프레임을 선별하고, 자막과 함께 VLM에 전달하면 비디오의 시각적-청각적 내용을 종합적으로 이해할 수 있습니다. 비용과 정확도의 균형을 위해 프레임 수, 해상도, 분석 깊이를 작업에 맞게 조절하는 것이 핵심입니다.

다음 장에서는 멀티모달 검색의 기반인 멀티모달 임베딩과 크로스모달 검색을 다룹니다. CLIP 임베딩을 활용한 텍스트-이미지 검색, 통합 벡터 스토어 설계를 배웁니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#llm#multimodal#embedding

관련 글

AI / ML

7장: 멀티모달 임베딩과 크로스모달 검색

CLIP 기반 멀티모달 임베딩의 원리, 텍스트-이미지 크로스모달 검색, 통합 벡터 스토어 설계, 그리고 실전 멀티모달 검색 시스템 구축을 다룹니다.

2026년 2월 19일·11분
AI / ML

5장: 음성 AI — STT, TTS, 실시간 음성 대화

음성 인식(STT), 음성 합성(TTS), 실시간 음성 대화 시스템의 원리와 구현을 다룹니다. Whisper, OpenAI Audio API, 음성 에이전트 설계 패턴을 배웁니다.

2026년 2월 15일·11분
AI / ML

8장: 멀티모달 RAG 시스템 설계

텍스트, 이미지, 표, 차트 등 다양한 모달리티를 통합하는 멀티모달 RAG 시스템의 설계와 구현을 다룹니다. ColPali, 비전 기반 검색, 문서 파싱 전략을 배웁니다.

2026년 2월 21일·13분
이전 글5장: 음성 AI — STT, TTS, 실시간 음성 대화
다음 글7장: 멀티모달 임베딩과 크로스모달 검색

댓글

목차

약 12분 남음
  • 비디오 이해의 접근 방식
    • 프레임 기반 접근
    • 네이티브 비디오 입력
  • 프레임 추출 전략
    • 균일 샘플링
    • 장면 전환 기반 추출
  • VLM을 활용한 비디오 분석
    • 다중 프레임 분석
    • 영상 + 자막 결합 분석
  • 활용 패턴
    • 강의 영상 요약
    • 제품 데모 분석
    • CCTV/보안 영상 분석
  • 비디오 처리 최적화
    • 토큰 비용 관리
  • 정리