Hololens人脸属性识别原理

hololens的人脸识别承诺的原理解析视频没办法(懒)录给大家了。
原因是我重装了系统并且以后工作方向更改了,不用unity了。
我知道文字说明再详细也比不上视频演示看得明白,我尽量吧,代码能贴的都贴出来。

首先呢,hololens的人脸识别我做了两版,第一版是匆忙上马,架构很烂,我就简单说一下。第二版是准备好好说的。

第一版简述:
hololens拍照得到一个Pic,
Pic通过hololensSharingServer传给服务器上的程序A,
A将Pic保存到硬盘得到路径P,
A将参数P传给python程序B,
B作为客户端访问python程序C,并传参数P给C,
C作为服务器一直运行,识别模型在C上面,
C接收P,按照P读取Pic,Pic输入模型并得到输出S
C将S返回给B,
B将S返回给A,
A将S通过hololensSharingServer发送给hololens,
hololens显示S解析后的信息。
因为这里面的架构极其松散,容易出问题(虽然在开发环境没问题,但是不堪大用),就很快优化了。

第二版详述:
1 - hololens拍照,(这步肯定少不了)
有些人会疑问,为什么不是视频流?
因为hololens的摄像头不能我的需求。hololens的摄像头现在只有两种模式:拍照和录像。录像只有一种结果就是存在硬盘的MP4格式。
拍照有两种结果一个是存到硬盘另一个是内存中的一段数据。(好像还有第三种,没仔细看)。如果使用视频,那么只能先录一段,发送识别,这样搞和拍照比,没优势。最理想肯定是视频流,但是hololens无法实现(或者是我不会)
2 - 将hololens内存中的Pic发送到服务器
服务器一直运行(因为模型启动会耗费时间,所以模型一直运行比较好),接收到Pic后进入模型,模型出结果后返回给hololens
现在说下第二版的一些代码相关:
有hololens部分和python服务器部分:
hololens:
hololens使用相机有这么几个关键函数,这些都在hololens官网上能找到(这是我写出来的原因之一)
OnPhotoCaptureCreated
OnPhotoModeStarted
OnCapturedPhotoToMemory
拍照之前要创建相机 PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
这里的false是“要不要拍摄到MR物体”
注意有一个坑是,你启动了相机还可以启动相机,(请理解一下左侧话)就是说你可能启动一万个相机然后hololens卡崩了(咦,我为什么知道?哈哈哈)
具体开始拍照的语句是photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
我是设置了间隔,每隔3秒拍照一次(这个时间我是开环控制的,这个时间比较安全)(讲道理应该上次拍照完成就可以进行下次拍照了,虽然有点费电)
获取到相片的语句是photoCaptureFrame.UploadImageDataToTexture(targetTexture);
我自己写的发送Pic的语句mySendPic_new(tex.EncodeToJPG()); //byte[]
发送的具体方法是异步的 StartCoroutine(sendPicToPyByWWW(tex2JPG_bs));
最为关键的一个函数!!!
IEnumerator sendPicToPyByWWW(byte[] bs)
{
print("发送的长度= " + 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);
}
}
}
其中最最关键的语句是uwr那一句。因为使用网络传输文件有几种写法(我忘记了),只有这一种可以在hololens上使用(反正我只成功了这一个)。
具体和.net库有关,在PC上跑这个unity程序用好几种方法都可以,但是上了hololens就不行。这段代码是耗时最多的一段了。
关于代码应该很好懂,我都没写注释:准备一个form放图片,再准备一个post请求携带form发到服务器URL,等待返回,如果返回不出错就下一步处理。

python:
先要交代的是服务器和模型:
服务器使用from http.server import HTTPServer, BaseHTTPRequestHandler
模型使用
# YOLOV2
# reference from https://github.com/experiencor/keras-yolo2
# https://github.com/experiencor/keras-yolo2/blob/master/LICENSE
服务器启动:
sever = HTTPServer(ADDR, PostHandler)
sever.serve_forever()
然后处理POST请求:
form使用cgi处理
(这里有一个问题,form中的图片信息是2进制的,yolov2网络接收的是CV2中的np格式)
所以使用python的PIL库中Image:
pimg = Image.open(io.BytesIO(pic)) # 这里图片转成RGB
再使用CV2就可以啦
cvimg = CV2.cvtColor(np.asarray(pimg), CV2.COLOR_RGB2BGR) # 这里图片转成cv的BGR
如果不按照上面两行代码这样搞,就需要把form中二进制流存到硬盘再读取出来,比较耗性能而已。
这样就可以进模型了
最后把模型的处理结果转成二进制返回就行了
hololens的人脸识别原理讲解到此结束,虽然肯定没有说清楚,但是也为想做类似项目的同学指了一条明路
其中的名词单词如果不是专门搞python或者网络或者hololens的,看不懂也很正常。(这篇文档的阅读量不知道能不能过10)

下一步计划
本人下一步方向近期是flutter,中长期是图像。
近一周在学习flutter,本来想出一些视频同步我的学习,不过发现已经有人出了比较好的教学视频了JSPang这个也是B站找得到的。
我还在跟着他的视频学习。
以后出视频可能会跟图像有关。
如果有同学有图像方面的经验希望可以不吝赐教共同进步。
