1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Author: Samyak Datta (datta[dot]samyak[at]gmail.com) 3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * A program to detect facial feature points using 5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Haarcascade classifiers for face, eyes, nose and mouth 6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "opencv2/objdetect/objdetect.hpp" 10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "opencv2/highgui/highgui.hpp" 11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "opencv2/imgproc/imgproc.hpp" 12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <iostream> 14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <cstdio> 15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <vector> 16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <algorithm> 17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace std; 19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace cv; 20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Functions to parse command-line arguments 22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic string getCommandOption(const vector<string>&, const string&); 23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void setCommandOptions(vector<string>&, int, char**); 24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool doesCmdOptionExist(const vector<string>& , const string&); 25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Functions for facial feature detection 27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void help(); 28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectFaces(Mat&, vector<Rect_<int> >&, string); 29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectEyes(Mat&, vector<Rect_<int> >&, string); 30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectNose(Mat&, vector<Rect_<int> >&, string); 31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectMouth(Mat&, vector<Rect_<int> >&, string); 32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectFacialFeaures(Mat&, const vector<Rect_<int> >, string, string, string); 33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstring input_image_path; 35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstring face_cascade_path, eye_cascade_path, nose_cascade_path, mouth_cascade_path; 36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint main(int argc, char** argv) 38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(argc < 3) 40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler help(); 42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 1; 43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Extract command-line options 46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<string> args; 47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler setCommandOptions(args, argc, argv); 48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler input_image_path = argv[1]; 50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler face_cascade_path = argv[2]; 51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler eye_cascade_path = (doesCmdOptionExist(args, "-eyes")) ? getCommandOption(args, "-eyes") : ""; 52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nose_cascade_path = (doesCmdOptionExist(args, "-nose")) ? getCommandOption(args, "-nose") : ""; 53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mouth_cascade_path = (doesCmdOptionExist(args, "-mouth")) ? getCommandOption(args, "-mouth") : ""; 54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Load image and cascade classifier files 56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat image; 57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler image = imread(input_image_path); 58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Detect faces and facial features 60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<Rect_<int> > faces; 61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detectFaces(image, faces, face_cascade_path); 62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detectFacialFeaures(image, faces, eye_cascade_path, nose_cascade_path, mouth_cascade_path); 63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler imshow("Result", image); 65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler waitKey(0); 67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid setCommandOptions(vector<string>& args, int argc, char** argv) 71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 1; i < argc; ++i) 73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler args.push_back(argv[i]); 75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstring getCommandOption(const vector<string>& args, const string& opt) 80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler string answer; 82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<string>::const_iterator it = find(args.begin(), args.end(), opt); 83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(it != args.end() && (++it != args.end())) 84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler answer = *it; 85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return answer; 86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool doesCmdOptionExist(const vector<string>& args, const string& opt) 89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<string>::const_iterator it = find(args.begin(), args.end(), opt); 91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return (it != args.end()); 92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void help() 95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cout << "\nThis file demonstrates facial feature points detection using Haarcascade classifiers.\n" 97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "The program detects a face and eyes, nose and mouth inside the face." 98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "The code has been tested on the Japanese Female Facial Expression (JAFFE) database and found" 99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "to give reasonably accurate results. \n"; 100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cout << "\nUSAGE: ./cpp-example-facial_features [IMAGE] [FACE_CASCADE] [OPTIONS]\n" 102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "IMAGE\n\tPath to the image of a face taken as input.\n" 103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "FACE_CASCSDE\n\t Path to a haarcascade classifier for face detection.\n" 104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "OPTIONS: \nThere are 3 options available which are described in detail. There must be a " 105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "space between the option and it's argument (All three options accept arguments).\n" 106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "\t-eyes : Specify the haarcascade classifier for eye detection.\n" 107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "\t-nose : Specify the haarcascade classifier for nose detection.\n" 108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "\t-mouth : Specify the haarcascade classifier for mouth detection.\n"; 109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cout << "EXAMPLE:\n" 112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "(1) ./cpp-example-facial_features image.jpg face.xml -eyes eyes.xml -mouth mouth.xml\n" 113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "\tThis will detect the face, eyes and mouth in image.jpg.\n" 114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "(2) ./cpp-example-facial_features image.jpg face.xml -nose nose.xml\n" 115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "\tThis will detect the face and nose in image.jpg.\n" 116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "(3) ./cpp-example-facial_features image.jpg face.xml\n" 117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "\tThis will detect only the face in image.jpg.\n"; 118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cout << " \n\nThe classifiers for face and eyes can be downloaded from : " 120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler " \nhttps://github.com/Itseez/opencv/tree/master/data/haarcascades"; 121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cout << "\n\nThe classifiers for nose and mouth can be downloaded from : " 123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler " \nhttps://github.com/Itseez/opencv_contrib/tree/master/modules/face/data/cascades\n"; 124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectFaces(Mat& img, vector<Rect_<int> >& faces, string cascade_path) 127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CascadeClassifier face_cascade; 129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler face_cascade.load(cascade_path); 130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler face_cascade.detectMultiScale(img, faces, 1.15, 3, 0|CASCADE_SCALE_IMAGE, Size(30, 30)); 132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectFacialFeaures(Mat& img, const vector<Rect_<int> > faces, string eye_cascade, 136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler string nose_cascade, string mouth_cascade) 137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(unsigned int i = 0; i < faces.size(); ++i) 139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Mark the bounding box enclosing the face 141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Rect face = faces[i]; 142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rectangle(img, Point(face.x, face.y), Point(face.x+face.width, face.y+face.height), 143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Scalar(255, 0, 0), 1, 4); 144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Eyes, nose and mouth will be detected inside the face (region of interest) 146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat ROI = img(Rect(face.x, face.y, face.width, face.height)); 147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Check if all features (eyes, nose and mouth) are being detected 149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bool is_full_detection = false; 150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (!eye_cascade.empty()) && (!nose_cascade.empty()) && (!mouth_cascade.empty()) ) 151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is_full_detection = true; 152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Detect eyes if classifier provided by the user 154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(!eye_cascade.empty()) 155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<Rect_<int> > eyes; 157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detectEyes(ROI, eyes, eye_cascade); 158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Mark points corresponding to the centre of the eyes 160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(unsigned int j = 0; j < eyes.size(); ++j) 161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Rect e = eyes[j]; 163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler circle(ROI, Point(e.x+e.width/2, e.y+e.height/2), 3, Scalar(0, 255, 0), -1, 8); 164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* rectangle(ROI, Point(e.x, e.y), Point(e.x+e.width, e.y+e.height), 165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Scalar(0, 255, 0), 1, 4); */ 166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Detect nose if classifier provided by the user 170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler double nose_center_height = 0.0; 171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(!nose_cascade.empty()) 172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<Rect_<int> > nose; 174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detectNose(ROI, nose, nose_cascade); 175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Mark points corresponding to the centre (tip) of the nose 177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(unsigned int j = 0; j < nose.size(); ++j) 178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Rect n = nose[j]; 180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler circle(ROI, Point(n.x+n.width/2, n.y+n.height/2), 3, Scalar(0, 255, 0), -1, 8); 181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nose_center_height = (n.y + n.height/2); 182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Detect mouth if classifier provided by the user 186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler double mouth_center_height = 0.0; 187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(!mouth_cascade.empty()) 188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler vector<Rect_<int> > mouth; 190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler detectMouth(ROI, mouth, mouth_cascade); 191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(unsigned int j = 0; j < mouth.size(); ++j) 193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Rect m = mouth[j]; 195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mouth_center_height = (m.y + m.height/2); 196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // The mouth should lie below the nose 198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (is_full_detection) && (mouth_center_height > nose_center_height) ) 199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rectangle(ROI, Point(m.x, m.y), Point(m.x+m.width, m.y+m.height), Scalar(0, 255, 0), 1, 4); 201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if( (is_full_detection) && (mouth_center_height <= nose_center_height) ) 203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler rectangle(ROI, Point(m.x, m.y), Point(m.x+m.width, m.y+m.height), Scalar(0, 255, 0), 1, 4); 206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectEyes(Mat& img, vector<Rect_<int> >& eyes, string cascade_path) 215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CascadeClassifier eyes_cascade; 217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler eyes_cascade.load(cascade_path); 218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler eyes_cascade.detectMultiScale(img, eyes, 1.20, 5, 0|CASCADE_SCALE_IMAGE, Size(30, 30)); 220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectNose(Mat& img, vector<Rect_<int> >& nose, string cascade_path) 224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CascadeClassifier nose_cascade; 226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nose_cascade.load(cascade_path); 227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nose_cascade.detectMultiScale(img, nose, 1.20, 5, 0|CASCADE_SCALE_IMAGE, Size(30, 30)); 229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void detectMouth(Mat& img, vector<Rect_<int> >& mouth, string cascade_path) 233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CascadeClassifier mouth_cascade; 235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mouth_cascade.load(cascade_path); 236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mouth_cascade.detectMultiScale(img, mouth, 1.20, 5, 0|CASCADE_SCALE_IMAGE, Size(30, 30)); 238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 240