#include "pch.h"
#include <tuple>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iterator>
using namespace cv;
using namespace cv::dnn;
using namespace std;
/**
* @brief Get the Face Box object 人脸定位
*
* @param net 人脸检测网络
* @param frame 检测图像
* @param conf_threshold 阈值
* @return tuple<Mat, vector<vector<int>>> 元组容器,可返回多个值
*/
tuple<Mat, vector<vector<int>>> getFaceBox(Net net, Mat &frame, double conf_threshold)
{
//图像复制
Mat frameOpenCVDNN = frame.clone();
int frameHeight = frameOpenCVDNN.rows;
int frameWidth = frameOpenCVDNN.cols;
//缩放尺寸
double inScaleFactor = 1.0;
//检测图大小
Size size = Size(300, 300);
// std::vector<int> meanVal = {104, 117, 123};
Scalar meanVal = Scalar(104, 117, 123);
cv::Mat inputBlob;
inputBlob = cv::dnn::blobFromImage(frameOpenCVDNN, inScaleFactor, size, meanVal, true, false);
net.setInput(inputBlob, "data");
//四维矩阵输出
cv::Mat detection = net.forward("detection_out");
//提取结果信息
cv::Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
vector<vector<int>> bboxes;
for (int i = 0; i < detectionMat.rows; i++)
{
//预测概率
float confidence = detectionMat.at<float>(i, 2);
if (confidence > conf_threshold)
{
//左上角点,坐标被归一化
int x1 = static_cast<int>(detectionMat.at<float>(i, 3) * frameWidth);
int y1 = static_cast<int>(detectionMat.at<float>(i, 4) * frameHeight);
//右下角角点,坐标被归一化
int x2 = static_cast<int>(detectionMat.at<float>(i, 5) * frameWidth);
int y2 = static_cast<int>(detectionMat.at<float>(i, 6) * frameHeight);
vector<int> box = { x1, y1, x2, y2 };
//人脸坐标
bboxes.push_back(box);
//图像框选
cv::rectangle(frameOpenCVDNN, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0), 2, 4);
}
}
return make_tuple(frameOpenCVDNN, bboxes);
}
int main(void)
{
//人脸模型
string faceProto = "model/opencv_face_detector.pbtxt";
string faceModel = "model/opencv_face_detector_uint8.pb";
//年龄模型
string ageProto = "model/age_deploy.prototxt";
string ageModel = "model/age_net.caffemodel";
//性别模型
string genderProto = "model/gender_deploy.prototxt";
string genderModel = "model/gender_net.caffemodel";
//均值
Scalar MODEL_MEAN_VALUES = Scalar(78.4263377603, 87.7689143744, 114.895847746);
//年龄段标签
vector<string> ageList = { "(0-2)", "(4-6)", "(8-12)", "(15-20)", "(25-32)",
"(38-43)", "(48-53)", "(60-100)" };
//性别标签
vector<string> genderList = { "Male", "Female" };
//导入网络
Net ageNet = cv::dnn::readNet(ageProto, ageModel);
Net genderNet = cv::dnn::readNet(genderProto, genderModel);
Net faceNet = cv::dnn::readNetFromTensorflow(faceModel, faceProto);
//打开摄像头
VideoCapture cap;
cap.open(0);
if (cap.isOpened())
{
cout << "camera is opened!" << endl;
}
else
{
return 0;
}
int padding = 20;
while (waitKey(1) < 0)
{
// read frame 读图
Mat frame;
cap.read(frame);
if (frame.empty())
{
waitKey();
break;
}
frame = imread("./images/couple1.jpg");
//人脸坐标
vector<vector<int>> bboxes;
//人脸检测结果图
Mat frameFace;
//人脸定位
//tie()函数解包frameFace和bboxes
tie(frameFace, bboxes) = getFaceBox(faceNet, frame, 0.7);
//人脸判断
if (bboxes.size() == 0)
{
cout << "No face detected, checking next frame." << endl;
continue;
}
//逐个提取人脸检测
for (auto it = begin(bboxes); it != end(bboxes); ++it)
{
//框选人脸
Rect rec(it->at(0) - padding, it->at(1) - padding, it->at(2) - it->at(0) + 2 * padding, it->at(3) - it->at(1) + 2 * padding);
//避免人脸框选超过图像边缘
rec.width = ((rec.x + rec.width) > frame.cols) ? (frame.cols - rec.x - 1) : rec.width;
rec.height = ((rec.y + rec.height) > frame.rows) ? (frame.rows - rec.y - 1) : rec.height;
// take the ROI of box on the frame,原图中提取人脸
Mat face = frame(rec);
//性别检测
Mat blob;
blob = blobFromImage(face, 1, Size(227, 227), MODEL_MEAN_VALUES, false);
genderNet.setInput(blob);
// string gender_preds; 获取前向传播softmax结果
vector<float> genderPreds = genderNet.forward();
// find max element index max_ele�
基于深度学习识别人脸性别和年龄
5星 · 超过95%的资源 需积分: 0 83 浏览量
更新于2019-03-04
26
收藏 82.53MB 7Z 举报
在本文中,我们将深入探讨如何使用深度学习技术来识别人脸的性别和年龄。这个主题主要涉及计算机视觉和机器学习领域,特别是在人脸识别和图像处理方面。我们提供的资源包括C++和Python的代码实现,以及相关的模型和图像数据。
我们要理解深度学习的基本概念。深度学习是一种人工神经网络的方法,通过多层非线性变换对数据进行建模,能够从大量数据中自动提取特征并进行预测。在人脸识别性别和年龄的应用中,深度学习模型通常会学习到人脸图像中的关键特征,如面部轮廓、眼睛、嘴巴等,从而推断出性别和年龄。
OpenCV是一个强大的开源计算机视觉库,它提供了许多用于图像处理和分析的工具。在这个项目中,OpenCV被用来进行人脸检测和预处理,这是识别性别和年龄的第一步。OpenCV的Haar级联分类器或Dlib库的HOG特征可以用于检测图像中的人脸。
`age_gender.cpp` 和 `AgeGender.py` 分别是用C++和Python实现的代码。在C++中,你可能使用OpenCV的C++接口来加载模型,处理图像,并进行预测。而在Python版本中,除了OpenCV,还可能涉及到其他深度学习框架,如TensorFlow或Keras,它们提供了更高级的API来构建和运行深度学习模型。
模型文件(未在列表中给出具体名称)通常包含预训练的权重,这些权重是在大量标注数据上训练得到的。这些模型可能是卷积神经网络(CNN),如VGG、Inception或ResNet,因为CNN在图像识别任务中表现出色。模型接受人脸图像作为输入,然后通过多层网络计算出性别和年龄的概率分布。
`images` 文件夹很可能包含了测试或示例图像,用于验证代码功能和模型性能。这些图片可能包含不同年龄、性别的人脸,以展示模型在不同情况下的表现。
在实际应用中,首先需要对输入图像进行预处理,例如调整尺寸、归一化和灰度化,以符合模型的输入要求。然后,模型会将处理后的图像作为输入,输出性别和年龄的预测。我们可以根据概率最高的类别来确定性别和年龄。
为了提高模型的准确性和泛化能力,通常需要大量的标注数据进行训练。这可能涉及到收集大量的人脸图像,并手动标注性别和年龄。此外,还可以使用数据增强技术,如旋转、裁剪和光照变化,以增加训练集的多样性。
这个项目展示了如何利用深度学习和OpenCV实现人脸性别和年龄的识别。通过理解和实践这些代码,你可以深入理解深度学习在计算机视觉领域的应用,同时也可以进一步提升自己的编程技能。
落痕的寒假
- 粉丝: 2102
- 资源: 24
最新资源
- libiptcdata-devel-1.0.4-11.el7.x64-86.rpm.tar.gz
- Simulink仿真逆变器:多电平调制方式下的SPWM与SVPWM调制及电压电流双闭环PI控制策略探究,Simulink仿真逆变器,两电平三电平,有正弦脉宽(spwm)调制和矢量脉宽(svpwm)调制
- libiptcdata-python-1.0.4-11.el7.x64-86.rpm.tar.gz
- 轮毂电机分布式驱动车辆状态估计:基于无迹与扩展卡尔曼滤波的7自由度模型分析,车辆状态估计,扩展卡尔曼滤波EKF,无迹卡尔曼滤波UKF 角阶跃输入+整车7自由度模型+UKF状态估计模型+附送EKF状态估
- libiscsi-1.9.0-7.el7.x64-86.rpm.tar.gz
- 三菱PLC大型自动化控制项目:QCPU与QD77MS一体化电气开发系统,高效程序结构助力自动化设备控制程序开发,三菱PlC程序大型项目QCPU+QD77MS16 项目说明如下: 1.包含一套完整的电
- libiscsi-devel-1.9.0-7.el7.x64-86.rpm.tar.gz
- 西门子PLC与KUKA机器人协同工作:安全控制、信号交互与多车型运行策略,西门子PLC配KUKA机器人程序 程序为西门子S7-1500PLC博途调试: 西门子与KUKA机器人通讯; PLC控制KU
- libiscsi-utils-1.9.0-7.el7.x64-86.rpm.tar.gz
- 台达触摸屏直接通信控制多台变频器及与第三方MODBUS产品(含温控器)的通信实现与接线指南,台达触摸屏与多台变频器485通信 温控器通信 1,不用通过PLC,直接由触摸屏的com口进行通信控制 2
- libisofs-1.2.8-4.el7.x64-86.rpm.tar.gz
- libisofs-devel-1.2.8-4.el7.x64-86.rpm.tar.gz
- 欧姆龙CP1H+CIF11与3台E5CC温控通讯程序:稳定可靠的串口网关通讯,实现3台温控器设定与监控,功能丰富,可扩展,附送威纶通触摸屏程序 ,欧姆龙CP1H+CIF11与3台欧姆龙E5CC温控通讯
- libitm-4.8.5-44.el7.x64-86.rpm.tar.gz
- libitm-devel-4.8.5-44.el7.x64-86.rpm.tar.gz
- 激光水平仪全面解决方案:原理图解析、PCB布局与源代码集成,激光水平仪整体方案 原理图 PCB 源代码 ,核心关键词:激光水平仪整体方案; 原理图; PCB; 源代码;,"激光水平仪综合方案:原理图