糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 基于深度学习的人脸检测和关键点检测推理实践(OpenCV实现 含代码)

基于深度学习的人脸检测和关键点检测推理实践(OpenCV实现 含代码)

时间:2023-12-17 05:30:35

相关推荐

基于深度学习的人脸检测和关键点检测推理实践(OpenCV实现 含代码)

目录

一、任务概述

二、环境准备

三、实现步骤

3.1 Python推理

3.2 C++推理

3.2.1 环境准备

3.2.2 推理

3.3Java推理

一、任务概述

最近项目中大量场景需要用到人脸检测和人脸关键点检测技术,因此经过一番查找,将相关资料进行了整理,最终的目的是希望能够将基于深度学习的人脸检测算法落地部署,方便未来直接嵌入到自己的项目中。

本文主要使用于士琪的人脸检测代码来操作,详细的训练(Pytorch版)过程和使用说明请参考官方代码:

libfacedetection/ShiqiYu/libfacedetection值得注意的是上述开源项目已经贡献到OpenCV里面了,因此,只需要安装最新的opencv即可方便的使用该人脸检测代码。

本文使用Windows10操作系统进行部署,只使用CPU,不依赖GPU。如果需要使用GPU,需要下载对应支持GPU CUDA版本的opencv。

本文完整代码链接:/download/qianbin396/77986050

二、环境准备

安装OpenCV,版本要求>= 4.5.4从官网下载已经训练并导出的onnx推理文件,下载地址:libfacedetection.train/yunet.onnx at a61a428929148171b488f024b5d6774f93cdbc13 · ShiqiYu/libfacedetection.train · GitHub

三、实现步骤

3.1 Python推理

首选安装环境包:

pip install numpypip install "opencv-python>=4.5.4.58" -i /pypi/simple

这里为了加速下载使用了百度镜像源。安装过程中如果opencv一直安装不上,可以尝试先更新下pip软件:

pip install --upgrade pip setuptools wheel

推理代码如下所示:

import numpy as npimport cv2 as cvdef visualize(image, faces, print_flag=False):'''可视化结果'''output = image.copy()for idx, face in enumerate(faces):if print_flag:print('Face {}, top-left coordinates: ({:.0f}, {:.0f}), box width: {:.0f}, box height {:.0f}, score: {:.2f}'.format(idx, face[0], face[1], face[2], face[3], face[-1]))coords = face[:-1].astype(np.int32)# 画人脸框cv.rectangle(output, (coords[0], coords[1]), (coords[0]+coords[2], coords[1]+coords[3]), (0, 255, 0), 2)# 画关键点cv.circle(output, (coords[4], coords[5]), 2, (255, 0, 0), 2)cv.circle(output, (coords[6], coords[7]), 2, (0, 0, 255), 2)cv.circle(output, (coords[8], coords[9]), 2, (0, 255, 0), 2)cv.circle(output, (coords[10], coords[11]), 2, (255, 0, 255), 2)cv.circle(output, (coords[12], coords[13]), 2, (0, 255, 255), 2)# 画置信度cv.putText(output, '{:.4f}'.format(face[-1]), (coords[0], coords[1]+15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))return outputdef main():'''主函数'''# 初始化模型yunet = cv.FaceDetectorYN.create(model='./yunet.onnx',config='',input_size=(320, 320),score_threshold=0.6,nms_threshold=0.3,top_k=5000,backend_id=cv.dnn.DNN_BACKEND_DEFAULT,target_id=cv.dnn.DNN_TARGET_CPU)# 读入图像image = cv.imread('test.jpg')# 重新设置模型输入尺寸yunet.setInputSize((image.shape[1], image.shape[0]))# 执行检测_, faces = yunet.detect(image)# 画检测框和关键点vis_image = visualize(image, faces)# 保存图像cv.imwrite('new.jpg', vis_image)print('完成')if __name__ == '__main__':main()

效果图如下所示:

从效果上来看检测精度是比较高的,满足实用需求。

测试结果如下所示:

如果想要达到实时性检测要求,把图像分辨率降低1倍,即控制在512x512的尺寸,那么就可以满足该指标。如果想要在嵌入式设备上跑该代码,那还需要再进一步优化。

3.2 C++推理

