К содержимому
MoranaLabs.
Инженерные гайды5 мин чтения1 просмотр

Калибровка камер для видеоаналитики: как перевести пиксели в метры без ошибок 

Думаете, нейросеть решит все? Разбираем, зачем нужна калибровка камер для видеоаналитики: как перевести пиксели в метры без ошибок, почему PTZ-камеры сводят трекинг с ума и как вибрация станка рушит метрики охраны труда.

0xReality

Ошибка в оценке скорости на 15 км/ч или пропущенный человек в опасной зоне цеха на дистанции 40 метров. Это реальная цена сдвига объектива на 2 градуса от порыва ветра или вибрации тяжелого пресса. Скептик скажет: «Зачем вы усложняете с геометрией, нейронка сама найдет человека, просто нарисуй прямоугольник на кадре и считай пересечения линий». Это самое опасное заблуждение в индустриальном CV. Мое мнение жесткое: калибровка камер для видеоаналитики: как перевести пиксели в метры без ошибок — это не академическая прихоть, а граница между красивой демкой для инвесторов и суровым реальным внедрением. Пока вы работаете в 2D-координатах кадра, ваши бизнес-метрики — мусор.

Шахматная доска против физики оптики

«Я купил топовую камеру с отличным стеклом, у нее нет искажений», — типичная фраза системного интегратора на промышленном объекте. К сожалению, законы физики не обмануть бюджетом. Любой, даже самый дорогой индустриальный объектив вносит дисторсию: прямые трубы на заводе выгибаются бочкой (barrel distortion), а по краям кадра пропорции объектов сплющиваются. Внутренняя калибровка (intrinsic parameters) вычисляет фокусное расстояние, оптический центр матрицы и те самые коэффициенты линзовых искажений.

Да, ходить по действующему горячему цеху или оживленному перекрестку с гигантской распечатанной на алюминии шахматной доской на длинной палке — занятие, выглядящее глупо. Рабочие курят и смеются, водители сигналят. Но это единственный рабочий математический способ отменить то, что дешевая оптика сделала со светом. Отступление: я видел команды, которые пытались калибровать дисторсию «по параллельным линиям» дорожной разметки. Заканчивалось это переписыванием пайплайнов по ночам, потому что подрядчики на трассах укладывают линии как угодно, но только не строго параллельно. Шахматная доска не врет. Внешняя калибровка (extrinsic) в свою очередь задает положение камеры относительно реального 3D-мира — высоту подвеса и углы наклона. Без этого мы просто смотрим в кривое зеркало и пытаемся угадать расстояние на глаз.

Гомография: почему фуры едут боком, а очереди считаются криво

Допустим, мы выпрямили кадр. Скептик не унимается: «Зачем доска? Давайте просто привяжем четыре точки на видео к плану цеха или спутниковому снимку, делов на пять минут». Звучит логично, пока вы не посмотрите на результаты под нагрузкой. Гомография — это математическая проекция плоского 2D-изображения на другую плоскость, в нашем случае — на плоскость земли (ground plane). И здесь начинается настоящий ад разметчиков-новичков, которые ставят опорные точки на крыши легковых машин, капоты или головы людей вместо асфальта.

