- 💂 个人主页:风间琉璃
- 🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主
- 💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦
目录
前言
在当今数字时代,计算机视觉技术正在不断发展,并在多个领域产生影响。其中之一是年龄和性别识别。这项技术对于广告定向、人脸解锁和安全访问控制等领域至关重要。
卷积神经网络是一种深度学习模型,它在计算机视觉中表现出色。CNN的核心思想是通过多层卷积和池化操作,从图像中学习特征。这些特征可以用于各种任务,包括图像分类、对象检测和人脸识别。对于年龄和性别识别,CNN可以通过学习人脸的视觉特征来实现高精度。
参考链接:Age and Gender Classification Using Convolutional Neural Networks - Tal Hassner
一、预处理
一般图片都需要进行尺寸大小,维度以及RGB通道的变换。图片尺寸大小要求可以在配置文件的输入网络中查看,年龄的配置文件输入层如下:
//图像预处理
Mat blob = blobFromImage(image, 1.0, Size(227, 227));
其次,需要将网络模型的标签文件读取到内存中,如果标签类别较小也可以直接定义一个数组。
//获取年龄的区间
vector<String> ageLabels()
{
vector<String> ages;
ages.push_back("0-2");
ages.push_back("4-6");
ages.push_back("8-13");
ages.push_back("15-20");
ages.push_back("25-32");
ages.push_back("38-43");
ages.push_back("48-53");
ages.push_back("60-");
return ages;
}
二、模型加载
数据准备后,就可以从模型文件和配置文件中加载网络模型。
//年龄预测网络模型
String age_model = "F:/data/CQU/VS/CNN_Age_Gender/age_net.caffemodel";
//年龄预测配置文件
String age_config = "F:/data/CQU/VS/CNN_Age_Gender/deploy_age.prototxt";
//性别预测网络模型
String gender_model = "F:/data/CQU/VS/CNN_Age_Gender/gender_net.caffemodel";
//性别预测配置文件
String gender_config = "F:/data/CQU/VS/CNN_Age_Gender/deploy_gender.prototxt";
//加载网络
Net age_net = readNetFromCaffe(age_config, age_model);
Net gender_net = readNetFromCaffe(gender_config, gender_model);
三、执行推理
然后就可以进行图像的预测,这里为了预测提高预测的准确度,所先要从图像中找到人脸部分,在送入给网络预测。
人脸检测:
//人脸检测文件
String haar_file = "F:/data/CQU/VS/CNN_Age_Gender/haarcascade_frontalface_alt_tree.xml";
//人脸检测
CascadeClassifier detector;
detector.load(haar_file);
vector<Rect> faces;
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
detector.detectMultiScale(gray, faces, 1.02, 1, 0, Size(40, 40), Size(500, 500));
预测:
// 预测分类
Mat prob = net.forward("prob");
四、解析输出
推理之后就获取到了预测的结果,我们需要对预测结果进行解析,并显示。
//预测年龄
string predict_age(Net& net, Mat& image)
{
//图像预处理
Mat blob = blobFromImage(image, 1.0, Size(227, 227));
net.setInput(blob, "data");
//预测分类
Mat prob = net.forward("prob");
//打平成一维
Mat probMat = prob.reshape(1, 1);
Point classNum;
double classProb;
vector<String> ages = ageLabels();
//提取最大概率的编号和概率值
minMaxLoc(probMat, NULL, &classProb, NULL, &classNum);
int classidx = classNum.x;
return ages.at(classidx);
}
//预测性别
String predict_gender(Net& net, Mat& image)
{
//图片预处理
Mat blob = blobFromImage(image, 1.0, Size(227, 227));
net.setInput(blob, "data");
// 预测分类
Mat prob = net.forward("prob");
Mat probMat = prob.reshape(1, 1);
//比较大小,得到预测结果
String res = (probMat.at<float>(0, 0) > probMat.at<float>(0, 1) ? "Man" : "Female");
return res;
}
//对检测到的人脸进行预测,所以只有在检测到人脸时才会进行预测
String age,gender;
for(size_t t = 0; t < faces.size(); t++)
{
rectangle(src, faces[t], Scalar(30, 255, 30), 2, 8, 0);
//年龄、性别预测
Mat face = src(faces[t]);
age = predict_age(age_net, face);
gender = predict_gender(age_net, face);
putText(src, format("age:%s", age.c_str()), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
putText(src, format("gender:%s", gender.c_str()),Point(20, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
}
imshow("age-gende", src);
运行结果:
程序源码:下载:OpenCV年龄和性别预测资源-CSDN文库
// CNN_Age_Gender.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <vector>
#include <opencv2/highgui/highgui_c.h>
using namespace cv;
using namespace cv::dnn;
using namespace std;
//人脸检测文件
String haar_file = "F:/data/CQU/VS/CNN_Age_Gender/haarcascade_frontalface_alt_tree.xml";
//年龄预测网络模型
String age_model = "F:/data/CQU/VS/CNN_Age_Gender/age_net.caffemodel";
//年龄预测配置文件
String age_config = "F:/data/CQU/VS/CNN_Age_Gender/deploy_age.prototxt";
//性别预测网络模型
String gender_model = "F:/data/CQU/VS/CNN_Age_Gender/gender_net.caffemodel";
//性别预测配置文件
String gender_config = "F:/data/CQU/VS/CNN_Age_Gender/deploy_gender.prototxt";
//获取年龄的区间
vector<String> ageLabels()
{
vector<String> ages;
ages.push_back("0-2");
ages.push_back("4-6");
ages.push_back("8-13");
ages.push_back("15-20");
ages.push_back("25-32");
ages.push_back("38-43");
ages.push_back("48-53");
ages.push_back("60-");
return ages;
}
//预测年龄
string predict_age(Net& net, Mat& image)
{
//图像预处理
Mat blob = blobFromImage(image, 1.0, Size(227, 227));
net.setInput(blob, "data");
//预测分类
Mat prob = net.forward("prob");
//打平成一维
Mat probMat = prob.reshape(1, 1);
Point classNum;
double classProb;
vector<String> ages = ageLabels();
//提取最大概率的编号和概率值
minMaxLoc(probMat, NULL, &classProb, NULL, &classNum);
int classidx = classNum.x;
return ages.at(classidx);
}
//预测性别
String predict_gender(Net& net, Mat& image)
{
//图片预处理
Mat blob = blobFromImage(image, 1.0, Size(227, 227));
net.setInput(blob, "data");
// 预测分类
Mat prob = net.forward("prob");
Mat probMat = prob.reshape(1, 1);
//比较大小,得到预测结果
String res = (probMat.at<float>(0, 0) > probMat.at<float>(0, 1) ? "Man" : "Female");
return res;
}
int main()
{
Mat src = imread("5.jpg");
if(src.empty())
{
printf("could not load image...\n");
return -1;
}
namedWindow("src", CV_WINDOW_AUTOSIZE);
imshow("src", src);
//人脸检测
CascadeClassifier detector;
detector.load(haar_file);
vector<Rect> faces;
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
detector.detectMultiScale(gray, faces, 1.02, 1, 0, Size(40, 40), Size(500, 500));
//加载网络
Net age_net = readNetFromCaffe(age_config, age_model);
Net gender_net = readNetFromCaffe(gender_config, gender_model);
//对检测到的人脸进行预测,所以只有在检测到人脸时才会进行预测
String age,gender;
for(size_t t = 0; t < faces.size(); t++)
{
rectangle(src, faces[t], Scalar(30, 255, 30), 2, 8, 0);
//年龄、性别预测
Mat face = src(faces[t]);
age = predict_age(age_net, face);
gender = predict_gender(age_net, face);
putText(src, format("age:%s", age.c_str()), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
putText(src, format("gender:%s", gender.c_str()),Point(20, 40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1);
}
imshow("age-gende", src);
waitKey(0);
return 0;
}
结束语
感谢你观看我的文章呐~本次航班到这里就结束啦 🛬
希望本篇文章有对你带来帮助 🎉,有学习到一点知识~
躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。
最后,博主要一下你们的三连呀(点赞、评论、收藏),不要钱的还是可以搞一搞的嘛~
不知道评论啥的,即使扣个666也是对博主的鼓舞吖 💞 感谢 💐