Содержание статьи +
- TL;DR
- Зачем Это Нужно Знать
- Ментальная Модель – Optical Flow Это Поле Движения Между Двумя Кадрами
- Lucas-Kanade – Классика 1981, Которая Всё Ещё Поставляется В 2026
- RAFT – Deep Learning Ресет 2020
- Speed-Accuracy Trade-Off, Численно
- Три Failure-Mode, Которые Разваливают Пайплайны Optical Flow
- Production-Паттерн – Когда Что Выбирать
- Где Здесь Фора Софт
- Ключевые Тезисы
- Что Читать Дальше
- Talk To Us / Кейсы / Скачать
TL;DR
Optical flow – это попиксельная карта того, куда в следующем кадре сместилось всё, что было в текущем; это тихий workhorse под video stabilization, frame interpolation, multi-object tracking, action recognition, content-aware encoding и почти под каждой video super-resolution моделью в 2026. Два эталонных примитива: Lucas-Kanade – алгоритм 1981 года, который оценивает sparse motion-поле на нескольких сотнях отслеживаемых corner-точек, бежит на сотнях FPS на CPU и поставляется как cv2.calcOpticalFlowPyrLK в OpenCV, – и RAFT – deep learning модель 2020 года от Princeton, оценивающая dense per-pixel flow, получившая ECCV 2020 best paper award и работающая на 9–20 FPS на современной GPU. Эта статья проводит нетехнического читателя через то, что такое optical flow, почему эти два алгоритма стоят на противоположных концах кривой скорость-точность, когда какой выбирать (плюс их современные наследники – DIS для быстрого dense flow на CPU, FlowFormer и SEA-RAFT для state-of-the-art точности), и как планировать compute-бюджет и выбирать, какой примитив реально нужен видеопродукту. В финале вы сможете спланировать фичу, зависящую от optical flow, грамотно поговорить с инженерами и обойти failure-mode, которые разваливают production-пайплайны.
Зачем Это Нужно Знать
Optical flow – это не фича, которую вы отгружаете пользователям. Это примитив – кирпич, который живёт внутри фич. Multi-object tracker, который ведёт игрока по футбольному полю, использует optical flow, чтобы предсказать, где появится каждый отслеживаемый bounding box в следующем кадре. Video stabilizer на телефоне использует optical flow, чтобы оценить дрожание камеры. Frame interpolator, превращающий 30 FPS-съёмку в 60 FPS для гладкого slow motion, использует optical flow, чтобы изобрести недостающие кадры. Блок temporal alignment внутри BasicVSR++ – open-weight дефолта для video super-resolution – буквально является обученным optical flow estimator. Ошибётесь с примитивом потока – и все downstream-фичи ломаются. Статья для продакт-менеджера, video-platform-инженера или фаундера, которому надо принять build-vs-buy-решение по видеофиче, в инженерном описании которой упоминается «optical flow» – что в 2026 значит – почти по любой.
Ментальная Модель – Optical Flow Это Поле Движения Между Двумя Кадрами
Представьте два последовательных кадра видео рядом. На первом – красная машина в левой части дороги. На втором, снятом через 1/30 секунды, та же машина сместилась на шесть пикселей вправо. Optical flow – это ответ на один вопрос, заданный для каждого пикселя: откуда этот пиксель пришёл в предыдущем кадре и куда он уйдёт в следующем? Ответ – двухмерный вектор на пиксель: горизонтальная и вертикальная скорость. Карта всех ответов, по вектору на пиксель, называется flow field – поле потока.
Flow field 1080p-видео содержит примерно 2 миллиона векторов. HD – около 920 000. SD – около 100 000. Посчитать их все, точно, тридцать раз в секунду – одна из более тяжёлых задач computer vision, и это непрерывная исследовательская тема с 1981 года.
Число яркости – то, что инженеры называют luma value, – для любой точки в кадре 2 предполагается равным яркости в какой-то точке кадра 1. Это допущение – brightness constancy constraint – фундамент каждого алгоритма optical flow. Уравнение выглядит как одна строка школьного матана: I_x · u + I_y · v + I_t = 0. Члены I_x и I_y – это насколько яркость меняется при сдвиге на пиксель вправо или вниз. Член I_t – насколько яркость меняется от кадра 1 к кадру 2 в этой точке. Неизвестные – u и v, горизонтальная и вертикальная скорости. Одно уравнение, две неизвестные – значит, для отдельного пикселя его не решить. Любой алгоритм optical flow в истории – это разный ответ на один вопрос: какое дополнительное допущение я добавлю, чтобы это стало решаемо?
Lucas-Kanade – Классика 1981, Которая Всё Ещё Поставляется В 2026
Bruce Lucas и Takeo Kanade в Carnegie Mellon опубликовали свою iterative image registration technique в 1981. Идея была элегантной: не пытайтесь решить brightness constancy для отдельного пикселя; вместо этого возьмите небольшое окно пикселей – обычно 3×3, 5×5 или 7×7 – и предположите, что у всех пикселей в окне одно и то же движение. Получается девять, двадцать пять или сорок девять уравнений в двух неизвестных – переопределённая система, которая решается least-squares. Выход – один motion-вектор на окно, а не на пиксель, поэтому Lucas-Kanade называется sparse-методом.
Соотношение яркость-позиция внутри маленького окна линеаризовано – то есть алгоритм предполагает, что яркость меняется внутри окна достаточно плавно, чтобы аппроксимироваться прямой. Это допущение проваливается на больших движениях (пиксель, сместившийся на двадцать пикселей между кадрами, не может быть смоделирован плавным локальным приближением), поэтому Lucas-Kanade поставляется в OpenCV в пирамидальной форме: изображение downsample-ится до половины, четверти, восьмой части разрешения, и алгоритм сначала отслеживает движение на самом грубом масштабе, затем уточняет на каждом более тонком. Этот трюк, изобретённый Bouguet и другими в конце 90-х, расширяет диапазон алгоритма с нескольких пикселей до сотни и более.
В OpenCV функция называется cv2.calcOpticalFlowPyrLK. Стандартный паттерн – сначала задетектить corners – точки, где у изображения сильные градиенты в двух направлениях, что и есть условие хорошо обусловленного least-squares-решения – через cv2.goodFeaturesToTrack (Shi-Tomasi corner detector, 1994). Получаете список из двух-четырёх сотен corner-точек, передаёте оба кадра и список корнеров в Lucas-Kanade – на выходе двести-четыреста motion-векторов. Весь вызов занимает около 5 миллисекунд на современном CPU при 720p – примерно 200 FPS на одном ядре, без GPU.
Выход sparse. Если камера панорамирует по сцене с двумя сотнями отслеженных корнеров, вы узнаёте движение в этих двухстах позициях. Вы не узнаёте ничего о гладкой текстурно-пустой стене позади – там нет градиентов, которые можно было бы отследить. Эта sparseness – одновременно сила модели (не претендует на то, что не может измерить) и её ограничение (фича, которой нужен flow на каждом пикселе – stabilization, frame interpolation – получит от Lucas-Kanade недостаточно).
Математика вслух для окна 5×5: вы строите матрицу A размера 25×2, где каждая строка – (I_x, I_y) для одного пикселя окна. Строите вектор b размера 25, где каждый элемент – -I_t для одного пикселя. Решаете A^T A · v = A^T b относительно v = (u, v). Матрица A^T A имеет размер 2×2; матрица A^T b – 2×1; обратная 2×2-матрица – это closed-form формула в три строки. На точку получается около 200 floating-point операций – и поэтому CPU отслеживает сотни точек на 200 FPS в реальном времени.
Failure modes известны. Lucas-Kanade проваливается на больших движениях за пределами того, что пирамида может восстановить, на motion-blurred входе, где brightness assumption ломается, на текстурно-пустых регионах, где нет градиентов, на прозрачных или зеркальных поверхностях, где brightness constancy ложна, и на сменах освещённости между кадрами. Для всего остального – а это покрывает большинство хорошо освещённого, чётко снятого видео – работает поразительно хорошо для 45-летнего алгоритма.
RAFT – Deep Learning Ресет 2020
Zachary Teed и Jia Deng в Princeton опубликовали RAFT – Recurrent All-Pairs Field Transforms – в preprint-фазе перед ECCV 2020, где модель получила best paper award. arXiv preprint – 2003.12039. Reference-имплементация – github.com/princeton-vl/RAFT. Лицензия BSD 3-Clause, commercial-friendly.
RAFT не использует brightness constancy напрямую. Вместо этого он делает три вещи. Первое: feature encoder – небольшая свёрточная сеть с шестью residual-блоками – конвертирует каждый входной кадр из сырых RGB-пикселей в 256-канальный feature map на одной восьмой исходного разрешения. Encoder shared между двумя кадрами; одна и та же сеть бежит на кадре 1 и на кадре 2. Отдельный context encoder бежит только на кадре 1 и выдаёт context-фичи, которые направляют итеративный update.
Второе: RAFT вычисляет 4D correlation volume. Для каждой фичи на 1/8 в кадре 1 (их H/8 × W/8) он вычисляет dot product с каждой фичей кадра 2 (ещё H/8 × W/8). Результат – четырёхмерный тензор формы (H/8) × (W/8) × (H/8) × (W/8), где каждая ячейка – «насколько похожа эта фича в кадре 1 на эту фичу в кадре 2». Объём затем average-pooled на нескольких масштабах (kernel-размеры 1, 2, 4, 8), давая multi-scale correlation-пирамиду, охватывающую и малые, и большие движения.
Третье: update operator – recurrent neural network на базе Gated Recurrent Unit – итеративно уточняет flow estimate. Стартует с нулевого потока везде. На каждой итерации использует текущую оценку потока, чтобы lookup-нуть корреляционные значения из 4D-volume, миксует их с context-фичами кадра 1 и выдаёт residual-апдейт потока. После 12 итераций при обучении (20 на тесте, обычно) оценка потока – финальный output.
Цифры точности на стандартных бенчмарках были скачком. На бенчмарке Sintel (синтетический dataset на базе Blender-фильмов), final pass, RAFT достиг end-point-error 2,855 пикселей – 30%-ное снижение ошибки относительно предыдущего лучшего published-результата. На KITTI (реальный driving dataset) RAFT достиг F1-all error 5,10% – 16%-ное снижение. Модель имеет около 5,3 миллиона параметров в полной конфигурации – мало по меркам 2026, много по меркам 1981.
Runtime: на одной NVIDIA 1080 Ti оригинальная имплементация обрабатывает кадр 1088×436 на 9 FPS. Меньшая версия с одной пятой параметров – 20 FPS. На современном железе – RTX 4090, A100 – эти числа удваиваются или утраиваются. Follow-up SEA-RAFT (2024, arXiv 2405.14793) – 20+ FPS на 1080p на RTX 3090. Это real-time для многих use case-ов, под-real-time для high frame-rate-нагрузок, и центральная инженерная причина, почему продуктовая команда выбирает RAFT для offline accuracy-работы и Lucas-Kanade или DIS для live-tracking.
Speed-Accuracy Trade-Off, Численно
Два алгоритма стоят на противоположных концах кривой, которая в 2026 определяет каждое практическое решение по optical flow. Цифры ниже – из оригинальной документации OpenCV по Lucas-Kanade, статьи RAFT, статьи DIS и follow-up-ов SEA-RAFT и FlowFormer.
| Алгоритм | Год | Тип | Sintel final EPE | KITTI F1-all | Скорость (1080p) | Железо | Use case |
|---|---|---|---|---|---|---|---|
| Lucas-Kanade (pyramidal) | 1981 / 1999 | Sparse, классический | Не сравним напрямую | Не сравним напрямую | 200 FPS @ 720p | CPU, одно ядро | Real-time tracking сотен точек |
| Horn-Schunck | 1981 | Dense, классический | ~8–10 px (плохо) | High | 5–10 FPS @ 720p | CPU | Учебный / baseline |
| Farnebäck | 2003 | Dense, классический | ~5–7 px | High | 30 FPS @ 720p | CPU | Лёгкий real-time dense flow |
| DIS (Kroeger 2016) | 2016 | Dense, классический | ~4 px | Moderate | 300–600 FPS @ SD | CPU, одно ядро | Real-time dense flow без GPU |
| RAFT | 2020 | Dense, deep | 2,855 px | 5,10% | 9 FPS @ 1088×436 | GPU (1080 Ti) | Offline accuracy |
| RAFT small | 2020 | Dense, deep | ~3,2 px | ~7% | 20 FPS @ 1088×436 | GPU (1080 Ti) | Near-real-time, accuracy-flexible |
| FlowFormer | 2022 | Dense, transformer | 2,183 px | ~4,8% | 4 FPS @ 1080p | GPU (A100) | State-of-the-art offline |
| SEA-RAFT | 2024 | Dense, deep (refined) | ~2,4 px | ~4,6% | 20+ FPS @ 1080p | GPU (RTX 3090) | Быстро и точно; 2026 default |
| MegaFlow / FlowIt / DPFlow | 2026 | Dense, deep | ~1,8–2,2 px | <4% | <5 FPS @ 1080p | GPU | Research-grade точность |
Несколько вещей из таблицы. Lucas-Kanade не сравним напрямую на Sintel или KITTI, потому что стандартные бенчмарки измеряют dense flow accuracy, а Lucas-Kanade не выдаёт dense выход. Dense-классики – Horn-Schunck, Farnebäck, DIS – все драматически менее точны, чем RAFT, и разрыв только увеличился с FlowFormer и 2026-наследниками. Trade – real-time CPU-скорость (DIS) против offline deep-точности (RAFT-семейство). Для большинства production видеофич в 2026 правильный ответ – либо Lucas-Kanade для sparse real-time tracking, либо SEA-RAFT для dense offline flow. У экзотических опций специфические ниши.
Три Failure-Mode, Которые Разваливают Пайплайны Optical Flow
Мы интегрировали optical flow в видеопайплайны через четыре вертикали в Фора Софт – video conferencing, surveillance, OTT и e-learning-аналитику. Три failure-mode появляются в каждой.
Failure 1: Не Та Sparsity. Команда выбирает Lucas-Kanade для фичи, которой нужен поток на каждом пикселе – скажем, video stabilization на телефоне или per-pixel frame interpolation для slow motion, – и обнаруживает в QA, что стабилизатор дёргается или slow motion полон дыр там, где corner detector ничего не нашёл. Fix – match-ить sparsity под фичу: выбирайте Lucas-Kanade только для фич, которые реально потребляют sparse-треки (multi-object tracker box prediction, KLT-style feature tracking для visual odometry, sparse AR-якоря). Всё, что dense – stabilization, interpolation, super-resolution alignment – требует dense-estimator, то есть DIS для CPU-only-fast path или RAFT / SEA-RAFT для accurate offline path.
Failure 2: Игнорирование Brightness Constancy. Команда выкатывает optical-flow-зависимую фичу в продукт видеосвязи и обнаруживает, что она драматически проваливается на тусклых indoor-звонках и в переговорках со смешанным светом. Каждый классический optical flow assume-ит, что яркость движущейся точки остаётся постоянной кадр-к-кадру; это допущение ломается под агрессивный auto-exposure, в low-light, где аналоговое усиление камеры высокое (и шумное), и под flicker от люминесцентных или LED-ламп. Fix двусторонний: сначала прогоните явный photometric normalization-этап перед optical flow (локально нормализуйте контраст на каждом кадре); во-вторых, предпочитайте deep-модели вроде RAFT или SEA-RAFT для brightness-нестабильных входов, потому что они обучены быть устойчивыми к тем видам вариаций интенсивности, с которыми классика не справится.
Failure 3: Latency Как Договороспособная Величина. PM scope-ит real-time AR-эффект – скажем, hand-tracked virtual jewelry в видеозвонке – и закладывает RAFT в пайплайн, потому что «он самый точный». Реальность: RAFT на 9 FPS в 30-FPS-пайплайне вносит 100 мс latency, которые AR-эффект не может поглотить, и виртуальное кольцо заметно отстаёт от руки пользователя. Fix – планировать latency до accuracy: sub-100ms real-time pipeline не может позволить себе 9-FPS optical flow stage. Точка. Для real-time AR используйте Lucas-Kanade для sparse anchor tracking и лёгкую MediaPipe-модель для dense body-part field, или закладывайте SEA-RAFT и принимайте его 20+ FPS как верхнюю границу пайплайна.
Production-Паттерн – Когда Что Выбирать
В нашей собственной интеграционной работе decision tree простой. Нужен поток на каждом пикселе? Если нет – нужен только в небольшом наборе feature-точек для tracking, visual odometry или sparse-якорей – используйте Lucas-Kanade. Он в OpenCV, он CPU-only, бежит на 200 FPS, и сорок пять лет production-использования значат, что failure modes задокументированы.
Если да – пайплайн real-time (видеосвязь, surveillance, AR)? Если да, выбирайте DIS для CPU-only-fast path или SEA-RAFT для accelerated path с GPU. Если пайплайн offline (архивный upscaling, post-production stabilization, content-aware encoding pre-pass), выбирайте RAFT или SEA-RAFT для точности, а FlowFormer или 2026-наследников (MegaFlow, FlowIt, DPFlow) – когда точность реально важнее runtime.
Нужно только направление движения или полная sub-pixel-точность? Для action recognition и многих tracking-by-detection пайплайнов направления хватает; DIS или Farnebäck подойдут. Для video super-resolution alignment, frame interpolation и stabilization sub-pixel-точность – это и есть смысл; выбирайте deep-модель.
Build-vs-buy для optical flow едва возникает. Все workhorse-ы поставляются как open-source под permissive-лицензиями – Lucas-Kanade в OpenCV (Apache 2.0), DIS в OpenCV-contrib (Apache 2.0), RAFT под BSD 3-Clause, FlowFormer под MIT, SEA-RAFT под BSD 3-Clause. Нет коммерческого optical flow-вендора, чей продукт настолько лучше open-source state-of-the-art, чтобы оправдать стоимость интеграции. NVIDIA Optical Flow SDK – одно исключение, о котором стоит знать – он использует выделенное optical flow-железо на Turing и более новых NVIDIA-GPU и даёт детерминированный, low-latency dense flow при очень низком compute. Для real-time-пути на NVIDIA-железе Optical Flow SDK – часто правильный ответ; для портабельного open-source-пути – RAFT / SEA-RAFT.
Где Здесь Фора Софт
В Фора Софт мы интегрировали optical flow в видеопайплайны через video conferencing, surveillance, OTT и e-learning. В видеосвязи мы используем Lucas-Kanade для sparse face-anchor tracking под real-time AR-эффектами, где latency-бюджет жёсткий, а dense flow не нужен. В surveillance используем DIS для motion-region proposals – флага частей кадра, которые сдвинулись настолько, чтобы прогнать более дорогой multi-object tracker – и RAFT для offline-forensic-анализа инцидентов. В OTT используем RAFT-grade поток внутри content-aware encoding pre-pass для archive upscaling, в паре с BasicVSR++ для самой super-resolution-стадии. Мы не ведём свои собственные optical flow-исследования; мы интегрируем open-source state-of-the-art в видеопродукты, которые отгружаются и работают.
Ключевые Тезисы
- Optical flow – это per-pixel motion field между двумя последовательными кадрами, примитив внутри tracking, stabilization, interpolation и super-resolution.
- Lucas-Kanade (1981, sparse, 200 FPS на CPU) и RAFT (2020, dense, 9–20 FPS на GPU) – две референсные точки; всё остальное где-то на кривой между ними.
- Соответствуйте sparsity потребности фичи: sparse для tracking, dense для stabilization и interpolation.
- В 2026 для real-time dense flow используйте DIS на CPU или SEA-RAFT на GPU; для offline-точности – RAFT, FlowFormer или 2026-наследников.
- Brightness constancy – допущение, на которое опирается каждый классический алгоритм, и которое первым ломается под flicker, low light или агрессивный auto-exposure.
- Закладывайте latency до accuracy: 9-FPS optical flow stage не живёт внутри 30-FPS real-time пайплайна.
Что Читать Дальше
- Multi-object tracking – DeepSORT, ByteTrack, OC-SORT – upstream-потребитель sparse optical flow для box-to-box motion prediction.
- Real-ESRGAN / BasicVSR++ для OTT archive upscaling – downstream-потребитель dense optical flow внутри propagation-блока BasicVSR++.
- Vision Transformer primer для video ИИ инженеров – архитектурное семейство, лежащее под transformer-based flow-моделями (FlowFormer, MegaFlow).
Talk To Us / Кейсы / Скачать
- Поговорить с видео-инженером – забронировать 30-минутный scoping call по optical-flow-зависимой фиче.
- Посмотреть наши кейсы – изучить WebRTC, surveillance и OTT-проекты, где мы интегрировали optical flow внутрь пайплайна.
- Скачать picker по оптическим алгоритмам – одностраничный printable-worksheet, который сопоставляет требования вашей фичи по sparsity, latency и accuracy с одним из шести production-grade алгоритмов optical flow и даёт per-frame-compute-бюджет для каждого.