
Пояснение переводчика: в статье речь пойдет об изготовлении устройства, которое позволяет делать снимки объекта в различных участках спектра электромагнитных волн.В данном случае автор приводит пример самостоятельного изготовления подобного непростого устройства.
Цитата из Википедии: спектрозональная съёмка производится для получения изображений деталей объекта, неразличимых в видимом свете.
В статье много фото.
Я уже давно планировал собрать эту систему, и как только у меня появилось свободное время, направился в наш местный хакспейс (TAMI), где этим и занялся. Состоит оно в итоге из нескольких сотен светодиодов, посаженных на одну шину I2C, и темного ящика, который на 1/3 изнутри обклеен алюминиевой фольгой (альтернатива – пенополистирол) для максимально равномерного рассеивания света, а на 2/3 черным картоном для минимизации отражения лучей. Все светодиоды я объединил группами по 4 штуки, чтобы добиться большей яркости.
Начался весь проект с покупки светодиодов, которые обошлись мне около $0.5 каждый.

Затем я красиво разместил их все на алюминиевом листе, который также выступил в роли теплоотвода.

Каждая группа из 4-х светодиодов подключена к МОП-транзистору и мультиплексору (pca9685). Я подумываю заменить этот pca9685 на pca9635 (1кГц против 97кГц) и добавить фототранзистор для настройки ШИМ светодиодов с обратной связью. Также можно проверить время нарастания и спада свечения каждой группы. В качестве источника постоянного тока я задействовал драйвер LDD-700H, а в качестве контроллера Raspberry Pi (код будет приведен далее).

Тестирование светодиодов перед установкой:
Дополнительное тестирование (белый лист А4 и эталон отражения):
Все цвета я проанализировал спектрометром: получилось от ~370нм до ~880нм, а цветовая температура белого 2.7К, 6К, 10К:

Пардон за косячное фото экрана – получил бракованный дисплей для планшета x61t
Далее нужно просверлить большое отверстие в центре алюминиевой пластины под монохроматическую камеру.
Памятка себе: найти фотодиод FDS010?). Для получения реальных значений ШИМ и яркости света фотодиод/фототранзистор должен соответствовать спектру светодиодов. Нашел подходящий в ящике инструментов (FDS10X10?, S2387-1010R?, 340нм-110нм ?).

Думаю, пока этого будет достаточно. Похоже, что стандартным решением для преобразования тока фотодиода в напряжение является LTC1050.
Съемка экрана планшета (лист авокадо) на телефон. Изображение получено с монохроматической камеры, еще не откалиброванной и не синхронизированной со светодиодами.
Апдейт по сборке: добавил сенсорный дисплей – нужно еще исправить драйвер eGalax (
apt install xserver-xorg-input-evdev
, отредактировать /etc/X11/xorg.conf, заменить libinput на evdev, apt install xinput-calibrator
, поменять местами оси x-y дисплея).
Все запитано от одного БП (драйвер светодиодов 15В, дисплей 12В, Pi 5В).

Просверлил отверстие

Притащил из TAMI несколько кусков анодированного алюминия, из которых собрал настраиваемый кронштейн для камеры.

Дополнительные фото
Апдейт: важно, чтобы в объектив попадал только отраженный от тестируемого объекта свет, поэтому я измерил отверстие и подобрал подходящую ПВХ-трубу, которая вошла в него достаточно плотно. Обрезал я ее коротковато – по факту оказалось, что лучше ее сделать длиннее.



Похоже, что мне удалось добиться улучшения, несмотря на слишком короткую трубу (думаю, желательна длина от 10см). В качестве временного решения я ее наращу с помощью черного картона и оберну внешнюю сторону фольгой.


Ниже очередное видео, теперь с листом винограда. Яркость светодиодов еще не откалибрована, и некоторые диапазоны лист поглощает. Плюс не помогло практически полное закрытие затвора объектива. Попробую снять другое видео завтра.
Изображение получилось «в кружке» из-за того, что я излишне нарастил трубу (20см), в результате чего угол обзора захватывает ее край. В дальнейшем я планирую сделать трубу уже с настраиваемой длинной под разные объективы.


