這個(gè)項(xiàng)目能夠?yàn)橄绬T提供紅外視覺(jué)感,以幫助他們從燃燒的建筑物中營(yíng)救人員。
背景
熱像儀 (TIC) 已被證明是消防員的寶貴工具。它們使消防員能夠更快地找到受害者,更一致地成功駛出燃燒的房屋,并減少令人滿意地完成搜索所需的時(shí)間。然而,一些問(wèn)題仍然存在。尋找受害者時(shí),需要花費(fèi)時(shí)間拉出 TIC,進(jìn)行設(shè)置并讀取顯示。手持 TIC 顯示器在濃煙中難以準(zhǔn)確看到,導(dǎo)致受害者定位較慢。使用顯示器需要操作員將他們的眼睛和注意力從周圍的環(huán)境中移開(kāi),從而導(dǎo)致意識(shí)喪失并增加隧道視力的風(fēng)險(xiǎn)。
利用機(jī)器學(xué)習(xí)為消防員提供紅外線 (IR) 感覺(jué)的感官替代設(shè)備將是一個(gè)有用的工具。這將減少消防員在顯示器上將視線從周圍環(huán)境中移開(kāi)的次數(shù)(也降低了隧道視力的風(fēng)險(xiǎn)),因?yàn)樗麄儗⒉辉儆X(jué)得需要不斷地監(jiān)控 TIC 顯示器,因?yàn)樗麄儗⒉粩嗟孬@得重要的 IR 信息。當(dāng)感覺(jué)到適當(dāng)?shù)拇碳r(shí),他們將能夠更快地做出反應(yīng),而不是不得不參考顯示器,從而減少受害者的救援時(shí)間。直接將關(guān)鍵信息流式傳輸給消防員將減少顯示器在濃煙中的低能見(jiàn)度成為問(wèn)題的情況。總體而言,具有 IR 意識(shí)的消防員在搜救行動(dòng)中會(huì)更有效。
如何設(shè)置項(xiàng)目
我們將 Qwiic 電纜(面包板跳線(4 針))連接到 MLX90640 SparkFun IR Array Breakout (MLX)。四根線(黑、紅、黃、藍(lán))分別代表GND、VIN(3.3V)、SCL、SDA。

因?yàn)槲覀兊?Qwiic 電纜不是母跳線,所以我們使用四根 ff 面包板線將 Qwiic 電纜引腳連接到 Raspberry Pi (Pi)。在下圖中,可以看到黑色、紅色、黃色和藍(lán)色 Qwiic 引腳分別連接到棕色、紅色、黃色和橙色 ff 面包板線。

ff 面包板線的顏色并不重要,但關(guān)鍵是 Qwiic 電纜 GND、VIN、SCL 和 SDA 引腳連接到適當(dāng)?shù)?Pi 引腳(分別為引腳 6、1、5 和 3)。下面可以看到 Pi 引腳分配指南以及我們與 Pi 的連接。

完成后,我們創(chuàng)建了一個(gè)小紙板相機(jī)支架,通過(guò)切掉披薩盒的一側(cè)來(lái)幫助支撐相機(jī)。此步驟不是必需的,因此請(qǐng)隨意跳過(guò)它或自己制作。

