Handy: работа с камерой
Калибровка камеры в рамках летней практики Дениса Бакина.
Первые шаги
В рамках летней практики мне удалось поработать над очень интересным проектом Handy — манипулятором, который сможет играть в настольный теннис. Я занимался настройкой камеры и разрабатывал программный модуль для ее калибровки.
Уверен, многие, как и я, видели применение роботизированных манипуляторов на производстве. Меня часто удивляло и вдохновляло, как точно и быстро они могут выполнять задачи и даже играть!
Поскольку цель проекта — именно игра в настольный теннис, то актуальна проблема локализации теннисного шарика. Задачу предполагается решать с помощью изображений с массива камер, которые будут расставлены вокруг стола. Если мы видим шарик с нескольких точек, то можем весьма точно триангулировать его в пространстве.
Система должна работать в реальном времени, поэтому нужно научиться получать кадры с высокой частотой. Первые успехи были достигнуты быстро: наша промышленная камера с Алиэкспресс передавала отличное изображение, но замер показал FPS на уровне 15-20 кадров, чего оказалось недостаточно. За то время, пока сенсор получал свет, шарик успевал пролететь достаточное расстояние, чтобы его силуэт оказался смазан.
После изменения экспозиции (времени, в течение которого сенсор улавливает свет для одного кадра) и других параметров камеры удалось получить весьма четкое и яркое изображение при 100 кадрах в секунду, однако картинка сильно потускнела.
На кадре выше видно, что даже быстро летящий шарик четко виден на изображении — все из-за низкой экспозиции, которая позволяет снимать объекты в движении без размытия.
Система должна работать в реальном времени, а это значит, что на все вычисления отведено весьма ограниченное время. Поэтому одной из задач было свести вычисления к минимуму. Так появилась идея отказаться от RGB формата в пользу сырых данных от сенсора. Для этого мне пришлось разобраться, как свет от сцены становится цифровым изображением.
Вообще сенсор камеры состоит из светочувствительных элементов — фотодиодов. Для каждого снимка происходит замер, сколько света попало на каждый фотодиод за время экспозиции. Как же мы получаем цветное изображение, если сенсор улавливает просто свет? Дело в том, что каждый фотодиод накрыт светофильтром, который пропускает только определенный цвет. Так работают мозаичные фильтры, среди которых самым распространенным является фильтр Байера.
Таким образом, изначально для каждого кадра мы знаем, сколько и какой фотодиод уловил света, а также расположение светофильтров на сенсоре.
На иллюстрации выше можно заметить, что оранжевый шарик под фильтром Байера соответствует “сетке” из светлых пикселей — красных фотодиодов. Зеленый шарик, наоборот, не так выделяется, так как зеленые пиксели расположены более равномерно.
Чтобы не использовать производительность и время зря, было решено не конвертировать фильтр Байера в RGB изображение. На данный момент планируется проверить точность модели детектора для такого подхода и после этого принять окончательное решение.
Если же требуется именно RGB изображение, то применяется дебайеризация — более сложный алгоритм, чем линейная интерполяция, который часто не раскрывается производителями цифровых фотокамер. Стандартная же версия такого алгоритма заключается в разделении фотодиодов по цветам и распределении этих данных по трем каналам RGB изображения.
Калибровать или не калибровать?
Как только техническая часть с камерой была закончена и отлажена, настала пора сделать следующий шаг и заняться не получением изображений, а их использованием, вернее, подготовкой к этому. Перед локализацией шарика необходимо провести калибровку камеры, то есть определение ее внутренних параметров.
Зачем же это нужно? Калибровка необходима, чтобы при дальнейшей обработке кадров с камеры была возможность убрать дисторсию, которая неизменно возникает у любой оптики. Дисторсия – это погрешность, которая выражается в нарушении подобия между сценой и кадром из-за изменения масштаба по мере удаления от центра линзы. Так, например, правильный прямоугольник в реальности будет соответствовать криволинейной фигуре на изображении.
Причина дисторсии заключается в более сильном отклонении лучей краями линзы, причем чем дальше от центра линзы пройдет луч, тем сильнее он будет подвержен отклонению. Очевидно, что эти искажения не позволят точно рассчитать положение шарика, а поскольку в перспективе камер для проекта потребуется изрядное количество, то было решено максимально автоматизировать этот процесс.
Чтобы убрать дисторсию, достаточно знать соответствие между пикселями на “искаженном” изображении и на “исправленном” результате, которое может быть выражено через коэффициенты дисторсии. За расчет остальных параметров отвечает особая матрица, в которой записаны рассчитанные координаты оптического центра и фокусного расстояния.
В ходе работы над этим модулем была выявлена проблема: часто пользователь может упускать покрытие части кадра или, наоборот, показывать паттерн слишком много и часто. Все это потенциально может привести к ухудшению качества калибровки. Для исправления этого недостатка была введена метрика: отношение пересечения к объединению. Когда положение доски весьма приближено к тому, которое уже было показано ранее, эта метрика дает достаточно большой результат, чтобы наш модуль не сохранял текущий кадр. Это позволило больше не беспокоиться о равномерности покрытия кадра: модуль сможет сам исключить избыточные кадры и подсветить пропущенные области изображения.
На данный момент весь ключевой функционал реализован, модуль находится в стадии отладки и тестирования. Теперь в проекте Handy можно с высокой частотой получать кадры с камеры, а также в автоматическом режиме калибровать ее и использовать полученные параметры в дальнейшем.
На этом моя летняя практика подошла к концу, да и само лето кончилось. К счастью, для меня это означает начало нового учебного год и на ПМИ, и в группе робототехники.
Проект Handy перспективен и амбициозен! В ближайшем будущем планируется измерить точность и производительность детектора положения шарика на одном кадре, усовершенствовать и, возможно, расширить функциональность модуля калибровки. Все это позволит перейти к уже непосредственной триангуляции теннисного шарика, где нас встретят очередные преодолимые трудности, а это значит, что впереди еще много нового и не менее интересного.
Как же найти все эти закономерности между исходным и исправленным изображениями? На приведенных иллюстрациях искажения визуально заметны, потому что мы ориентируемся на ровные линии шахматной доски (или любого другого ровного объекта). Примерно по такому принципу можно найти внутренние параметры камеры программно: достаточно сделать множество снимков, где присутствует паттерн (для простоты мы выбрали шахматную доску), определить его расположение его опорных точек и решить систему уравнений, которая и позволит установить искомое соответствие.
В итоге мне удалось написать модуль, который считывает поток изображения с камеры, локализует на каждом кадре шахматную доску, запоминает ее положение и показывает его пользователю зеленым цветом. Это позволяет с легкостью определить, в какой части кадра стоит показать паттерн дополнительно. После того как вся область видимости камеры окажется покрыта зелеными отметками, можно приступать к калибровке: модуль автоматически просчитает искомые параметры камеры и сохранит их в файл, а также проинформирует пользователя о точности и статусе калибровки.