Еще одно видео. Здесь потеряна пара кадров из-за недостатка питания для Pi. На этот раз снимал лист картофеля с обработкой изображения при помощи OpenCV (функция CLAHE).
Находясь в ожидании заказанного апгрейда в виде Nvidia Jetson, решил поработать над косметикой.

И вот мой «презент» готов к ведению многозональной съемки.Дополнительные фото
Как и обещал, привожу:
Кодfrom __future__ import division import time import Adafruit_PCA9685 import cv2 from pyueye import ueye import ctypes import datetime pwm = Adafruit_PCA9685.PCA9685(address = 0x40) #1st pwm1 = Adafruit_PCA9685.PCA9685(address = 0x41) #2nd pwm2 = Adafruit_PCA9685.PCA9685(address = 0x42) #3rd pwm.set_pwm_freq(1000) pwm1.set_pwm_freq(1000) pwm2.set_pwm_freq(1000) spec = "avo_leaf" #name of speciment led = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31] lux = [1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931] #temporary initial value 0, 4095 for x,y in zip(led, lux): if (x < 16): pwm.set_pwm(x,y,0) #led on 1st mux elif ( x>14 and x<32): pwm1.set_pwm(x-16,y,0) #led on 2nd mux elif (x>31 and x<33): pwm2.set_pwm(x-32,y,0) #led on 3rd mux else: print(x) hcam = ueye.HIDS(1) pccmem = ueye.c_mem_p() memID = ueye.c_int() hWnd = ctypes.c_voidp() ueye.is_InitCamera(hcam, hWnd) sensorinfo = ueye.SENSORINFO() ueye.is_GetSensorInfo(hcam, sensorinfo) ueye.is_AllocImageMem(hcam, sensorinfo.nMaxWidth, sensorinfo.nMaxHeight,24, pccmem, memID) ueye.is_SetImageMem(hcam, pccmem, memID) nret = ueye.is_FreezeVideo(hcam, ueye.IS_WAIT) if (nret == 0): print("camera") else: print("____problem!!!____") FileParams = ueye.IMAGE_FILE_PARAMS() FileParams.pwchFileName = spec + "_led_"+str(x+1)+"_cam_"+ datetime.datetime.now().strftime("%s") + ".bmp" FileParams.nFileType = ueye.IS_IMG_BMP FileParams.ppcImageMem = None FileParams.pnImageID = None nret = ueye.is_ImageFile(hcam, ueye.IS_IMAGE_FILE_CMD_SAVE, FileParams, ueye.sizeof(FileParams)) if (nret == 0): print("camera") else: print("____problem!!!____") ueye.is_FreeImageMem(hcam, pccmem, memID) ueye.is_ExitCamera(hcam) if (x < 16): pwm.set_pwm(x,0,0) #led off 1st mux elif ( x>14 and x<32): pwm1.set_pwm(x-16,0,0) #led off 2nd mux elif (x>31 and x<33): pwm2.set_pwm(x-32,0,0) #led off 3rd mux else: print(x)
Заключение
В целом получился занятный проект, и я планирую довести его до ревизии 2.0. В частности:
- заменить Raspberry Pi (~35$) на Nvidia Jetson Nano (~99$);
- возможно, использовать машинное обучение для улучшения контраста;
- пересобрать нижнюю часть для лучшего поглощения света;
- достать несколько многоцветных лазеров;
- использовать оптоволокно для подсветки в углах;
- сделать установку портативной (уменьшить, реализовать возможность складывания и добавить аккумулятор).
В качестве дополнения рекомендую ознакомиться с реализацией продвинутого аналога подобной системы специалистами NASA. Вот их небольшое видео:
Конкурс статей от RUVDS.COM. Три денежные номинации. Главный приз — 100 000 рублей.