實(shí)施概述
將相機(jī)連接到樹(shù)莓派
使用 Adafruit 庫(kù),我們能夠從 MLX90640 熱像儀中讀取數(shù)據(jù)。
import adafruit_mlx90640
import time,board,busio
i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000) # setup I2C
mlx = adafruit_mlx90640.MLX90640(i2c) # begin MLX90640 with I2C comm
mlx.refresh_rate = adafruit_mlx90640.RefreshRate.REFRESH_2_HZ # set refresh rate
frame = [0]*768 # setup array for storing all 768 temperatures
mlx.getFrame(frame)
此時(shí),我們將溫度數(shù)據(jù)存儲(chǔ)在一個(gè)數(shù)組中,準(zhǔn)備好進(jìn)行預(yù)處理。
預(yù)處理原始溫度數(shù)據(jù)并提供給分類服務(wù)
我們的預(yù)處理步驟需要將溫度數(shù)據(jù)轉(zhuǎn)換為稍后可以輸入到我們的邊緣脈沖模型中的圖像。這是使用Matplotlib 庫(kù)完成的,然后將圖像保存到 Buffer Stream 并編碼為 base64 字符串。
mlx.getFrame(frame)
mlx_shape = (24,32)
fig = plt.figure(frameon=False)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
thermal_image = ax.imshow(np.zeros(mlx_shape), aspect='auto')
MIN= 18.67
MAX= 43.68
data_array = (np.reshape(frame,mlx_shape)) # reshape to 24x32
thermal_image.set_data(np.fliplr(data_array)) # flip left to right
thermal_image.set_clim(vmin=MIN,vmax=MAX) # set bounds
buf = io.BytesIO()
fig.savefig(buf,format='jpg',facecolor='#FCFCFC',bbox_inches='tight')
img_b64 = base64.b64encode(buf.getvalue()).decode()
buf.close()
plt.close(fig)
使用 http post 請(qǐng)求將 base64 字符串和原始幀數(shù)據(jù)發(fā)送到我們的分類微服務(wù)。微服務(wù)將通過(guò) Edge Impulse 模型運(yùn)行圖像,并經(jīng)過(guò)一些后處理(如下所述)返回一個(gè)標(biāo)志,說(shuō)明是否在幀中檢測(cè)到一個(gè)人,如果是,那么他們是什么方向,即左、中、右。
分類服務(wù)
分類服務(wù)接受一個(gè) post 請(qǐng)求,請(qǐng)求中包含兩個(gè)數(shù)據(jù)對(duì)象:原始數(shù)據(jù)數(shù)組和以 base64 表示的圖像。圖像在被傳遞到分類器之前需要進(jìn)行預(yù)處理。首先,我們必須提取圖像的原始特征。圖像被解碼為圖像緩沖區(qū),然后將其轉(zhuǎn)換為圖像的十六進(jìn)制表示。這個(gè)十六進(jìn)制字符串被分割成單獨(dú)的 RGB 值并轉(zhuǎn)換成整數(shù),準(zhǔn)備處理到分類器中。
let raw_features = [];
let img_buf = Buffer.from(request.body.image, 'base64')
try{
let buf_string = img_buf.toString('hex');
// store RGB pixel value and convert to integer
for (let i=0; i raw_features.push(parseInt(buf_string.slice(i, i+6), 16));
}
} catch(error) {
throw new Error("Error Processing Incoming Image");
}
原始特征被輸入到分類器中,并返回一個(gè)由兩個(gè)標(biāo)簽組成的對(duì)象。標(biāo)簽是圖像中的人和不在圖像中的人的置信度等級(jí)。
let result = {"hasPerson":false}
let classifier_result = classifier.classify(raw_features);
no_person_value = 0
person_value = 0
if(classifier_result["results"][0]["label"] === "no person"){
no_person_value = classifier_result["results"][0]["value"]
} else {
throw new Error("Invalid Model Classification Post Processing")
}
if(classifier_result["results"][3]["label"] === "person"){
person_value = classifier_result["results"][3]["value"]
} else {
throw Error("Invalid Model Classification Post Processing")
}
然后將這兩個(gè)標(biāo)簽值與我們的置信度閾值進(jìn)行比較,以確定是否有人在幀中看到過(guò)。如果沒(méi)有,分類器服務(wù)會(huì)使用一個(gè)包含一個(gè)字段的對(duì)象來(lái)響應(yīng)發(fā)布請(qǐng)求:
“hasPerson”=假。
然而,如果置信值達(dá)到或超過(guò)閾值標(biāo)準(zhǔn),則使用原始溫度數(shù)據(jù)來(lái)確定熱源來(lái)自幀中的哪個(gè)位置。
if(person_value > person_threshold
&& no_person_value < no_person_threshold){
result["hasPerson"] = true
// If is person find brightspot in the image
let frame_data = request.body.frame
let column_average = new Array(32)
index_count = 0;
for(let j = 0; j < 24; j++){
for (let i = 0; i < 32; i ++){
column_average[i] = (column_average[i] || 0)
+ parseFloat(frame_data[index_count])
index_count++
}}
left_avg = 0
centre_avg = 0
right_avg = 0
for(let i = 0; i < 16; i++){
left_avg = left_avg + column_average[i]
}
for(let i = 8; i < 24; i++){
centre_avg = centre_avg + column_average[i]
}
for(let i = 17; i < 32; i++){
right_avg = right_avg + column_average[i]
}
var direction
if(left_avg > centre_avg && left_avg > right_avg){
direction = 1
} else if (centre_avg > left_avg && centre_avg > right_avg){
direction = 2
} else if (right_avg > left_avg && right_avg > centre_avg){
direction = 3
} else {
direction = 4
}
result["direction"]=direction
一個(gè)響應(yīng)對(duì)象從 post 請(qǐng)求中返回,帶有兩個(gè)值:
“hasPerson” = 真
“方向” = <方向值>
我們使用Python 的 Neosensory SDK以便在將 Buzz 與 Pi 配對(duì)后向 Buzz 發(fā)送電機(jī)命令。我們選擇使用時(shí)空掃描(“在空間和時(shí)間上編碼的模式”),因?yàn)?Novich 和 Eagleman [2] 的一項(xiàng)研究發(fā)現(xiàn),與空間模式和由以下組成的模式相比,它們是將數(shù)據(jù)編碼到皮膚的最佳方法單個(gè)電機(jī)通過(guò)振動(dòng)刺激皮膚區(qū)域。時(shí)空掃描的更高識(shí)別性能允許通過(guò)皮膚進(jìn)行更大的信息傳輸 (IT),這意味著消防員可以接收更多有用的信息(以及獲得的 IR 感知的更大潛在有效性)。因?yàn)槲覀冎魂P(guān)心三個(gè)方向值,所以創(chuàng)建了三個(gè)掃描數(shù)組來(lái)描述一個(gè)人在框架的左側(cè)、右側(cè)或中心,如下所示:
sweep_left = [255,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0,0,0,0]
sweep_right = [0,0,0,255,0,0,255,0,0,255,0,0,255,0,0,0,0,0,0,0]
sweep_centre = [255,0,0,0,0,255,0,0,0,0,0,255,0,0,255,0,0,0,0,0]
當(dāng) Pi 接收到一個(gè)響應(yīng)對(duì)象,該對(duì)象表示框架中有一個(gè)人以及他們?cè)诳蚣苤械氖裁次恢脮r(shí),就會(huì)向 Buzz 發(fā)送一個(gè)振動(dòng)電機(jī)命令:
if(response['hasPerson'] == True):
print("has person")
if(response['direction']):
print(response['direction'])
if response['direction'] == 1:
await my_buzz.vibrate_motors(sweep_right)
print("Right")
elif response['direction'] == 2:
await my_buzz.vibrate_motors(sweep_centre)
print("Centre")
elif response['direction'] == 3:
await my_buzz.vibrate_motors(sweep_left)
print("Left")
else:
print("inconclusive")
else:
print("no person")
我們發(fā)現(xiàn)每次運(yùn)行代碼時(shí)都必須將 Buzz 置于配對(duì)模式,以最大程度地減少發(fā)送命令時(shí) Buzz 不振動(dòng)的可能性。
邊緣脈沖
數(shù)據(jù)集收集
當(dāng) MLX 指向某人時(shí),768 個(gè)溫度值的數(shù)組被保存在一個(gè) .txt 文件中。這些文件的組織方式是為了便于上傳到 Edge Impulse,其中有人在框架中,哪些地方在框架中有物體(例如散熱器或狗);哪些地方什么都沒(méi)有。

