opencv学习笔记六十三:基于CNN的性别、年龄预测

来自于2015年CVPR的一篇paper《Age and Gender Classification using Convolutional Neural Networks》。

Paper所用的网络包含:3个卷积层,还有2个全连接层。这个算是层数比较少的CNN网络模型了,这样可以避免过拟合。对于年龄的识别,paper仅仅有8个年龄段,相当于8分类模型,对于性别识别自然而然是二分类问题了。

首先上Model Zoo下载年龄和性别的caffe模型及其描述文件,下载网址https://talhassner.github.io/home/publication/2015_CVPR

步骤:

  1. 加载模型文件和描述文件
  2. 列出分类的标签文件
  3. 人脸检测,将脸部图像转换为网络输入的格式
  4. 网络输入
  5. 前向传播
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace dnn;
using namespace std;

String age_model = "age_net.caffemodel";
String age_txt = "deploy_age.prototxt";
String gender_model = "gender_net.caffemodel";
String gender_txt = "deploy_gender.prototxt";
String haar_xml = "haarcascade_frontalface_alt.xml";

void predict_age(Net &net, Mat &image);
void predict_gender(Net &net, Mat &image);

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;
}
vector<String> ages = ageLabels();

int main(int arc, char** argv) { 
	Mat src = imread("1.jpg");
	
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);
	
	CascadeClassifier detector;
	detector.load(haar_xml);
	vector<Rect>faces;
	Mat gray;
	cvtColor(src, gray, CV_BGR2GRAY);
	detector.detectMultiScale(gray, faces, 1.02, 3, 0, Size(30, 30));
	//读入模型文件和描述文件
	Net age_net = readNetFromCaffe(age_txt, age_model);
	Net gender_net = readNetFromCaffe(gender_txt, gender_model);
	for (int i = 0; i < faces.size(); i++) {
		rectangle(src, faces[i], Scalar(0, 255, 0), 2);
		predict_age(age_net, src(faces[i]));
		predict_gender(gender_net, src(faces[i]));
	}
	imshow("output", src);
	waitKey(0);
	return 0;
}
void predict_age(Net &net, Mat &image) {
	//将图像转化为网络输入的格式
	Mat blob = blobFromImage(image, 1.0, Size(227, 227));
	//输入
	net.setInput(blob,"data");
	//前向传播
	Mat prob = net.forward("prob");
	Point classNum;
	double classProb;
	minMaxLoc(prob, NULL, &classProb, NULL, &classNum);	
	putText(image, format("%s", ages.at(classNum.x).c_str()), Point(2, 15), FONT_HERSHEY_PLAIN, 1, Scalar( 0, 0, 255), 1);
}

void predict_gender(Net &net, Mat &image) {
	Mat blob = blobFromImage(image, 1.0, Size(227, 227));
	net.setInput(blob, "data");
	Mat prob = net.forward("prob");
	Point classNum;
	double classProb;
	putText(image, format("%s",(prob.at<float>(0,0)>prob.at<float>(0, 1)? "female":"male")), Point(2, 25), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255), 1);
}

猜你喜欢

转载自blog.csdn.net/qq_24946843/article/details/82861732