栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

使用Unity的Barracuda和Pytorch实现表情识别

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Unity的Barracuda和Pytorch实现表情识别

Barracuda官方文档https://docs.unity3d.com/Packages/com.unity.barracuda@1.0/manual/index.html

表情识别算法来源https://github.com/WuJie1010/Facial-Expression-Recognition.Pytorch

Unity资源商店Moodme免费版(三种表情识别)https://assetstore.unity.com/packages/add-ons/machinelearning/moodme-emotions-barracuda-sdk-191930

 

目录

第一步:跑通表情识别算法

输入处理:

输出处理

第二步:将神经网络模型输出成.onnx文件

第三步:Unity下载Moodme,把表情识别部分改成自己的网络

最终运行效果


第一步:跑通表情识别算法

下载Github上的代码,按照其指引跑通visualize.py(环境配置、创建image文件夹等,略)

用其他算法也同理,稍微看懂它输入输出的大小、处理过程就ok。

输入处理
#Input image
raw_img = io.imread('images/1.jpg')
"521x425"
gray = rgb2gray(raw_img)
"resize成48x48"
gray = resize(gray, (48,48), mode='symmetric').astype(np.uint8)
img = gray[:, :, np.newaxis]
"数组连接,48x48x3"
img = np.concatenate((img, img, img), axis=2)
img = Image.fromarray(img)
"(四角+中心)*2(水平翻转)切出10张44x44的照片,10,3,44,44"
inputs = transform_test(img)

可以看出,输入图片应为48x48,然后切成44x44,再输入到神经网络。

输出处理
outputs_avg = outputs.view(ncrops, -1).mean(0)  # avg over crops
score = F.softmax(outputs_avg)
_, predicted = torch.max(outputs_avg.data, 0)

神经网络outputs为10x7

先求10张图片结果的均值outputs_avg(1x7)

用softmax函数归一化

7个数值中最大的为预测结果

第二步:将神经网络模型输出成.onnx文件

visualize.py添加代码

torch.onnx.export(net,inputs,"face_emotions_model.onnx",output_names={"outputs"},verbose=True)

然后就能在项目文件夹找到相应的文件了。

第三步:Unity下载Moodme,把表情识别部分改成自己的网络

它有面部检测,只是表情识别阉割成了3种,我懒得自己搞了(●'◡'●)

把刚才导出的onnx文件存到Network文件夹,赋值给NetworkAgent>ManageEmotionNetwork脚本>Emotions N Network

ImageNetworkWidth&Height改成44,Channel改成3

 

重点就改ManageEmotionNetwork脚本:仿照原.py对输入输出进行处理

面部图片48x48:previewTexture

//脸部图像处理成10x44x44x3,这里没弄水平翻转,懒
        Texture2D[] ComputeInputTensor(Texture2D source)
        {
            Texture2D texture0, texture1, texture2, texture3, texture4, texture5, texture6, texture7, texture8, texture9, texture10;
            texture0 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture1 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture2 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture3 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture4 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture5 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture6 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture7 = new Texture2D(44, 44, TextureFormat.R8, false);
            texture8 = new Texture2D(44, 44, TextureFormat.R8 false);
            texture9 = new Texture2D(44, 44, TextureFormat.R8, false);

            
            Color[] pix = source.GetPixels(0, 0, 44, 44);
            texture0.SetPixels(pix);
            texture0.Apply();
            texture5.SetPixels(pix);
            texture5.Apply();
            pix = source.GetPixels(0, 4, 44, 44);
            texture1.SetPixels(pix);
            texture1.Apply();
            texture6.SetPixels(pix);
            texture6.Apply();
            pix = source.GetPixels(4, 0, 44, 44);
            texture2.SetPixels(pix);
            texture2.Apply();
            texture7.SetPixels(pix);
            texture7.Apply();
            pix = source.GetPixels(4, 4, 44, 44);
            texture3.SetPixels(pix);
            texture3.Apply();
            texture8.SetPixels(pix);
            texture8.Apply();
            pix = source.GetPixels(2, 2, 44, 44);
            texture4.SetPixels(pix);
            texture4.Apply();
            texture9.SetPixels(pix);
            texture9.Apply();

            var textures = new[] { texture0, texture1, texture2, texture3, texture4, texture5, texture6, texture7, texture8, texture9 };
            return textures;
        }

//仅摘录核心部分

 var textures = ComputeInputTensor(previewTexture);
 tensor = new Tensor(textures, ChannelCount);

output = engine.ExecuteAndWaitForCompletion(tensor);

float[] results = output.data.Download(output.shape);

float[] results_avg=new float[7];

Debug.Log("Result:" + EmotionsLabel[findMax(results_avg)]);

最终运行效果

 

 

对不起了德善(●'◡'●) 

再来个特写

 项目代码下载(等我整理好了再上传)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901387.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号