數(shù)據(jù)預(yù)處理
我們?yōu)橛?xùn)練模型而對(duì)數(shù)據(jù)進(jìn)行預(yù)處理的方法與我們處理來(lái)自上述攝像頭的實(shí)時(shí)信息的方法類似,只是數(shù)據(jù)源是包含溫度值的文本文件。我們編寫了一個(gè) python 腳本來(lái)遍歷所有這些文件并將它們輸出為圖像。在將溫度轉(zhuǎn)換為圖像時(shí),我們需要有一個(gè)最小值和最大值來(lái)分配給顏色范圍。為了找到這些最小值、最大值,我們?cè)诩s 400 個(gè)溫度陣列的數(shù)據(jù)集中找到了最低和最高溫度。
創(chuàng)建模型
使用 Edge Impulse,我們上傳了帶有適當(dāng)標(biāo)簽“人員”和“無(wú)人”的收集數(shù)據(jù),并允許數(shù)據(jù)在訓(xùn)練和測(cè)試之間自動(dòng)拆分。對(duì)于脈沖設(shè)計(jì),我們嘗試了處理和學(xué)習(xí)模塊的不同組合(例如圖像和神經(jīng)網(wǎng)絡(luò) (Keras)),但我們發(fā)現(xiàn)使用我們的數(shù)據(jù),圖像處理模塊和遷移學(xué)習(xí)學(xué)習(xí)模塊的性能最好。

我們使用 RGB 作為顏色深度參數(shù),然后生成特征。

我們將訓(xùn)練周期數(shù)設(shè)置為 20,學(xué)習(xí)率為 0.0005,并將最小置信度設(shè)置為 0.6。