Если вы привязываете геометрию не строго к уровню пола, перспектива жестоко мстит:

  • Подсчет скорости транспорта: крыша грузовика в пикселях визуально смещается быстрее, чем его колеса. Результат — генерация ложных штрафов за скорость, которой в реальности не было.
  • Контроль зон охраны труда (ОТ): 2D-полигон опасной зоны станка просто наложен поверх кадра. Рабочий безопасно стоит в пяти метрах за станком, но из-за ракурса перекрывает полигон своей головой. Система орет об инциденте, смена останавливается, заказчик бесится.
  • Плотность очередей: десять человек вблизи камеры занимают половину матрицы, а полсотни вдалеке — пару пикселей. Без проекции вида сверху (BEV — Bird's-Eye View) метрика плотности толпы превращается в генератор случайных чисел.

Отдельный жанр инженерной боли — широкоугольные объективы и PTZ-камеры. Ширики (fisheye) так сильно гнут края, что ошибка репроекции на периферии улетает в космос: человек на границе кадра кажется алгоритмам растянутым на три метра. А PTZ (Pan-Tilt-Zoom) камеры постоянно динамически меняют фокусное расстояние. Использовать PTZ для метрической видеоаналитики — это осознанно стрелять себе в ногу. При каждом зуме, при каждом повороте оператора старая матрица проекции разрушается. Если бизнес требует и патрулирования PTZ-камерой, и точного подсчета скорости — готовьтесь снимать телеметрию угла поворота по ONVIF и на лету пересчитывать фокус, молясь на отсутствие рассинхрона по времени между кадром и пакетом телеметрии.

Молчаливая деградация: когда камера уплыла

Главная подлость геометрических расчетов в том, что система не падает с ошибкой (crash), если камера физически сместилась. Узел крепления на мачте освещения ослаб на миллиметр от перепада температур, кронштейн дернуло ветром, тяжелая фура дала вибрацию на столб. Нейросеть продолжает исправно находить bounding box'ы. Pipeline инференса крутится, GPU загружены на 100%, логи сервиса абсолютно чистые. Просто с этого конкретного момента скорость автомобилей завышается на 20%, а люди магическим образом «телепортируются» за пределы безопасных пешеходных дорожек.

Метрики деградируют молча. Без встроенной автоматической рекалибровки или хотя бы жесткой детекции сдвига вы узнаете об этом через месяц, когда придут гневные отчеты от бизнеса.

У нас в MoranaLabs мы решаем эту проблему на уровне архитектуры: кадр не идет в инференс-пайплайн пространственного трекинга, пока не пройдет проверку на геометрическое смещение. Мы аппаратно извлекаем статические визуальные фичи из фона (столбы, элементы статических конструкций) и сверяем их позицию с эталонной матрицей гомографии.

import cv2
import numpy as np

def check_calibration_drift(reference_frame, current_frame, H_baseline, threshold=15.0):
    # Псевдокод извлечения ключевых точек на статичном фоне (ORB/SIFT)
    pts_ref, pts_curr = get_matched_static_features(reference_frame, current_frame)
    
    # Проецируем точки текущего кадра матрицей H_baseline
    projected = cv2.perspectiveTransform(pts_curr.reshape(-1, 1, 2), H_baseline)
    
    # Считаем p99 ошибку репроекции в пикселях
    errors = np.linalg.norm(pts_ref - projected.reshape(-1, 2), axis=1)
    p99_error = np.percentile(errors, 99)
    
    if p99_error > threshold:
        # Сдвиг критический, пространственным метрикам доверять нельзя
        return True 
    return False

Если функция вернула True — камера уплыла. Обработка прерывается, система немедленно алеартит техническую поддержку, а данные в базе помечаются флагом недостоверности. На краевых устройствах (edge) лучше вовремя обрубить поток и не выдать метрику вообще, чем накормить бизнес-дашборды галлюцинациями сдвинутого объектива.

  • #computer vision
  • #edge computing
  • #opencv
  • #видеоаналитика
  • #калибровка камер
ПоделитьсяTelegramX
рассылка

Новые статьи — на почту

Лонгриды про ML в проде, edge и компьютерное зрение — сразу после выхода.

Канал в Telegram: morana.log

Без спама. Нажимая «Подписаться», соглашаетесь с обработкой персональных данных

бесплатный pdf-гайд

Edge AI или облако: когда тащить нейросеть на железо

Признаки, фреймворк выбора и прикидка экономии — короткий PDF-гайд на почту.

PDF · 5 страниц · без спама. Нажимая «Получить», соглашаетесь с обработкой персональных данных

Читать дальше
— заявка

Опишите задачу  ответим как инженеры. 

Оставьте имя и Telegram — остальное обсудим. Без брифов на 40 слайдов и звонков по три раза.

Отвечаем за пару часовотвечает инженер, а не отдел продажNDA по запросу

Сюда напишем — это быстрее всего

Или сразу написать в Telegram

Без спама и звонков-роботов. Нажимая кнопку, вы соглашаетесь с политикой конфиденциальности и обработкой персональных данных.