Opencv3.3版本以上使用CNN模型实现年龄和性别检测

环境:

1、安装opencv3.3以上,因为3.3以上才有dnn模块。目前opencv已经更新到opencv4.0.0-alpha,下面网站对更新日志一目了然:

https://github.com/opencv/opencv/wiki/ChangeLog#version400

2、如果是window系统最好安装vs2015或者vs2017,因为vs2013已经不支持vc14,具体怎么搭建环境就不说了,网上一大把。当然在Ubuntu上也可以,并且实现起来更流畅。

模型:

下载地址:https://talhassner.github.io/home/publication/2015_CVPR

代码:

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>

using namespace cv;
using namespace cv::dnn;
using namespace std;
String haar_file = "E:/opencv/opencv3.4.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt_tree.xml";
String age_model = "E:/opencv/opencv3.4.1/opencv/sources/samples/data/dnn/age_gender/age_net.caffemodel";
String age_text = "E:/opencv/opencv3.4.1/opencv/sources/samples/data/dnn/age_gender/deploy_age.prototxt";

String gender_model = "E:/opencv/opencv3.4.1/opencv/sources/samples/data/dnn/age_gender/gender_net.caffemodel";
String gender_text = "E:/opencv/opencv3.4.1/opencv/sources/samples/data/dnn/age_gender/deploy_gender.prototxt";

void predict_age(Net &net, Mat &image);
void predict_gender(Net &net, Mat &image);
int main(int argc, char** argv) {
	Mat src = imread("E:/opencv/opencv3.4.1/opencv/sources/samples/data/timg.jpg");
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", 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(200, 200));

	Net age_net = readNetFromCaffe(age_text, age_model);
	Net gender_net = readNetFromCaffe(gender_text, gender_model);

	for (size_t t = 0; t < faces.size(); t++) {
		rectangle(src, faces[t], Scalar(30, 255, 30), 2, 8, 0);
		predict_age(age_net, src(faces[t]));
		predict_gender(age_net, src(faces[t]));
	}
	imshow("age-gender-prediction-demo", src);

	waitKey(0);
	return 0;
}

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;
}

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");
	Mat probMat = prob.reshape(1, 1);
	Point classNum;
	double classProb;

	vector<String> ages = ageLabels();
	minMaxLoc(probMat, NULL, &classProb, NULL, &classNum);
	int classidx = classNum.x;
	putText(image, format("age:%s", ages.at(classidx).c_str()), Point(2, 10), FONT_HERSHEY_PLAIN, 0.8, 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");
	Mat probMat = prob.reshape(1, 1);
	putText(image, format("gender:%s", (probMat.at<float>(0, 0) > probMat.at<float>(0, 1) ? "M" : "F")),
		Point(2, 20), FONT_HERSHEY_PLAIN, 0.8, Scalar(0, 0, 255), 1);
}

 测试结果:

猜你喜欢

转载自blog.csdn.net/hunzhangzui9837/article/details/82840072