開(kāi)箱:得捷越做越好,現(xiàn)在從購(gòu)買(mǎi)到收貨速度越來(lái)越快啦!短短一周就收到貨了。
UNITV M12板子非常小巧,正面是使用陽(yáng)極氧化鋁切割出來(lái)的外殼,背面是塑料殼。有顆大大的攝像頭,攝像頭背面,可以插入SD卡。底部有兩個(gè)接口,一個(gè)是Type-C電源數(shù)據(jù)口,另外一個(gè)是2.0mm的4P的GLOVE接口,對(duì)應(yīng)管腳G34、G35,可以做串口或I2C口使用。側(cè)面各有一個(gè)按鍵,按鍵對(duì)應(yīng)管腳G19、G18。
因?yàn)橐龅墓苣_有限,在編程開(kāi)發(fā)時(shí),從Grove接口用杜邦線接了個(gè)串口轉(zhuǎn)Usb模塊,將G34、G35作為串口使用,輸出數(shù)據(jù),方便調(diào)試。
需求:大樓電機(jī)房需要定時(shí)巡檢。電機(jī)房位置比較偏僻,巡檢工作內(nèi)容簡(jiǎn)單,但是要求巡檢到位。為了保證值班人員巡檢到位,通過(guò)AI攝像頭,進(jìn)行工作質(zhì)量檢查。
設(shè)計(jì):通過(guò)攝像頭進(jìn)行人臉識(shí)別,當(dāng)識(shí)別到人臉,就拍照記錄到SD卡上。定期收集SD卡的文件,核驗(yàn)工作情況。
實(shí)現(xiàn):首先附上代碼。
import sensor
import image
import lcd
import time
import utime
from machine import UART
import KPU as kpu
from Maix import GPIO
from fpioa_manager import *
fm.register(34,fm.fpioa.UART1_TX)
fm.register(35,fm.fpioa.UART1_RX)
uart_out = UART(UART.UART1, 115200, 8, None, 1, timeout=1000, read_buf_len=4096)
lastsnaptime=""
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.run(1)
while False:
uart_out.write('TEST\n')
utime.sleep_ms(100)
def getStrTime():
nowtime=time.localtime()
return "{:0>4d}{:0>2d}{:0>2d}{:0>2d}{:0>2d}{:0>2d}".format(nowtime[0],nowtime[1],nowtime[2],nowtime[3],nowtime[4],nowtime[5])
#task = kpu.load(0x300000) # 你需要把模型(face.kfpkg)在閃存地址0x300000
task = kpu.load("/sd/face.kmodel")#將模型放在 SD 卡中。
#模型描參數(shù)
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
#初始化 yolo2 網(wǎng)絡(luò)
a = kpu.init_yolo2(task, 0.8, 0.3, 5, anchor)
while(True):
img = sensor.snapshot()
code = kpu.run_yolo2(task, img)#運(yùn)行 yolo2 網(wǎng)絡(luò)
if code:
for i in code:
uart_out.write(getStrTime()+" "+str(i)+"\n")
if lastsnaptime!=getStrTime():
lastsnaptime=getStrTime()
img.save("/sd/img/"+lastsnaptime+".jpg?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg,t_20")
#sensor.snapshot().save("/sd/img/"+str(time.ticks_ms())+".jpg?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg,t_20")
a = img.draw_rectangle(i.rect())
a = lcd.display(img)
a = kpu.deinit(task)#反初始化
這里使用了maixpy作為編程工具,使用了官網(wǎng)提供的KPU人臉識(shí)別算法。從官網(wǎng)下載人臉識(shí)別算法模型文件(既可以保存在flash里,也可以保存在SD卡上)。在代碼中使用kpu.load()方法加載模型文件。
#初始化 yolo2 網(wǎng)絡(luò)
a = kpu.init_yolo2(task, 0.8, 0.3, 5, anchor)
為yolo2網(wǎng)絡(luò)模型傳入初始化參數(shù), 留意第二個(gè)參數(shù),是概率閾值, 只有是這個(gè)物體的概率大于這個(gè)值才會(huì)輸出結(jié)果, 取值范圍:[0, 1],我這里取了0.8的閾值,實(shí)測(cè)基本不會(huì)誤記錄了。當(dāng)kpu模型檢測(cè)到人臉時(shí),就將獲得到的圖片保存到SD卡。最后將代碼保持到boot.py就能夠上電運(yùn)行了。
問(wèn)題:整個(gè)項(xiàng)目過(guò)程中遇到兩個(gè)大問(wèn)題。
問(wèn)題1:原本計(jì)劃著搞好人臉檢測(cè),再加上人臉識(shí)別的。Maixpy的人臉識(shí)別也提供了模型,但是模型是加了密的。 密碼使用的是機(jī)器碼。機(jī)器碼是一機(jī)一碼的一種加密方式,用于模型文件的加密。如果使用別的機(jī)器碼去加密或者下載以 smodel 為文件后綴的模型文件,開(kāi)發(fā)板是無(wú)法使用該模型文件的。通過(guò)官方的說(shuō)明,下載了key_gen.bin這個(gè)固件,燒寫(xiě)后上電應(yīng)該就能通過(guò)串口獲得到機(jī)器碼了。但是UNITV M12這個(gè)板子,沒(méi)有復(fù)位鍵!沒(méi)有復(fù)位鍵!沒(méi)有復(fù)位鍵!燒寫(xiě)完固件后,只能通過(guò)插拔USB線,復(fù)位,但是插上USB線后,電腦要好一會(huì)才能認(rèn)到這個(gè)USB串口,讀不到機(jī)器碼!最終放棄了這個(gè)思路。
問(wèn)題2:這個(gè)模塊的RTC感覺(jué)很奇怪,使用 time.localtime()去讀取時(shí)間,按文檔說(shuō)明,應(yīng)該讀取到的是一個(gè) 年、月、日、時(shí)、分、秒……的元組。有時(shí)能讀到正常的時(shí)間,有時(shí)讀取到的數(shù)據(jù)又是亂的,找不到規(guī)律,還不清楚是什么引起的。
所以,這個(gè)UNITV M12很適合做一個(gè)圖像的傳感器,配合其它主控一起工作。