[Из песочницы] Как подружить тепловизор FLIR One второго поколения с компьютером

Последнее время появилось довольно много обзоров тепловизионной приставки к смартфону Seek Thermal. Однако, Seek Thermal не единственный тепловизор доступный широким массам пользователей — всем известная компания FLIR также выпускает свою тепловизионную приставку FLIR One трёх разных поколений. В данной статье речь пойдёт о приставке второго поколения FLIR One Gen 2 для Android, имеющей разрешение болометрической матрицы 160×120 пикселей.
Купил я эту приставку на ebay три месяца назад с надеждой подключить к персональному компьютеру по USB и, надо сказать, моя надежда оправдалась.

Первое, что потребовалось сделать, так это собрать кабель с micro-USB (мама) на USB (папа). Тут проблем не возникнет.

Дальше — интереснее. На форуме eevblog.com tomas123 вскрыл протокол обмена по USB и написал для Linux своё консольное приложение для получения картинки с тепловизионной и обычной камер приставки с использованием libusb. Для Linux мне программа была не интересна, и я попробовал написать свою программу для Windows XP на базе программы tomas123. И вот тут-то и возникла проблема: libusb для Windows отказалась корректно работать, выдавая ошибку

libusb0-dll: err [submit_async] submitting request failed, win error: Параметр задан неверно.


Задав вопрос на форуме eevblog.com, я получил ответ, что я стал третьим, кто пытался безуспешно запустить эту программу для Windows с использованием libusb. Так же выяснилось, что и под Linux далеко не со всеми дистрибутивами FLIR One через libusb работает стабильно — в Ubuntu 10, например, часты ошибки «pipe error», а в Mageia 5 таких проблем не возникает. Ну что ж, пришлось отложить программу для Windows на будущее.

Следующая ОС, для которой я попытался написать программу, была QNX 6.3. Эту ОС я использую на работе, но я никогда не писал драйвер USB для неё. С помощью форума qnx.org.ru мне всё же удалось написать нечто более-менее корректно работающее по USB с FLIR One. Вот на картинке интерфейс получившейся программы:

4a6957b903574f219c3aa8ef7daabf21.PNG
Программа для QNX 6.3.

Однако программа работает нестабильно — io-usb очень часто спустя пару-тройку минут погибает в неравном бою с тепловизором. Более того, на некоторых машинах система даже не замечает подключение устройства! Оказалось, что переключив в BIOS работу портов в USB 1, система всё же оживает и начинает обнаруживать устройство и работать с ним, пусть и с пониженным FPS. Я полагаю, что, возможно, FLIR One использует не совсем стандартный USB, и это и приводит к подобным проблемам. Но главное — программа работает и картинка строится.

Дальше настало время вернуться к Windows. С помощью вот этой темы я написал драйвер для Windows XP. Вылетев раз 20 в BSOD в процессе отладки, драйвер ожил, и я получил картинку с тепловизора в программе для Windows XP. Победа! Однако, всё опять-таки, не так радужно, как казалось сначала. На некоторых компьютерах (и даже с разных USB-разъёмов одного и того же компьютера) с Windows XP драйвера просто невозможно установить — система видит FLIR One как составное USB-устройство и совершенно не желает его разделить на три устройства с окончаниями на .iAP, .FileIO и .Frame. Такая же проблема обнаружилась и в Windows 7, что также не позволило мне установить драйвер для этой ОС. Как эту проблему обойти, мне до сих пор неизвестно.

Собственно, в настоящий момент, на этом разработка программ для FLIR One у меня и остановилась.

284bd92c3a2b4dcda77db51c5b028839.PNG
Программа для Windows XP.

