Kinect: избавляемся от искажений при помощи потолка

16 Nov 2014

Идеально плоский потолок

Давеча я писал про то, как выглядят данные, которые приходят с сенсора. Такое поведение сенсора просто возмутительно и долго это продолжаться не может.

Ок. А что нам потребуется? Нам потребуется потолок. Я внимательно его осмотрел и убедился, что в реальности он плоский. А вот на восстановленом изображении - нифига.

Для начала нам нужно сохранить дамп глубин “идеального” потолка. Можно и стену если у вас есть достаточно плоской поверхности. :)

В файл будет сохранена двумерная матрица из чисел разделенных пробелами. Строки по строкам и т.д. Позже поймем зачем именно так.

Кусочек файла

888 889 890 890 890 890 890 891 890 891 891 892 892 892 892 892 892 892 892 892 891 893 892 892 892 892 892 ... 2047 2047 2047 2047 2047 2047 ...

Теперь посмотрим на картинку этой самой плоскости. Для этого запускаем maxima.

(%i1) load(numericalio);  
(%i2) m: read_matrix("<путь к файлу с глубинами>");  
($i3) f(x, y) := float('m [round(x), round(y)]);  
-- тут мы зададим функцию извлечения нужного значения из матрицы.  
-- Так как матрица наши данные дискретны  
-- и существуют только в определенных точках  
(%i4) plot3d (f(x, y), [x, 1, 640], [y, 1, 480]);

О! Круто. Мы что-то видим.

Потолок. Необработанная карта глубин

Что-то не то :)

Стоит заметить, что в режиме сырых данных FREENECT_DEPTH_11BIT самые правые 8 столбцов не используются и всегда возвращают значение FREENECT_DEPTH_RAW_MAX_VALUE. Об этом не стоит забывать при последующих действиях.

Поэтому нам нужно посмотреть плоскость без правых столбцов (8 штук).

(%i4) plot3d (f(x, y), [x, 1, 632], [y, 1, 480]);

И тут уже то, что нам надо.

Потолок: карта глубин после доработкиЭто плоскость. Но не очень плоская. И таки да. Надо сделать ее обратно плоской. :)

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

Поэтому можно ввести коэффициент нормировки для каждой из точек (x, y). Который будет равен отношению реального расстояния к полученному.

Зная этот коэффициент можно узнать, реальное расстояние до точки. Просто умножив полученное от кинекта значение на коэффициент нормировки в данной точке (x, y).

Коэффициенты считаем один раз по калибровочному изображению. А затем загружаем в свое приложение и пользуемся.

Минусы решения

UPD

Код на гитхабе

Теги: обработка изображений

Категории: JFF kinect