三十、项目实战:实时人脸检测

OpenCV3.3之后的版本都支持了深度学习框架,具体的模型相关路径如下图所示
在这里插入图片描述

一、相关文件下载

前期准备工作:
下载两个文件:下载链接
在这里插入图片描述
最好放到跟项目一块,到时候方便调用

二、代码

yy_main.cpp

pbtxt_pathpb_path为下载的那俩文件的路径

cv::dnn::Net net = cv::dnn::readNetFromTensorflow(pb_path, pbtxt_path);
读取得到神经网络对象net

VideoCapture capture(0);,这是调用本地摄像头,要是播放视频,可以将参数0换成视频的路径字符串即可,路径记得是正斜杠哈

cv::Mat frame;
用于存储视频中的每一帧数据信息

capture.read(frame);
读取每一帧数据信息

flip(frame,frame,1);
如果是调用本地摄像头的话,可能需要对视频内容进行翻转一下,摄像头详细内容可参考博文:二十二、摄像头的调用

cv::Mat blob = cv::dnn::blobFromImage(frame, 1.0, Size(300, 300), cv::Scalar(104, 177, 123), false, false);
blobFromImage主要是用来对图片进行预处理
参数一:frame,将要输入神经网络进行处理的图片
参数二:1.0,该参数得优先考虑到参数四,当我们将图片减去平均值之后,还可以对剩下的像素值进行一定的尺度缩放,默认值是1.0;若需要减去平均像素之后的值,全部缩小一半,那么可以将该参数设为1/2即可
参数三:Size(300, 300),训练时,输入的图片大小
参数四:cv::Scalar(104, 177, 123),对BGR通道的像素求一个平均值,然后将每个像素值减去平均值,得到像素之间的相对值,尽可能减少光照等因素的影响;OpenCV给出了均值,如下图所示,当然OpenCV给出的肯定是按照BGR顺序来的
参数五:OpenCV中图片通道顺序是BGR,但是平均值假设的顺序是RGB,所以如果需要交换R和G,那么就要设置为true;这里是通过查阅OpenCV给出的均值进行填入的,故也是BGR顺序,不需要交换
参数六:是否对图片进行裁剪,这里就是false即可

下面就是参数四的设置由来
在这里插入图片描述
net.setInput(blob);
把网络传进去

cv::Mat probs = net.forward();
反向传播求梯度求结果,得到的返回结果为一个个的box,大小为1×1×N×7,N代表有多少张人脸,每个人脸有7个值;7个值得前两个不需要解析,第三个值是置信度,后四个值是左上角和右下角得坐标,后期需要这些坐标来进行框人脸

Mat detectMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());
人脸信息是四维,解析人脸数据信息

detectMat.rows,共有7行,每一行都是float数据

float conf = detectMat.at<float>(row, 2);
第三个是置信度,获取到置信度,置信度超过多少就算是人脸,根据情况而定

float x1 = detectMat.at<float>(row, 3) * frame.cols;
float y1 = detectMat.at<float>(row, 4) * frame.rows;
float x2 = detectMat.at<float>(row, 5) * frame.cols;
float y2 = detectMat.at<float>(row, 6) * frame.rows;
得到左上角(x1,y1)和右下角(x2,y2)坐标

因为预测得到得detectMat.at<float>(row, 3)是0-1之间的,目前是在图片上进行显示,故再乘以对应的每帧图像的行或列即可,例如这个是乘以原图的列frame.cols,得到实际人脸左上角关键点在图片中的实际的x位置,其他也都类似

cv::Rect box(x1, y1, x2 - x1, y2 - y1);
定义进行对象,参数分别为起始坐标和宽高信息

cv::rectangle(frame, box, cv::Scalar(255, 0, 0), 2, 8);
绘制矩形框,具体可参考博文:十四、图像几何形状绘制

