Hololens人臉屬性識別原理

hololens的人臉識別承諾的原理解析視頻沒辦法(懶)錄給大家了。
原因是我重裝了系統(tǒng)并且以后工作方向更改了,不用unity了。
我知道文字說明再詳細(xì)也比不上視頻演示看得明白,我盡量吧,代碼能貼的都貼出來。

首先呢,hololens的人臉識別我做了兩版,第一版是匆忙上馬,架構(gòu)很爛,我就簡單說一下。第二版是準(zhǔn)備好好說的。

第一版簡述:
hololens拍照得到一個Pic,
Pic通過hololensSharingServer傳給服務(wù)器上的程序A,
A將Pic保存到硬盤得到路徑P,
A將參數(shù)P傳給python程序B,
B作為客戶端訪問python程序C,并傳參數(shù)P給C,
C作為服務(wù)器一直運(yùn)行,識別模型在C上面,
C接收P,按照P讀取Pic,Pic輸入模型并得到輸出S
C將S返回給B,
B將S返回給A,
A將S通過hololensSharingServer發(fā)送給hololens,
hololens顯示S解析后的信息。
因?yàn)檫@里面的架構(gòu)極其松散,容易出問題(雖然在開發(fā)環(huán)境沒問題,但是不堪大用),就很快優(yōu)化了。

第二版詳述:
1 - hololens拍照,(這步肯定少不了)
有些人會疑問,為什么不是視頻流?
因?yàn)閔ololens的攝像頭不能我的需求。hololens的攝像頭現(xiàn)在只有兩種模式:拍照和錄像。錄像只有一種結(jié)果就是存在硬盤的MP4格式。
拍照有兩種結(jié)果一個是存到硬盤另一個是內(nèi)存中的一段數(shù)據(jù)。(好像還有第三種,沒仔細(xì)看)。如果使用視頻,那么只能先錄一段,發(fā)送識別,這樣搞和拍照比,沒優(yōu)勢。最理想肯定是視頻流,但是hololens無法實(shí)現(xiàn)(或者是我不會)
2 - 將hololens內(nèi)存中的Pic發(fā)送到服務(wù)器
服務(wù)器一直運(yùn)行(因?yàn)槟P蛦訒馁M(fèi)時間,所以模型一直運(yùn)行比較好),接收到Pic后進(jìn)入模型,模型出結(jié)果后返回給hololens
現(xiàn)在說下第二版的一些代碼相關(guān):
有hololens部分和python服務(wù)器部分:
hololens:
hololens使用相機(jī)有這么幾個關(guān)鍵函數(shù),這些都在hololens官網(wǎng)上能找到(這是我寫出來的原因之一)
OnPhotoCaptureCreated
OnPhotoModeStarted
OnCapturedPhotoToMemory
拍照之前要創(chuàng)建相機(jī) PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
這里的false是“要不要拍攝到MR物體”
注意有一個坑是,你啟動了相機(jī)還可以啟動相機(jī),(請理解一下左側(cè)話)就是說你可能啟動一萬個相機(jī)然后hololens卡崩了(咦,我為什么知道?哈哈哈)
具體開始拍照的語句是photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
我是設(shè)置了間隔,每隔3秒拍照一次(這個時間我是開環(huán)控制的,這個時間比較安全)(講道理應(yīng)該上次拍照完成就可以進(jìn)行下次拍照了,雖然有點(diǎn)費(fèi)電)
獲取到相片的語句是photoCaptureFrame.UploadImageDataToTexture(targetTexture);
我自己寫的發(fā)送Pic的語句mySendPic_new(tex.EncodeToJPG()); //byte[]
發(fā)送的具體方法是異步的 StartCoroutine(sendPicToPyByWWW(tex2JPG_bs));
最為關(guān)鍵的一個函數(shù)!?。?/p>
IEnumerator sendPicToPyByWWW(byte[] bs)
? ? {
? ? ? ? print("發(fā)送的長度= " + bs.Length);
? ? ? ? form = new WWWForm();
? ? ? ? form.AddBinaryData("pic", bs);
? ? ? ? using (UnityWebRequest uwr = UnityWebRequest.Post(URL, form))
? ? ? ? {
? ? ? ? ? ? uwr.timeout = TIMEOUT;
? ? ? ? ? ? yield return uwr.SendWebRequest();
? ? ? ? ? ? if (uwr.isDone && string.IsNullOrEmpty(uwr.error))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? string res = uwr.downloadHandler.text;
? ? ? ? ? ? ? ? showWhatIGet(res);
? ? ? ? ? ? }
? ? ? ? }
? ? }
其中最最關(guān)鍵的語句是uwr那一句。因?yàn)槭褂镁W(wǎng)絡(luò)傳輸文件有幾種寫法(我忘記了),只有這一種可以在hololens上使用(反正我只成功了這一個)。
具體和.net庫有關(guān),在PC上跑這個unity程序用好幾種方法都可以,但是上了hololens就不行。這段代碼是耗時最多的一段了。
關(guān)于代碼應(yīng)該很好懂,我都沒寫注釋:準(zhǔn)備一個form放圖片,再準(zhǔn)備一個post請求攜帶form發(fā)到服務(wù)器URL,等待返回,如果返回不出錯就下一步處理。

python:
先要交代的是服務(wù)器和模型:
服務(wù)器使用from http.server import HTTPServer, BaseHTTPRequestHandler
模型使用
# YOLOV2
# reference from https://github.com/experiencor/keras-yolo2
# https://github.com/experiencor/keras-yolo2/blob/master/LICENSE
服務(wù)器啟動:
sever = HTTPServer(ADDR, PostHandler)
sever.serve_forever()
然后處理POST請求:
form使用cgi處理
(這里有一個問題,form中的圖片信息是2進(jìn)制的,yolov2網(wǎng)絡(luò)接收的是CV2中的np格式)
所以使用python的PIL庫中Image:
pimg = Image.open(io.BytesIO(pic))? # 這里圖片轉(zhuǎn)成RGB
再使用CV2就可以啦
cvimg = CV2.cvtColor(np.asarray(pimg), CV2.COLOR_RGB2BGR)? # 這里圖片轉(zhuǎn)成cv的BGR
如果不按照上面兩行代碼這樣搞,就需要把form中二進(jìn)制流存到硬盤再讀取出來,比較耗性能而已。
這樣就可以進(jìn)模型了
最后把模型的處理結(jié)果轉(zhuǎn)成二進(jìn)制返回就行了
hololens的人臉識別原理講解到此結(jié)束,雖然肯定沒有說清楚,但是也為想做類似項(xiàng)目的同學(xué)指了一條明路
其中的名詞單詞如果不是專門搞python或者網(wǎng)絡(luò)或者h(yuǎn)ololens的,看不懂也很正常。(這篇文檔的閱讀量不知道能不能過10)

下一步計劃
本人下一步方向近期是flutter,中長期是圖像。
近一周在學(xué)習(xí)flutter,本來想出一些視頻同步我的學(xué)習(xí),不過發(fā)現(xiàn)已經(jīng)有人出了比較好的教學(xué)視頻了JSPang這個也是B站找得到的。
我還在跟著他的視頻學(xué)習(xí)。
以后出視頻可能會跟圖像有關(guān)。
如果有同學(xué)有圖像方面的經(jīng)驗(yàn)希望可以不吝賜教共同進(jìn)步。
