点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
关于模型
OpenVINO自带的表情识别模型是Caffe版本的,这里使用的模型是前面一篇文章中训练生成的pytorch全卷积网络,模型基于残差网络结构全卷积分类网络。
输入格式:NCHW=1x3x64x64
输出格式:NCHW=1x8x1x1
支持八种表情识别,列表如下:
["neutral","anger","disdain","disgust","fear","happy",
"sadness","surprise"]
转ONNX
训练好的Pytorch模型可以保存为pt文件,通过pytorch自带的脚本可以转换为ONNX模型,这一步的转换脚本如下:
dummy_input = torch.randn(1, 3, 64, 64, device='cuda')
model = torch.load("./face_emotions_model.pt")
output = model(dummy_input)
model.eval()
model.cuda()
torch.onnx.export(model, dummy_input, "face_emotions_model.onnx", output_names={"output"}, verbose=True)
OpenCV DNN调用ONNX模型测试
转换为ONNX格式的模型,是可以通过OpenCV DNN模块直接调用的,调用方式如下:
1landmark_net = cv.dnn.readNetFromONNX("landmarks_cnn.onnx")
2image = cv.imread("D:/facedb/test/464.jpg")
3cv.imshow("input", image)
4h, w, c = image.shape
5blob = cv.dnn.blobFromImage(image, 0.00392, (64, 64), (0.5, 0.5, 0.5), False) / 0.5
6print(blob)
7landmark_net.setInput(blob)
8lm_pts = landmark_net.forward()
9print(lm_pts)
10for x, y in lm_pts:
11 print(x, y)
12 x1 = x * w
13 y1 = y * h
14 cv.circle(image, (np.int32(x1), np.int32(y1)), 2, (0, 0, 255), 2, 8, 0)
15cv.imshow("人脸五点检测", image)
16cv.imwrite("D:/landmark_det_result.png", image)
17cv.waitKey(0)
18cv.destroyAllWindows()
运行结果如下:
ONNX转IR
如何把ONNX文件转换OpenVINO的IR文件?答案是借助OpenVINO的模型优化器组件工具,OpenVINO的模型优化器组件工具支持常见的Pytorch预训练模型与torchvision迁移训练模型的转换,
要转换ONNX到IR,首先需要安装ONNX组件支持,直接运行OpenVINO预安装脚本即可获得支持,截图如下:
然后执行下面的转换脚本即可:
加速推理
使用OpenVINO的Inference Engine加速推理,对得到的模型通过OpenVINO安装包自带的OpenCV DNN完成调用,设置加速推理引擎为Inference Engine,这部分的代码如下:
1dnn::Net emtion_net = readNetFromModelOptimizer(emotion_xml, emotion_bin);
2emtion_net.setPreferableTarget(DNN_TARGET_CPU);
3emtion_net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
其中readNetFromModelOptimizer表示使用OpenVINO模型优化器来加载文件,并使用inference engine执行加速推理。
执行推理与输出解析,得到表情分类的结果,代码如下:
1Rect box(x1, y1, x2 - x1, y2 - y1);
2Mat roi = frame(box);
3Mat face_blob = blobFromImage(roi, 0.00392, Size(64, 64), Scalar(0.5, 0.5, 0.5), false, false);
4emtion_net.setInput(face_blob);
5Mat probs = emtion_net.forward();
6int index = 0;
7float max = -1;
8for (int i = 0; i < 8; i++) {
9 const float *scores = probs.ptr(0, i, 0);
10 float score = scores[0];
11 if (max < score) {
12 max = score;
13 index = i;
14 }
15}
16rectangle(frame, box, Scalar(0, 255, 0));
最终的运行结果如下图:
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~