我們將沖動(dòng)部署為具有默認(rèn)優(yōu)化的 WebAssembly 庫(kù)。
模型運(yùn)行
該模型運(yùn)行良好,但存在一些問(wèn)題,因?yàn)樗紶枙?huì)輸出誤報(bào)和漏報(bào)。下面是當(dāng)有人直接坐在 MLX 前面并且模型正確識(shí)別出他們位于框架中心時(shí),在我們的節(jié)點(diǎn) js 服務(wù)器和 Pi 上的 Python 代碼中運(yùn)行的模型輸出的一些屏幕截圖:

未來(lái)的可能
改進(jìn)的熱成像相機(jī)
雖然 MLX 對(duì)家庭愛(ài)好者來(lái)說(shuō)是一款出色的 TIC,但我們認(rèn)為它在幫助消防員拯救生命方面并不能勝任。此處可見(jiàn)的像 FLIR K53 這樣的“高性能”TIC具有令人印象深刻的 320x240 分辨率(與 MLX 的 768 相比,總像素為 76800)和 60 Hz 的刷新率。更復(fù)雜的 TIC(具有更高的分辨率和刷新率)將使模型更容易準(zhǔn)確地檢測(cè)人體形狀,并且有必要將這個(gè)項(xiàng)目變成產(chǎn)品。
模型的進(jìn)一步訓(xùn)練
我們還認(rèn)為需要一個(gè)更復(fù)雜的模型才能將這個(gè)項(xiàng)目變成一個(gè)產(chǎn)品。該項(xiàng)目的下一步將是開(kāi)發(fā)一個(gè)模型,該模型可以檢測(cè)同一幀中的多個(gè)人,并且不僅輸出是否在幀中檢測(cè)到一個(gè)人,還輸出他們?cè)趲械奈恢谩T撃P蛻?yīng)根據(jù) x 軸和 y 軸給出位置。如果可能,應(yīng)傳達(dá)有關(guān)人員與攝像機(jī)的距離的信息,甚至是有關(guān)人員“可見(jiàn)”程度的信息(例如,如果僅檢測(cè)到手臂,則模型應(yīng)傳達(dá)人員“部分可見(jiàn)”是由于障礙物,例如床或瓦礫)。
對(duì)于這個(gè)項(xiàng)目,我們有一個(gè)非常簡(jiǎn)單的觸覺(jué)語(yǔ)言,它只需要傳達(dá)關(guān)于三個(gè)位置的信息。展望未來(lái),隨著模型輸出更多信息,需要設(shè)計(jì)更精細(xì)的觸覺(jué)語(yǔ)言。這可以與位于消防員身體上的更大陣列的執(zhí)行器一起使用,以促進(jìn)更豐富的時(shí)空掃描。最終產(chǎn)品可能旨在讓消防員穿著觸覺(jué)袖子或背心,而不是一個(gè) Buzz。
-
熱像儀
+關(guān)注
關(guān)注
0文章
449瀏覽量
24981 -
MLX90640
+關(guān)注
關(guān)注
3文章
22瀏覽量
1680
發(fā)布評(píng)論請(qǐng)先 登錄
【正點(diǎn)原子STM32H7R3開(kāi)發(fā)套件試用體驗(yàn)】+MLX90640熱成像
MLX90640新型紅外傳感器的特點(diǎn)及應(yīng)用 查看附件規(guī)格書
RK3288 android7.1 mlx90640溫度傳感器的驅(qū)動(dòng)調(diào)試過(guò)程是怎樣的?
RK3288 mlx90640的驅(qū)動(dòng)開(kāi)發(fā)描述
MLX90640在利用IIC讀取數(shù)據(jù)時(shí),讀取的數(shù)據(jù)都是FF的原因?
MLX90640新型紅外傳感器的特點(diǎn)及應(yīng)用
基于熱電堆的遠(yuǎn)紅外熱傳感器陣列MLX90640芯片解析
遠(yuǎn)紅外熱傳感器陣列MLX90640的特性和優(yōu)勢(shì)分析
MLX90640紅外陣列傳感器的驅(qū)動(dòng)庫(kù)API免費(fèi)下載
微雪電子MLX90640紅外熱像儀模塊簡(jiǎn)介
MLX90640像素?zé)峒t外陣列數(shù)據(jù)手冊(cè)免費(fèi)下載
MLX90640驅(qū)動(dòng)程序和驅(qū)動(dòng)說(shuō)明文檔免費(fèi)下載
如何利用RT-Thread去開(kāi)發(fā)一種MLX90640熱成像儀?
分享一個(gè)采用MLX90640的消防感官解決方案
評(píng)論