Dlib —— 对图片进行人脸检测并绘出特征(附C++源码)

news2025/1/12 6:51:40
效果

在这里插入图片描述

在这里插入图片描述

注意:Dlib检测人脸在Release版耗时与CPU有关,本人I7 10代约100ms左右。建议人脸检测可以考虑使用Yolov5进行,之后将检测到的人脸输入给Dlib做特征或其他。

代码

#include <iostream>

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/dnn.h>
#include <dlib/gui_widgets.h>
#include <dlib/clustering.h>
#include <dlib/string.h>
#include <dlib/image_io.h>
#include <dlib/image_transforms.h>
#include <dlib/opencv.h>

#include "opencv2/opencv.hpp"

void line_one_face_detections(cv::Mat &img, std::vector<dlib::full_object_detection> fs)
{
	int i, j;
	for (j = 0; j < fs.size(); j++)
	{

		cv::Point p1, p2;
		for (i = 0; i < 67; i++)
		{
			//if (i != 48 && i != 64 && i != 38 && i != 43 && i != 29) { continue; }

			// 下巴到脸颊 0 ~ 16
			//左边眉毛 17 ~ 21
			//右边眉毛 21 ~ 26
			//鼻梁     27 ~ 30
			//鼻孔        31 ~ 35
			//左眼        36 ~ 41
			//右眼        42 ~ 47
			//嘴唇外圈  48 ~ 59
			//嘴唇内圈  59 ~ 67
			switch (i)
			{
			case 16:
			case 21:
			case 26:
			case 30:
			case 35:
			case 41:
			case 47:
			case 59:
				i++;
				break;
			default:
				break;
			}

			p1.x = fs[j].part(i).x();
			p1.y = fs[j].part(i).y();
			p2.x = fs[j].part(i + 1).x();
			p2.y = fs[j].part(i + 1).y();
			cv::line(img, p1, p2, cv::Scalar(0, 0, 255), 2, 4, 0);
			cv::circle(img, p1, 1, cv::Scalar(0, 0, 255), 3, 4, 0);

// 			char str[25] = { 0 };
// 			itoa(i, str, 10);
// 			cv::putText(img, str, cv::Point(p1.x, p1.y), 1, 1, cv::Scalar(0, 0, 255), 1, 4, 0);
		}
	}
}

int main()
{
	clock_t  start_t, end_t;

	//cv::VideoCapture vc(0);
	cv::VideoCapture vc("./test.mp4");
	if (vc.isOpened())
	{
		// 加载dlib的人脸检测器
		dlib::frontal_face_detector detector = dlib::get_frontal_face_detector();

		// 加载人脸形状探测器
		dlib::shape_predictor sp;
		dlib::deserialize("./Face/shape_predictor_68_face_landmarks.dat") >> sp;

		// 循环操作
		cv::Mat SrcMat, Mat;
		while (1)
		{
			// 读取一帧图像
			vc >> SrcMat;
			if (SrcMat.empty()) { break; }

			// 每5帧做一次,因为dlib人脸检测耗时约100ms(i7-10750H的CPU下测试)
			static unsigned short rFrameRate = 0;
			if (++rFrameRate <= 6) { continue; }rFrameRate = 0;

			// 提取灰度图
			cv::cvtColor(SrcMat, Mat, cv::COLOR_BGR2GRAY);

			// Mat转化为dlib的matrix
			dlib::array2d<dlib::bgr_pixel> dimg;
			dlib::assign_image(dimg, dlib::cv_image<uchar>(Mat));

			// 获取一系列人脸所在区域
			start_t = (double)clock();
			std::vector<dlib::rectangle> dets = detector(dimg);
			end_t = (double)clock();
			int64_t curTime = 1000 * (end_t - start_t) / (double)CLOCKS_PER_SEC;
			std::cout << "total ms:" << curTime;
			std::cout << "\tNumber of faces detected: " << dets.size() << std::endl;
			if (dets.size() > 0)
			{
				//获取人脸特征点分布
				std::vector<dlib::full_object_detection> shapes;
				for (int i = 0; i < dets.size(); i++)
				{
					dlib::full_object_detection shape = sp(dimg, dets[i]); //获取指定一个区域的人脸形状
					shapes.push_back(shape);
				}

				//指出每个检测到的人脸的位置
				for (int i = 0; i < dets.size(); i++)
				{
					//画出人脸所在区域
					cv::Rect r;
					r.x = dets[i].left();
					r.y = dets[i].top();
					r.width = dets[i].width();
					r.height = dets[i].height();
					cv::rectangle(SrcMat, r, cv::Scalar(0,255, 0, 0), 3, 1, 0);
				}

				// 特征绘制
				line_one_face_detections(SrcMat, shapes);
			}

			// 刷新图片
			cv::resize(SrcMat, SrcMat, cv::Size(480, 320));
			cv::imshow("Mat", SrcMat);
			cv::waitKey(1);
		}
		vc.release();
	}

	system("pause");
	return 0;
}