3.2.1 环境准备

本节使用VS在windows平台上通过C++实现人脸检测和人脸关键点检测。

首先从官网下载最新版opencv:Releases - OpenCV/releases/

本文下载使用对应windows版本的opencv4.5.5。

接下来用VS创建一个控制台项目:

创建完成后切换成64位Release平台:

然后进行项目配置如下:

(1)属性配置——VC++目录

(2)属性配置——库目录

(3)链接器——输入

添加lib文件如下:

接下来将opencv对应的dll文件(opencv_world455.dll)和模型文件yunet.onnx拷贝到项目根目录下即可。如下图所示:

3.2.2 推理

完整推理代码如下:

#include <iostream>//导入opencv库#include <opencv2/dnn.hpp>#include <opencv2/imgproc.hpp>#include <opencv2/highgui.hpp>#include <opencv2/objdetect.hpp>//定义命名空间using namespace std;using namespace cv;Mat visualize(cv::Mat input, cv::Mat faces, bool print_flag = false, int thickness = 2){cv::Mat output = input.clone();for (int i = 0; i < faces.rows; i++){if (print_flag) {cout << "Face " << i<< ", top-left coordinates: (" << faces.at<float>(i, 0) << ", " << faces.at<float>(i, 1) << "), "<< "box width: " << faces.at<float>(i, 2) << ", box height: " << faces.at<float>(i, 3) << ", "<< "score: " << faces.at<float>(i, 14) << "\n";}// 画人脸框cv::rectangle(output, cv::Rect2i(int(faces.at<float>(i, 0)), int(faces.at<float>(i, 1)), int(faces.at<float>(i, 2)), int(faces.at<float>(i, 3))), cv::Scalar(0, 255, 0), thickness);// 画关键点cv::circle(output, cv::Point2i(int(faces.at<float>(i, 4)), int(faces.at<float>(i, 5))), 2, cv::Scalar(255, 0, 0), thickness);cv::circle(output, cv::Point2i(int(faces.at<float>(i, 6)), int(faces.at<float>(i, 7))), 2, cv::Scalar(0, 0, 255), thickness);cv::circle(output, cv::Point2i(int(faces.at<float>(i, 8)), int(faces.at<float>(i, 9))), 2, cv::Scalar(0, 255, 0), thickness);cv::circle(output, cv::Point2i(int(faces.at<float>(i, 10)), int(faces.at<float>(i, 11))), 2, cv::Scalar(255, 0, 255), thickness);cv::circle(output, cv::Point2i(int(faces.at<float>(i, 12)), int(faces.at<float>(i, 13))), 2, cv::Scalar(0, 255, 255), thickness);// 画置信度cv::putText(output, cv::format("%.4f", faces.at<float>(i, 14)), cv::Point2i(int(faces.at<float>(i, 0)), int(faces.at<float>(i, 1)) + 15), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0));}return output;}int main(int argc, char** argv){//参数设置cv::String modelPath = "yunet.onnx";int backendId = 0; //0: default, 1: Halide, 2: Intel's Inference Engine, 3: OpenCV, 4: VKCOM, 5: CUDAint targetId = 0; //0: CPU, 1: OpenCL, 2: OpenCL FP16, 3: Myriad, 4: Vulkan, 5: FPGA, 6: CUDA, 7: CUDA FP16, 8: HDDLfloat scoreThreshold = 0.9;float nmsThreshold = 0.3;int topK = 5000;// 初始化人脸检测器FaceDetectorYNcv::Ptr<cv::FaceDetectorYN> detector = cv::FaceDetectorYN::create(modelPath, "", cv::Size(320, 320), scoreThreshold, nmsThreshold, topK, backendId, targetId);// 加载图像cv::Mat image = cv::imread("test.jpg");// 重新设置尺寸detector->setInputSize(image.size());//检测cv::Mat faces;detector->detect(image, faces);//可视化结果cv::Mat vis_image = visualize(image, faces, true);cout << "执行完成.\n";//保存结果cv::imwrite("result.jpg", vis_image); }

3.3Java推理

Java推理部分请参考另一篇博文。

如果觉得《基于深度学习的人脸检测和关键点检测推理实践(OpenCV实现 含代码)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。