一塊小小的免費PCB,就能 讓手機秒變熱成像儀 !
還是賊拉 高畫質 的那種!
總開發成本也就100元左右!
這不得圍觀一下!
一、開源描述
拋開了傳統的熱成像儀制作方式,使用 可見光camera 和 熱成像傳感器 制作了一個 雙目手機熱成像儀 。像素:640x480。
目前,計畫已全開源。
——這個熱成像儀的 設計原理 是什麽? 電路 如何設計? 軟體 如何設計?使用了什麽演算法和技巧?
下面一一進行分析!
二、計畫功能實作原理
了解功能原理前須知:
熱成像儀,為什麽要設計成「雙目」的?
使用可見光影像來補償熱成像影像,就可以達到熱成像圖—— 品質高、分辨率高 的效果。
那具體的功能實作是怎樣的?下面就分析一下!
本計畫整體功能框架圖如下。
首先MCU透過I2C介面 讀取熱成像傳感器 數據,透過USB介面 傳向USB Hub 。
Camera 通用免驅USB網路攝影機,也 接到USB Hub上面 。
然後將Usb Hub和Android手機連線。
接著,Android手機的套用層就會獲取到兩個傳感器的數據。
透過一定演算法進行融合,就能得到——分辨率較高、品質較好的熱成像圖!
這是 熱水壺 熱量分布圖:
這是 白天公園 的熱量分布圖:
這是 夜間街道 的熱量分布圖:
想實作這樣的效果,軟硬體該如何設計呢?
三、硬體設計原理
原理圖
PCB圖
本章會將原理圖拆分為5部份,一一說明一下。
1.MCU
MCU使用的是STM32F411CEU6,帶USB FS,其帶浮點運算單元可對熱成像數據進行解算。
2.USB Hub
USB Hub使用的是SL2.1A,支持USB HS,可以用於傳輸網路攝影機數據。此處接了晶振,可不焊接。
Camera則透過焊接方式連線到CAM_DM/CAM_DP。
USB1是一個USB TypeC公頭,用於連線手機。
3.熱成像傳感器
熱成像傳感器使用的是MLX90640。
4.電源
電源這裏直接使用了一塊LDO進行穩壓,型號是ME6211。
這 可以 直接用低ESR的陶瓷電容 進行輸入輸出的穩壓 。
5.其他
電源燈和測試LED電路:
偵錯SWD介面:
測試點,固件使用UART2作為Debug串口:
完成了硬體部份的設計,咱們再深入剖析一下,軟體部份的核心演算法是什麽!
四、軟體設計原理
軟體部份,將重點分析——軟體設計思路、Android APP設計、數據融合演算法,這三個部份。
1.軟體設計思路
開發環境使用STM32CubeIDE。
軟體整體設計框架圖如下:
透過I2C從mlx90640讀取數據,進行打包,再使用USB發送讀取到的數據。
整個過程使用一個迴圈即可。
其中mlx90640的 溫度測量範圍是 -40到300攝氏度 。
值得註意的是:
溫度測量範圍需要保留兩位小數,轉換為整型為-4000到30000,也可以用16位元整型覆蓋,使用一個0x8000為起始碼,後續跟768個溫度數據。
mlx90640官方已經提供驅動, 只需要實作對應I2C的讀寫操作 ,即可透過API來讀取傳感器數據。
USB庫由CubeIDE自動生成 ,直接呼叫USBCDC發送數據即可。
2.Android APP
Android端主要負責——數據讀取、融合和顯示功能的實作。
這裏有兩個USB裝置:
①軟體框架
Camera和熱成像傳感器的數據讀取都有對應的庫支持。
由於兩個庫對數據的讀取都是用的異步回呼的方式,因此這裏采用雙buffer緩存的機制
就以Camera為例,解析一下數據讀取的邏輯:
初始化一個長度為2的佇列 。回呼發生時,就新申請一塊buffer,然後將YUV數據拷貝到這塊buffer中,再將這塊buffer放入佇列。
再 起一個執行緒 ,不斷從佇列中讀取數據,用於數據融合。
如果執行緒讀取太慢 ,回呼發現佇列已經滿,則從佇列中取出一塊buffer丟棄,然後再將新的buffer放入佇列。
如果回呼一直不來 ,執行緒佇列為空,則跳過下一次再讀取。因為每一次回呼都會新申請一塊buffer,因此buffer不存在並行問題。
佇列添加和刪除 存取的都是同一個數據結構,存在並行問題, 操作時需要註意上鎖 。
如上所述,Camera有兩個佇列:
只透過一個執行緒來存取兩個佇列。兩個佇列都有數據時才取出,並進行數據融合。
由此我們得出,軟體總體執行流程如下:
②Camera數據讀取和預覽
Android對網路攝影機的支持使用 UVCAndroid 。
該庫基於saki4510t/UVCCamera開發,提供了更為簡單的介面。
③熱成像數據讀取和預覽
熱成像數據透過USBCDC傳輸,在Android端看到的是一個虛擬串口。
Android開發環境中,主要使用 felHR85/UsbSerial 提供虛擬串口的操作支持,並在回呼中將熱成像數據放入佇列中。
3.數據融合
上面提到過多次「數據融合」。
那麽,要如何獲取數據,並進行融合呢?
①獲取數據
使用一個執行緒即可獲取數據。
這裏預計可見光相機的幀率會比熱成像幀率更高。
因此在等待mYUVQueue佇列有數據時才會進行數據融合。
當 mThermalQueue 沒有數據時,則預設使用上一幀的數據。
②融合演算法
這裏網路攝影機采集的是可見光的影像,分辨率是640x480;
熱成像采集的是溫度分布,分辨率是32x24。
融合演算法的目的是 ——透過參考可見光的影像, 讓熱成像采集的溫度影像 分辨率更高, 擁有更多的細節 。
該演算法基於一個假設: 顏色相近的像素,大機率來自同一個物體,對應的溫度也應該相近。
該演算法的流程如下:
將熱成像溫度的分布,透過線性插值擴大到640x480像素。
以當前像素點為中心,選定一個長寬為REF_LEN的方形區域。
計算系數矩陣,系數表示每個像素的權重。
計算估計值矩陣,表示每個像素相對於當前像素溫度的估計值,t_hat_i = k_i * t_i。
計算估計值矩陣的平均值,即當前像素的溫度估計值。
由以上演算法可知,在參考值矩陣中,與當前像素值 色度差值越小 ,對應的 系數k_i也就越大 ,對應 溫度的估計值也就越大 ,對應的估計的 溫度也就越接近 。
舉個栗子。
使用如下兩個圖片進行本地仿真。
第一張 是 camera拍的 圖片, 第二張 是 熱成像獲取的 經過插值放大後的溫度分布圖片。分辨率均為640x480。
當REF_LEN = 4時,融合結果如下:
當REF_LEN = 7時,融合結果如下:
可見, 加入融合演算法之後 ,原本插值放大的低頻資訊中, 多出了一些高頻細節 。
色彩對映
完成一個熱成像儀的最後一步,就是將融合後的影像轉為偽彩色,再按照YUV的方式對映到camera影像中。
最終效果如下:
因為色彩對映的原因,原本熱成像融合出的高頻細節被淹沒在海量的camera影像細節中,因此影像融合演算法的效果並不明顯,後續可能會分為兩種模式分別進行輸出。
參考資料:
[1]https://oshwhub.com/colourfate/binocular_thermal_imager
— 完 —
嘉立創EDA·頭條號
關註我,看一手優質開源計畫