关注

笔者 - jxd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/703937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【胖虎的逆向之路】——GOT/PLT Hook详解针对自定义so库的Hook实操

文章目录 [TOC](文章目录) 前言一、ELF 是什么&#xff1f;1、ELF 的概念2、ELF 的组成2.1、 两种视图是什么呢&#xff1f;2.2、 ELF文件头又是什么西西&#xff1f;2.2、 ELF中节头表是什么南南呢&#xff1f;2.2、 ELF中程序头表是什么北北呢&#xff1f; 二、动态库装载、动…

uni-app 微信小程序发布时,主包超过2M限制

小程序发布时&#xff0c;提示超过2M&#xff0c;无法通过&#xff0c;此时可以尝试以下几种方法&#xff1a; 1、对图片做压缩 图片尽量放在服务器端&#xff0c;使用的时候&#xff0c;通过URL路径获取&#xff0c;若不得已放在本地时&#xff0c;可以对图片进行压缩&#…

基于springboot+Redis的前后端分离项目之分布式锁-redission(五)-【黑马点评】

&#x1f381;&#x1f381;资源文件分享 链接&#xff1a;https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA?pwdeh11 提取码&#xff1a;eh11 分布式锁-redission 分布式锁-redission1 分布式锁-redission功能介绍2 分布式锁-Redission快速入门3 分布式锁-redission可重入锁…

NoSQL之Redis优化(一)

Redis的高可用 一、Redis 持久化RDB 持久化AOF 持久化RDB和AOF的优缺点 二、Redis 性能管理内存碎片如何产生的&#xff1f;解决碎片率大的问题&#xff1a;内存使用率内回收key 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时…

【Java可执行命令】(四)反编译工具javap:深入解析应用程序反编译工具javap ~

Java可执行命令详解之javap 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法格式3.1.1 可选参数&#xff1a;-l3.1.2 可选参数&#xff1a;-c3.1.3 可选参数&#xff1a;-s3.1.4 可选参数&#xff1a;-verbose3.1.5 可选参数&#xff1a;-version 4️⃣ 应用场景5️⃣ 注意事项&…

6.21、设计模式 单例设计模式

1 设计模式&#xff08;Design pattern&#xff09; 代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来…

好用又智能笔记类工具有哪些?

在工作和生活中&#xff0c;我们经常面临大量信息和任务需要记录和整理。好用又智能的笔记类工具成为了办公人士提高工作效率和组织信息的必备利器。 敬业签笔记工具支持分类记录笔记&#xff0c;可以根据不同的主题或项目进行整理。无论是工作笔记、学习笔记还是个人生活记录…

OpenFeign——请求其他服务时传递token信息

文章目录 前言准备流程初测定义nacos-product子服务定义服务的消费方 cloudalibaba-openfeign-server初步测试结论 设置cloudalibaba-openfeign-server中的feign总结 前言 在实际开发过程中&#xff0c;服务与服务之间都会有比较频繁的通信操作。其次不同用户所需要查询的数据…

