基于onnx的人脸识别
·
基本出发点是想做一个C++版本的人脸识别,而caffe的C++库,或mxnet的C++库等,暂时还不会编译,而之前基于onnxruntime 搞过一个项目,对这个库稍微了解一些,所以尽量采用onnx搞定全部功能
直接运行该工程,可以得到如下结果:
Distance = 0.461761
Similarity = 0.769120
是可以正常运行的
不过他这个mtcnn人脸检测,看起来是采用mxnet加载的caffemodel的网络,嗯,可能不太好转为C++
不过我在github上还是找到了一个用onn库的mtcnn,https://github.com/linxiaohui/mtcnn-opencv
https://github.com/linxiaohui/mtcnn-opencv
暂时先用这个库来替换原来网络中的mtcnn,难度应该不大
接下来是用onnxruntime来替换mxnet,加载 arcfaceresnet100-8.onnx 来执行人脸识别,这个还是有点儿坑
如果直接替换的话,会报错:
2021-12-12 20:37:38.028783022 [E:onnxruntime:, sequential_executor.cc:346 Execute] Non-zero status code returned while running BatchNormalization node. Name:'stage1_unit1_bn1' Status Message: Invalid input scale: NumDimensions() != 3
Traceback (most recent call last):
File "/home/luke/Download/onnx/myFaceRec/arcface_inference_remove_mxnet.py", line 254, in <module>
out1 = get_feature(pre1)
File "/home/luke/Download/onnx/myFaceRec/arcface_inference_remove_mxnet.py", line 217, in get_feature
embedding = session.run([label_name], {'data': norm_img_data})
File "/home/luke/miniconda3/lib/python3.9/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 192, in run
return self._sess.run(output_names, input_feed, run_options)
onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Non-zero status code returned while running BatchNormalization node. Name:'stage1_unit1_bn1' Status Message: Invalid input scale: NumDimensions() != 3
如果搜索这个报错的话,可能可以搜索到issue:[ONNXRuntimeError] Arcface model fails during ONNX runtime session run · Issue #242 · onnx/models · GitHub在这个issue中有人给出了解决方案:
import onnx
model = onnx.load(r'arcfaceresnet100-8.onnx')
for node in model.graph.node:
if(node.op_type == "BatchNormalization"):
for attr in node.attribute:
if (attr.name == "spatial"):
attr.i = 1
onnx.save(model, r'updated_resnet100.onnx')
用该脚本执行后,就可以得到相同的结果,核心代码为:
session = onnxruntime.InferenceSession('updated_resnet100.onnx', None)
def get_feature(aligned):
input_name = session.get_inputs()[0].name
label_name = session.get_outputs()[0].name
norm_img_data = aligned.reshape(1, 3, 112, 112).astype('float32')
embedding = session.run([label_name], {'data': norm_img_data})
embedding = sklearn.preprocessing.normalize(embedding[0]).flatten()
return embedding
识别结果为:
Distance = 0.531714
Similarity = 0.734143
和原代码有点儿不同,但基本一致
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)