Итак, что же представляет этот тепловизор с точки зрения обмена с ним по USB:
Идентификатор производителя: 0×09CB.
Идентификатор устройства: 0×1996.
Тепловизор имеет три интерфейса:

  1. iAP с конечными точками: 0×00 (чтение и запись), 0×81 (чтение) и 0×02 (запись);
  2. FileIO с конечными точками: 0×00 (чтение и запись), 0×83 (чтение) и 0×04 (запись);
  3. Frame с конечными точками: 0×00 (чтение и запись), 0×85 (чтение) и 0×06 (запись).


Все эти конечные точки имеют тип bulk.

Интерфейс iAP позволяет управлять остальными двумя интерфейсами; посылая в iAP управляющую команду с нужными параметрами (они есть в приложенных файлах программ и драйверов). Чтобы получить тепловое изображение достаточно производить чтение и расшифровку данных из конечной точки 0×85 интерфейса Frame и не забывать читать данные и из конечных точек 0×81 и 0×85, иначе тепловизор может остановить передачу данных через некоторое время.

  1. Принятые данные выглядят примерно вот так:
  2. Четыре «магических» байта, отделяющие пакеты друг от друга: 0xEF,0xBE,0×00,0×00;
  3. Заголовок, в котором указаны размеры данных тепловой и обычной камеры, общий размер кадра и данных состояния устройства.
  4. Данные кадра тепловой камеры.
  5. Прочие данные.


Что же именно передаётся во всём кадре, я не изучал; мне было достаточно данных от тепловой камеры.

Принятые данные с тепловой камеры представляют собой массив 14 битных значений показаний АЦП с болометрической матрицы, начинающиеся с заголовков блоков данных для каждых 80 пикселей. Заголовок выглядит так (взято из документации на тепловизионный модуль Lepton 3, используемый в FLIR One Gen 2):

b8d335462c994eb0a211d1c8f684fd40.PNG
Заголовок блока данных в 80 байт.

Из этого заголовка нас интересует только код CRC, вычисляемый по полиному, указанному в документации.

Чтобы построить красивую картинку достаточно просто найдя максимум и минимум привести полученные показания в диапазон 0–255 (по числу цветов палитры). Собственно, на этом построение красочных картинок и заканчивается. Если же есть желание по данным показаний вычислить температуру, то тут потребуются интересные формулы с набором коэффициентов для конкретной модели тепловизора. К счастью, эти коэффициенты для FLIR One Gen 2 известны.
А формула, согласно документации «FL IR Lepton wi th Radiomet ry Qui cks tar t Guide», вот какая:

3b5e5a6044264a2c81224e762611cb6a.PNG

Мда… Хорошо, что tomas123 уже озаботился такими вычислениями и в своей программе написал функцию вычисления температуры объекта. В моей переделке она выглядит вот так:

double PlanckR1=16528.178;
double PlanckB=1427.5;
double PlanckF=1.0;
double PlanckO=-1307.0;
double PlanckR2=0.012258549;

double TempReflected=20;

double Emissivity=0.95;

//---------------------------------------------------------------------------
//вычислить температуру
//---------------------------------------------------------------------------
bool GetTemperature(unsigned short raw14,double &value)
{
 if (raw14>0x10000) return(false);
 raw14*=4;    
 double zn=(PlanckR2*(exp(PlanckB/(TempReflected+273.15))-PlanckF));
 if (fabs(zn)


Здесь TempReflected — температура болометрической матрицы, а Emissivity- коэффициент излучения измеряемой поверхности. Константы PlanckR1, PlanckB, PlanckF, Planck, и PlanckR2 специфичны для данной модели тепловизора.

Как можно заметить, моя программа для Windows сохраняет RAW-файлы. Для их анализа я также написал отдельное приложение. Выглядит оно вот так вот:

081dd1cddcfb42d1881ee963d750ac91.PNG
Анализатор RAW-файлов для Windows XP.

Собственно, на этом всё. Исходники и сами программы прилагаются по ссылкам ниже (я так и не понял, как их разместить на github).

  1. Для QNX 6.3
  2. Для Windows XP
  3. Программа для анализа RAW-изображений для Windows

© Geektimes