Реалізація AI-інтерполяції кадрів (Frame Interpolation)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Реалізація AI-інтерполяції кадрів (Frame Interpolation)
Середній
~2-3 дні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1288
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1122
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    859

ШІ-інтерполяція кадрів відео (Frame Interpolation)

Конвертація 24fps → 60fps або 30fps → 120fps через дублювання кадрів дає рви при швидких рухах. ШІ frame interpolation синтезує проміжні кадри за допомогою optical flow — результат плавніше за будь-який механічний метод.

RIFE — практичний інструмент

RIFE (Real-Time Intermediate Flow Estimation) — найшвидший open-source метод. RTX 3080, 1080p: ~30 кадрів/секунду при 2x інтерполяції.

import torch
import numpy as np
import cv2
from pathlib import Path

# Завантаження RIFE моделі (IFNet)
from model.RIFE_HDv3 import Model

def interpolate_video_rife(
    input_path: str,
    output_path: str,
    multiplier: int = 2,    # 2x, 4x, 8x — тільки ступені двійки в RIFE
    scale: float = 1.0,     # масштаб для optical flow (0.5 зі слабким GPU)
    fp16: bool = True
) -> None:
    device = torch.device('cuda')
    model = Model()
    model.load_model('train_log', -1)
    model.eval().device(device)

    cap = cv2.VideoCapture(input_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    w   = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    h   = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    out_fps = fps * multiplier
    writer = cv2.VideoWriter(
        output_path,
        cv2.VideoWriter_fourcc(*'mp4v'),
        out_fps, (w, h)
    )

    ret, prev_frame = cap.read()
    while ret:
        ret, curr_frame = cap.read()
        if not ret:
            break

        # Перетворення в тензори
        I0 = torch.from_numpy(prev_frame).permute(2,0,1).float() / 255.0
        I1 = torch.from_numpy(curr_frame).permute(2,0,1).float() / 255.0

        if fp16:
            I0 = I0.half()
            I1 = I1.half()

        I0 = I0.unsqueeze(0).to(device)
        I1 = I1.unsqueeze(0).to(device)

        # Паддинг до кратного 32
        pad_h = (32 - h % 32) % 32
        pad_w = (32 - w % 32) % 32
        I0 = torch.nn.functional.pad(I0, [0, pad_w, 0, pad_h])
        I1 = torch.nn.functional.pad(I1, [0, pad_w, 0, pad_h])

        writer.write(prev_frame)

        # Синтезуємо (multiplier-1) проміжних кадрів
        for i in range(1, multiplier):
            t = i / multiplier
            with torch.no_grad():
                middle = model.inference(I0, I1, scale=scale)
            mid_np = (middle[0].float().cpu().permute(1,2,0).numpy()
                     * 255).astype(np.uint8)
            writer.write(mid_np[:h, :w])

        prev_frame = curr_frame

    writer.write(prev_frame)
    cap.release()
    writer.release()

EMA-VFI для складних сцен

RIFE втрачає якість на сценах з окклюзіями та нелінійними рухами. EMA-VFI (Event-based Motion-Aware VFI) — точніше, але в 3–4 рази повільніше.

Типові артефакти та рішення

Ghosting — напівпрозорий двійник об'єкту. Виникає при швидких рухах, де optical flow дає помилку. Рішення: зменшити scale або переключитися на EMA-VFI.

Warping artifacts — деформація тексту та різких границь. RIFE погано працює з текстом на екранах. Рішення: маскувати статичні регіони та не інтерполювати їх.

Миготіння при shot cuts — RIFE не детектує зміну сцени та синтезує кадр між двома різними сценами. Потрібна предобробка: детекція shot boundaries через PySceneDetect.

from scenedetect import detect, ContentDetector, AdaptiveDetector

def find_scene_cuts(video_path: str, threshold: float = 27.0) -> list[int]:
    """
    Повертає номери кадрів, де відбувається зміна сцени.
    """
    scenes = detect(video_path, ContentDetector(threshold=threshold))
    return [int(scene[0].get_frames()) for scene in scenes]
Метод Швидкість (1080p) Якість VRAM
RIFE ~30 FPS (2x) Дуже добра 6–8 GB
EMA-VFI ~8 FPS (2x) Відмінна 8–10 GB
DAIN ~2 FPS (2x) Відмінна 11 GB
Super-SloMo ~3 FPS (8x) Добра 6 GB
Завдання Час
Базова інтерполяція кадрів (2x-4x) 1–2 тижні
Production конвеєр з детекцією shot 3–4 тижні
8x інтерполяція з забезпеченням якості 6–8 тижнів