【正点原子STM32连载】 第四十七章 SRAM实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第四…

使用inno打包程序流程

1:配置iss文件 ​​​​​​​ 2编译 3.生成安装包文件安装

浅谈建筑项目中的智能照明系统的设计与研究

【摘要】&#xff1a;建筑智能照明工程中智能照明控制系统发展迅速&#xff0c;具有舒适性和节能性两方面优势。智能照明控制系统已经处于模块化高速发展阶段&#xff0c;如今更好的控制方案成为制约系统发展的瓶颈。文章在研究了国内外智能照明系统的基础上&#xff0c;从照明…

【CSS】nth:children以及浏览器内核webkit使用(滚动条样式修改)

&#x1f609;博主&#xff1a;初映CY的前说(前端领域) ,&#x1f4d2;本文核心&#xff1a;nth:children以及浏览器中的webkit使用 前言&#xff1a;在页面的编写中使用了多个标签通常有需求去处理下特殊的样式&#xff0c;我们常见做法是给我们的标签加上一个类或者通过标签选…

【微服务】什么是微服务?-- 全面了解微服务架构

What is Microservices — Edureka 您有没有想过&#xff0c;什么是微服务以及扩展行业如何与它们集成&#xff0c;同时构建应用程序以满足客户的期望&#xff1f; 要了解什么是微服务&#xff0c;您必须了解如何将单体应用程序分解为独立打包和部署的小型微型应用程序。本文将…

力扣 -- 91.解码方法

题目链接&#xff1a;91. 解码方法 - 力扣&#xff08;LeetCode&#xff09; 以下是用动态规划的思想解决这道题目&#xff0c;如果对动态规划五部曲的含义还不是很清楚的老铁可以看看本专栏的第一题动规(10条消息) 力扣 -- 746. 使用最小花费爬楼梯_KOBE 0824 BRYANT的博客-…

软件测试编写文档模板【附文档模板】

一、测试岗位必备的文档 在一个常规的软件测试流程中&#xff0c;会涉及到测试计划、测试方案、测试用例、测试报告的编写&#xff0c;这些文档也是软件测试岗位必须掌握的文档类型。 1、测试计划 测试计划是组织管理层面的文件&#xff0c;从组织管理的角度对一次测试活动进…

华为OD机试真题 Python实现【最小的调整次数】【2023Q1 100分】

目录 一、题目描述二、输入描述三、输出描述四、补充说明五、解题思路六、Python算法源码七、效果展示1、输入2、输出3、说明 一、题目描述 有一个特异性的双端队列&#xff0c;该队列可以从头部或尾部添加数据&#xff0c;但是只能从头部移出数据。 小A依次执行2n个指令往队…

uboot详解(嵌入式学习)

uboot详解 概念详解扩展Windows的“uboot” 概念 U-Boot&#xff08;Unified Bootloader&#xff09;是一个开源的嵌入式系统引导加载程序&#xff0c;也是一种通用的引导加载程序。它主要用于嵌入式系统的启动过程&#xff0c;负责初始化硬件设备、加载操作系统内核和启动应用…

Android Studio 使用 Build Variants 配置测试/正式环境域名等字段

拿测试环境域名和正式环境域名举例&#xff1a;在项目调试和发版过程中可以通过频繁地注释和解开注释来切换正式环境域名和测试环境域名&#xff0c;但此方法过于繁琐&#xff1b;所以可以使用Android Studio的Build Variants根据切换环境来替我们执行切换环境的操作。 在项目…

《HelloGitHub》第 87 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …

可视化对讲广播电话可以用在哪里

可视化对讲广播电话可以用在哪里 可视化对讲广播电话&#xff1a;无处不在的沟通利器 【工地现场】 在矗立的高楼上&#xff0c;工地上忙碌的工人们使用着可视化对讲广播电话。借助高清画面和清晰音频&#xff0c;工作人员可以实时观察工地情况&#xff0c;更好地协调工作&a…