-
Notifications
You must be signed in to change notification settings - Fork 0
/
AgeGender.cpp
112 lines (91 loc) · 4.35 KB
/
AgeGender.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/dnn.hpp>
#include <tuple>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <iterator>
using namespace cv;
using namespace cv::dnn;
using namespace std;
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, 0, 255));
}
}
return make_tuple(frameOpenCVDNN, bboxes);
}
int main(int argc, char** argv)
{
cv::Mat frame;
int padding = 20;
const char* imagepath = argv[1];
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"};
// get picture
if (argc != 2){
fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);
return -1;
}
frame = cv::imread(imagepath, 1);
if(frame.empty()){
fprintf(stderr, "cv::imread %s failed\n", imagepath);
return -1;
}
// Load Network
Net ageNet = readNet("age_net.caffemodel", "age_deploy.prototxt");
Net genderNet = readNet("gender_net.caffemodel", "gender_deploy.prototxt");
Net faceNet = readNet("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt");
vector<vector<int>> bboxes;
Mat frameFace;
tie(frameFace, bboxes) = getFaceBox(faceNet, frame, 0.7);
if(bboxes.size()==0){
cout << "No face detected, checking next frame." << endl;
}
else{
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);
if(rec.x>=0 && rec.y>=0 && (rec.width+rec.x)<=frame.cols && (rec.height+rec.y)<=frame.rows){
Mat face = frame(rec); // take the ROI of box on the frame
Mat blob = blobFromImage(face, 1, Size(227, 227), MODEL_MEAN_VALUES, false);
genderNet.setInput(blob);
vector<float> genderPreds = genderNet.forward();
// find max element index (distance function does the argmax() work in C++)
int max_index_gender = std::distance(genderPreds.begin(), max_element(genderPreds.begin(), genderPreds.end()));
string gender = genderList[max_index_gender];
ageNet.setInput(blob);
vector<float> agePreds = ageNet.forward();
// finding maximum indicd in the age_preds vector
int max_indice_age = std::distance(agePreds.begin(), max_element(agePreds.begin(), agePreds.end()));
string age = ageList[max_indice_age];
cout << "Gender: " << gender << " Age: " << age << endl;
string label = gender + ", " + age; // label
cv::putText(frameFace, label, Point(it->at(0), it->at(1) -15), cv::FONT_HERSHEY_SIMPLEX, 0.7, Scalar(0, 255, 255));
}
}
imwrite("out.jpg",frameFace);
}
}