關于模型
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模塊直接呼叫的,呼叫方式如下:
landmark_net = cv.dnn.readNetFromONNX("landmarks_cnn.onnx")
image = cv.imread("D:/facedb/test/464.jpg")
cv.imshow("input", image)
h, w, c = image.shape
blob = cv.dnn.blobFromImage(image, 0.00392, (64, 64), (0.5, 0.5, 0.5), False) / 0.5
print(blob)
landmark_net.setInput(blob)
lm_pts = landmark_net.forward()
print(lm_pts)
for x, y in lm_pts:
print(x, y)
x1 = x * w
y1 = y * h
cv.circle(image, (np.int32(x1), np.int32(y1)), 2, (0, 0, 255), 2, 8, 0)
cv.imshow("人臉五點檢測", image)
cv.imwrite("D:/landmark_det_result.png", image)
cv.waitKey(0)
cv.destroyAllWindows()運行結果如下:

ONNX轉IR
如何把ONNX檔案轉換OpenVINO的IR檔案?答案是借助OpenVINO的模型優化器組件工具,OpenVINO的模型優化器組件工具支持常見的Pytorch預訓練模型與torchvision遷移訓練模型的轉換,
要轉換ONNX到IR,首先需要安裝ONNX組件支持,直接運行OpenVINO預安裝腳本即可獲得支持,截圖如下:

然后執行下面的轉換腳本即可:

不用懷疑了,轉換成功!

加速推理
使用OpenVINO的Inference Engine加速推理,對得到的模型通過OpenVINO安裝包自帶的OpenCV DNN完成呼叫,設定加速推理引擎為Inference Engine,這部分的代碼如下:
dnn::Net emtion_net = readNetFromModelOptimizer(emotion_xml, emotion_bin);
emtion_net.setPreferableTarget(DNN_TARGET_CPU);
emtion_net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
其中readNetFromModelOptimizer表示使用OpenVINO模型優化器來加載檔案,并使用inference engine執行加速推理。
執行推理與輸出決議,得到表情分類的結果,代碼如下:
Rect box(x1, y1, x2 - x1, y2 - y1);
Mat roi = frame(box);
Mat face_blob = blobFromImage(roi, 0.00392, Size(64, 64), Scalar(0.5, 0.5, 0.5), false, false);
emtion_net.setInput(face_blob);
Mat probs = emtion_net.forward();
int index = 0;
float max = -1;
for (int i = 0; i < 8; i++) {
const float *scores = probs.ptr<float>(0, i, 0);
float score = scores[0];
if (max < score) {
max = score;
index = i;
}
}
rectangle(frame, box, Scalar(0, 255, 0));
最終的運行結果如下圖:
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/175270.html
標籤:英特爾技術
上一篇:Python網路爬蟲快速上手
