Дата публикации: Dec 19, 2013 10:18:26 PM
Согласитесь, наверное каждому хотелось хоть раз побаловаться тепловизором. Посмотреть с помощью него на окружающий мир, и осознать как много вокруг самых разнообразных источников тепла. Начиная от ноутбука, и заканчивая всякой живностью, типа людей и тараканов. Кстати, разные части тела генерируют разное количество тепла, тоже интересное исследование. Найдутся и те, кто хотел бы применить сей прибор для более практичных вещей. Например, выявить утечки тепла в частном доме.
Лично я, захотел во владение такой удивительный прибор еще много-много лет назад. Сразу после того, как насмотрелся американских фильмов, в которых этот прибор частенько светился (Хищник, к примеру). Совсем недавно, появились и вполне конкретные задачи из области робототехники, для которых тепловизор стал просто необходим.
Все тепловизоры принято делить на два класса: охлаждаемые и неохлаждаемые. Первые, как правило, имеют стационарное исполнение, и используют для охлаждения жидкий азот. Такие тепловизоры применяются в промышленности. О цене подобных устройств я даже не интересовался.
Вторые имеют компактную переносную конструкцию, и не нуждаются в низких температурах. В качестве сенсоров в переносных тепловизорах примеряются матрицы микроболометров. Такой прибор с матрицей 100x80 точек, в Китае стоит от 50-60 тыс.руб. Спрашивается, почему так дорого??
А дорого потому, что основой такого тепловизора служит как раз та самая матрица микроболометров, совмещенная с кремниевой/германиевой оптикой. Её стоимость составляет до 90% стоимости самого прибора.
Отсюда возникает естественный вывод. Сделать дешевый прибор своими руками не получится, ведь один черт, придется покупать эту матрицу. Изготовить же её самому - задача весьма непростая, и требующая наличия специализированной лаборатории.
Именно поэтому, для себя я решил начать с небольшой матрицы. Применив механизм сканирования, даже с помощью небольшой разрешающей способности сенсора можно получиться большую и подробную картинку. Чем, собственно, я и планирую заняться сразу после опытов с самим сенсором.
Покопав интернет, я нашел три доступных сенсора, которые народ активно использует в своих проектах.
1. Devantech TPA81 8x1 Thermopile
Как понятно из названия, сенсор имеет всего одну линейку из 8 элементов. Стоимость - около $100.
2. Panasonic Grid-EYE
Очень интересный прибор с разрешением 8x8. Стоит около $40.
3. Melexis MLX90620
Тоже доступный сенсор, с самой большой матрицей 16х4. Цена $86.
Понятное дело, я очень захотел купить Grid-EYE. Даже заказал его на Digikey.com. Представляете, каково же было мое разочарование, когда мне отказали в продаже:( Аргументировали это тем, что товар имеет двойное назначение. При этом, легко подали MLX90620 ! ( можно подумать, с помощью второго сенсора я не смогу подбивать их танки, хехехе).
Ну да ладно. Затратив в два раза больше денег, чем планировалось, я все таки получил тепловизионную матрицу. Осталось её подключить.
Сенсор MLX90620 имеет I2C интерфейс, так что к контроллеру нужно подключить только две линии: SDA и SCL. Согласно даташиту, питать прибор лучше всего напряжением 2.6 В (хотя и от 3.3 В не сгорит). Для эксперимента, я поделил напряжение простым потенциометром (делителем напряжения, то бишь).
На этот раз, под рукой у меня была Arduino Uno R3. Именно к ней я и решил подцепить MLX90620. Схема ниже:
Я не первый, кто подключил MLX90620 к Arduino. Покопавшись в "интернетах" я нашел весьма сносный скетч, который получает вектор абсолютных температур с датчика:
https://github.com/nseidle/MLX90620_Example
Чтобы скетч работал правильно, и выдавал адекватные значения температуры, необходимо определить вектор калибровочных констант alpha_ij. Сделать это можно с помощью дополнительной программы MLX90620_alphaCalculator, которая лежит там же. Просто запускаем её, и в мониторе COM порта получаем готовый вектор. Затем, вставляем его в основную программу MLX90620_Example.ino.
Кстати, для работы скетча потребуется библиотека I2CMaster. Взять ее можно тут: http://bildr.org/2011/02/mlx90614-arduino/. Или тут: http://www.cheap-thermocam.bplaced.net/software/I2Cmaster.rar
Результатом работы скетча будет просто-напросто вектор абсолютных температур, которые он бросает в COM-порт. Не очень-то наглядный результат, согласитесь. Просто набор чисел...
В тех же "интернетах" можно увидеть много красивых картинок, на которых информация о температуре накладывается на изображение с видеокамеры в виде разноцветных квадратиков. Цвет каждого квадратика, отвечает за показания конкретного элемента тепловизионной матрицы.
Для пущей наглядности, я решил сделать именно такой вариант. Учитывая, что последним пакетом, который я использовал для обработки изображений, был OpenCV, программную реализацию тепловизора было решено сделать именно с помощью него. Концепция получившегося решения выглядит так:
1) Arduino Uno собирает показания с датчика MLC90620, и отправляет их на компьютер через последовательный порт.
2) Программа на компьютере принимает данные из COM-порта, и рисует матрицу полупрозрачных цветных квадратиков, накладывая их на исходное изображение с веб-камеры.
Для отправки вектора температур с Arduino я использовал свой примитивный протокол SerialFlow. Для этих целей, пришлось немного доработать вышеуказанный скетч, добавив в него процедуру отправки упакованных данных в последовательный порт.
Что касается программы, запускаемой на рабочей станции, то здесь я решил использовать язык python и cv2 вариацию библиотеки OpenCV. Непосредственно процедура формирования изображения, выглядит следующим образом:
Формирование изображения
def poll( self, img ):
colors = list( get_all_from_queue( self.data_q ))
if not colors:
return
colors = colors[-1]
overlay = img.copy()
for col in range(16):
for row in range(4):
color = getTempColor( colors[col*4+row] )
cv2.rectangle( overlay,
(WIDTH - (RECT_LEFT+col*RECT_W), RECT_TOP+row*RECT_H),
(WIDTH - (RECT_LEFT+col*RECT_W+RECT_W), RECT_TOP+row*RECT_H+RECT_H),
color, -1)
opacity = 0.6
cv2.addWeighted( overlay, opacity, img, 1 - opacity, 0, img )
if FLIP:
img = cv2.flip( img, 0 )
if SHOW_MAIN:
cv2.imshow('result', img)
Функция getTempColor - возвращает RGB цвет, в зависимости от значения температуры. Я остановился на смеси двух цветов - синего и красного. rectangle - понятно, рисует залитые прямоугольники. addWeighted - наклеивает квадратики на исходное изображение с заданной прозрачностью.
Код проекта для обоих платформ можно найти в репозитории: https://olegevsegneev@bitbucket.org/olegevsegneev/robot-dev.git
Для эксперимента я решил посмотреть через тепловизор на очень холодный и очень горячий объекты. Роль первого отлично сыграла замороженная цветная капуста. Очень горячим объектом стал стакан с кипятком. Ход эксперимента, как всегда, был снят на мой телефон с печальным качеством видео.
В общем, результат работы прибора меня полностью удовлетворил. Можно легко найти на картинке живое существо, очаг огня или мистера Фриза. На следующих этапах я планирую:
1) Изготовить для сенсора плату, дабы убрать паразитные наводки от макетки и висячих проводков.
2) Сделать сканирующую платформу, и написать/найти для неё соответствующий софт.
Все замечания и комментарии, как и прежде, можно отправлять мне на почту, или в любую соцсеть.