-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathface.cpp
More file actions
124 lines (96 loc) · 3.53 KB
/
face.cpp
File metadata and controls
124 lines (96 loc) · 3.53 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
/////////////////////////////////////////////////////////////////////////////
//
// COMS30121 - face.cpp
//
/////////////////////////////////////////////////////////////////////////////
// header inclusion
// header inclusion
#include <stdio.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using namespace cv;
/** Function Headers */
void detectAndDisplay( Mat frame , string filename);
bool checkMatch(string topleftx, string toplefty, string bottomrightx, string bottomrighty, std::vector<Rect> face);
void calcF1(std::vector<Rect> faces, string csv);
/** Global variables */
String cascade_name = "cascade.xml";
CascadeClassifier cascade;
/** @function main */
int main( int argc, const char** argv ) {
// 1. Read Input Image
Mat frame = imread(argv[1], CV_LOAD_IMAGE_COLOR);
// 2. Load the Strong Classifier in a structure called `Cascade'
if( !cascade.load( cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
// 3. Detect Faces and Display Result
detectAndDisplay( frame , argv[1]);
// 4. Save Result Image
imwrite( "output.jpg", frame );
return 0;
}
/** @function detectAndDisplay */
void detectAndDisplay( Mat frame , string filename) {
std::vector<Rect> faces;
Mat frame_gray;
// 1. Prepare Image by turning it into Grayscale and normalising lighting
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
// 2. Perform Viola-Jones Object Detection
cascade.detectMultiScale( frame_gray, faces, 1.1, 1, 0|CV_HAAR_SCALE_IMAGE, Size(50, 50), Size(500,500) );
// 3. Print number of Faces found
std::cout << faces.size() << std::endl;
// 4. Draw box around faces found
for( int i = 0; i < faces.size(); i++ ) {
rectangle(frame, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar( 0, 255, 0 ), 2);
}
calcF1(faces, filename);
}
bool checkMatch(string topleftx, string toplefty, string bottomrightx, string bottomrighty, Rect face) {
if (abs(stoi(topleftx) - face.x) < 50 && abs(stoi(toplefty) - face.y) < 50 \
&& abs(stoi(bottomrightx) - (face.x + face.width)) < 50 && abs(stoi(bottomrighty) - (face.y + face.height)) < 50) {
return true;
} else {
return false;
}
}
void calcF1(std::vector<Rect> faces, string csv) {
string subname = csv.substr(10, csv.size() - 14);
string csvname = subname + "coords.csv";
ifstream ip(csvname);
if(!ip.is_open()) std::cout << "Error; File Open" << '\n';
string topleftx;
string toplefty;
string bottomrightx;
string bottomrighty;
double numfaces = 0;
double truepositives = 0;
double falsenegatives = 0;
double falsepositives = 0;
while(ip.good()) {
getline(ip, topleftx, ',');
getline(ip, toplefty, ',');
getline(ip, bottomrightx, ',');
getline(ip, bottomrighty, '\n');
if (ip.eof()) break;
numfaces++;
for (int i = 0; i < faces.size(); i++) {
if (checkMatch(topleftx, toplefty, bottomrightx, bottomrighty, faces[i])) {
truepositives++;
}
}
}
falsepositives = faces.size() - truepositives;
falsenegatives = numfaces - truepositives;
double f1score = 2*truepositives/(2*truepositives + falsenegatives + falsepositives);
cout << "True number of faces: " << numfaces << endl << "True Positives: " \
<< truepositives << endl << "TPR: " << truepositives/numfaces << endl \
<< "F1 Score: " << f1score << endl;
ip.close();
}