#include<opencv2/opencv.hpp>
#include<iostream>using namespace cv;int main(int argc, char** agrv) {std::string pbtxt_path = "E:/C++_workspace/finally_face/opencv_face_detector.pbtxt";std::string pb_path = "E:/C++_workspace/finally_face/opencv_face_detector_uint8.pb";cv::dnn::Net net = cv::dnn::readNetFromTensorflow(pb_path, pbtxt_path);VideoCapture capture(0);cv::Mat frame;while (true) {capture.read(frame);//也可以通过之前的滤波等操作实现美颜效果//其实本质都是对每帧图像frame进行处理的而已//GaussianBlur(frame, frame, Size(3, 3), 1, 1);flip(frame,frame,1);//左右翻转if (frame.empty()) {break;}cv::Mat blob = cv::dnn::blobFromImage(frame, 1.0, Size(300, 300), cv::Scalar(104, 177, 123), false, false);net.setInput(blob);cv::Mat probs = net.forward();//1*1*N*7Mat detectMat(probs.size[2], probs.size[3], CV_32F, probs.ptr<float>());for (int row = 0; row < detectMat.rows; row++) {float conf = detectMat.at<float>(row, 2);if (conf > 0.5) {float x1 = detectMat.at<float>(row, 3) * frame.cols;float y1 = detectMat.at<float>(row, 4) * frame.rows;float x2 = detectMat.at<float>(row, 5) * frame.cols;float y2 = detectMat.at<float>(row, 6) * frame.rows;cv::Rect box(x1, y1, x2 - x1, y2 - y1);cv::rectangle(frame, box, cv::Scalar(255, 0, 0), 2, 8);}}cv::imshow("frame", frame);int c = waitKey(10);if (c == 27) {break;}}cv::waitKey(0);capture.release();cv::destroyAllWindows();return 0;
}

项目结构如下:
在这里插入图片描述

运行效果如下:
在这里插入图片描述

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

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

相关文章

Java 学习和实践笔记(20):static的含义和使用

static的本义是静止的。在计算机里就表示静态变量。 在Java中&#xff0c;从内存分析图上可以看到&#xff0c;它与类、常量池放在一个区里&#xff1a; 从图可以看到&#xff0c;普通的方法和对象属性&#xff0c;都在heep里&#xff0c;而static则在方法区里。 static声明的…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--大模型、扩散模型

专属领域论文订阅 VX 关注{晓理紫}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 分类: 大语言模型LLM视觉模型VLM扩散模型视觉语言…

API接口开发采集淘宝商品详情页数据优惠券sku价格销量信息等可支持高并发接入演示

要知道&#xff0c;要开发一个API接口用于采集淘宝商品详情页数据&#xff08;如优惠券、SKU、价格、销量信息等&#xff09;&#xff0c;并支持高并发接入&#xff0c;你需要考虑以下几个步骤&#xff1a; 需求分析: 确定你需要从淘宝商品详情页采集哪些具体信息。 遵守法律法…

STL - 并查集

1、并查集原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合&#xff1b;开始时&#xff0c;每个元素自成一个 单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并&#xff1b;在此过程中要反复用到查询某一 个元素归属于那个集合的…

Ps:明度直方图

明度 Luminosity直方图显示了图像中各个亮度级别的像素分布情况。 与 RGB 直方图不同&#xff0c;“明度”直方图专注于图像的亮度信息&#xff0c;而不是单独的颜色信息。 在“直方图”面板的通道中选择“明度”。 “明度”直方图提供了一种量化的方式来理解图像的整体明暗结构…

Excel多表格多工作簿合并

Excel多表格、多工作簿合并 直接通过“数据”栏目内置的“新建查询"可以实现&#xff0c;参考&#xff1a; https://blog.csdn.net/qq_42692386/article/details/116231710 一. 单工作簿多工作表合并 点击【数据】>【获取数据】>【来自文件】>【从工作簿】&am…

速度提高100倍 - 扩展 RAG 应用程序,以实现数十亿个嵌入,并行计算余弦相似度

原文链接&#xff1a;100x Faster — Scaling Your RAG App for Billions of Embeddings 2024 年 2 月 15 日 RAG应用程序最大的问题之一是它们的计算检索时间。想象一下&#xff0c;你有一个向量数据库&#xff0c;包含一万亿条Embedding向量的记录。当您尝试将用户查询与一…

idea 打jar包、lib文件夹

idea目录文件 idea四层级结构 idea操作Java文件的基本单位&#xff1a;项目&#xff08;Project&#xff09;。对应四级结构 第1层级架构&#xff1a;项目&#xff08;project&#xff09; 在 IntelliJ IDEA 中Project是最顶级的结构单元&#xff0c;然后就是Module&#xf…

Llama中文大模型-模型+工具(外延能力)

