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

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Реализация AI-интерполяции кадров (Frame Interpolation)
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

AI-интерполяция кадров видео (Frame Interpolation)

Конвертация 24fps → 60fps или 30fps → 120fps через дублирование кадров даёт рывки на быстрых движениях. AI 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)

        # Padding до кратного 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]:
    """
    Возвращает номера кадров, где происходит смена сцены.
    threshold=27: стандартный для ContentDetector.
    """
    scene_list = detect(
        video_path,
        ContentDetector(threshold=threshold)
    )
    cut_frames = []
    for scene in scene_list:
        cut_frames.append(scene[0].get_frames())
    return cut_frames

Сравнение методов

Метод Скорость 1080p 2x SSIM Артефакты Применение
Дублирование кадров Мгновенно Рывки Не использовать
DAIN ~5fps 0.942 Средние Архивное видео
RIFE v4.6 ~30fps 0.961 Ghosting на быстрых 24→48fps
EMA-VFI ~8fps 0.971 Минимальные Киновидео
Film (Google) ~3fps 0.978 Минимальные Максимум качества

Сроки

Задача Срок
API-сервис frame interpolation (RIFE) 1–2 недели
Pipeline с детекцией shot cuts + интерполяция 2–4 недели
Fine-tuning под специфический тип видео 6–10 недель