除了持续增强大模型内在的知识储备、通用理解、逻辑推理和想象能力等&#xff0c;未来&#xff0c;我们也会不断丰富大模型的外延能力&#xff0c;例如知识库检索、计算工具、WolframAlpha、操作软件等。 我们首先集成了LangChain框架&#xff0c;可以更方便地基于Llama2开发文…

MySQL知识点总结(六)——InnoDB底层架构

MySQL知识点总结&#xff08;六&#xff09;——InnoDB底层架构 InnoDB底层架构总览InnoDB底层各组件分析Buffer PoolChange BufferLog BufferAdaptive Hash IndexSystem TablesapceUndo TablespacesRedo Log InnoDB底层架构总览 关于InnoDB底层架构&#xff0c;网上有一张非常…

JS基础之常用方法

JS基础之常用方法 目录 JS基础之常用方法字符串数字布尔数组 字符串 length: 返回字符串的长度 var sen " Hello World" console.log(sen) // Hello World console.log(sen.length) // 12trim():去除首尾空格 var sen " Hello World" console.log(se…

电脑常见问题及解决方法

如何速度定位电脑故障&#xff1f; 根据开机报警的声音&#xff0c;判断硬件的问题。AMI BIOS 1 短——内存刷新失败 2 短——内存ECC 校验错误 3 短——系统基本内存[检查失败 4 短——系统时钟出错 5 短——中央处理器错误 6 短——键盘控制器错误 7 短——系统实模式…

Linux之JAVA环境配置Tomcat离线安装与启动

一&#xff0c;安装jdk和Tomcat 1.1上传JDK跟Tomcat 1.2解压 解压tomcat tar -zxvf apache-tomcat-8.5.20.tar.gz 解压jdk tar -zxvf jdk-8u151-linux-x64.tar.gz 1.3.配置环境变量 vim /etc/profile 在最后加上&#xff1a; #java environment export JAVA_HOME/usr/local/ja…

异步框架Celery在Django中的运用

参考博客&#xff1a;https://www.cnblogs.com/pyedu/p/12461819.html 参考视频&#xff1a;01 celery的工作机制_哔哩哔哩_bilibili 定义&#xff1a;简单灵活、处理大量消息的分布式系统&#xff0c;专注于实时处理异步队列&#xff0c;支持任务调度 主要架构&#xff1a; …

Linux的信号

Linux的信号是一种用于进程之间通信的机制。它们用于向进程发送通知&#xff0c;告知进程发生了某种事件或请求进程执行某个操作。信号可以由内核、其他进程或进程自身发送。 信号的作用有以下几个方面&#xff1a; 通知进程某个事件的发生&#xff0c;如进程的终止、挂起、恢…

springboot/ssm来访管理系统Java访客预约来访登记系统web

springboot/ssm来访管理系统Java访客预约来访登记系统web 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysq…

软件实例,物流货运配货单打印模板软件单据打印查询管理系统软件教程,可以同时打印标签或补打

软件实例&#xff0c;物流货运配货单打印模板软件单据打印查询管理系统软件教程&#xff0c;可以同时打印标签或补打 一、前言 以下软件教程以 佳易王物流单打印查询系统V17.1为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 这个版本在原来基…

Android 跨进程通信技术优劣分析

一、引言 在Android开发中&#xff0c;跨进程通信&#xff08;IPC&#xff09;是一项常见的任务&#xff0c;用于在不同的应用程序或组件之间交换数据。有多种IPC机制可供选择&#xff0c;每种机制都有其优势和劣势。以下是对几种常见IPC技术的分析。 二、跨进程通信 2.1、Bi…

【软件使用】postman使用教程

​ &#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;软件安装及使用 ⛳️ 功不唐捐&#xff0c;玉汝于成 ​ 目录 前言 正文 步骤1&#xff1a;安装Postman 步骤2&#xff1a;发送请求 步骤3&#xff1a;管理环境变量 步骤4&#xff1…

Leetcode 26-30题

删除有序数组中的重复项 给定一个有序数组&#xff0c;要求原地删除重复出现的元素&#xff0c;返回删除后的数组的长度。 这里的原地删除其实可以这样表示&#xff0c;用双指针从前往后扫一遍&#xff0c;遇到新的没出现过的元素就放到前面去&#xff0c;就可以实现删除后的数…