//This is our project #include <iostream> #include <string> #include <fstream> #include <sstream> #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/core/core.hpp" #include "opencv2/contrib/contrib.hpp" using namespace std; using namespace cv; Mat picture, picture_grayscale, face, face_grayscale; char key; int picture_height; int picture_width; int face_x, face_y, face_width, face_height; Rect face_dims; int num_subdirectories; vector<Mat> images; vector<int> labels; vector<Rect> faces; vector<string> users; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; /* * Currently loads any images from the directory "myfaces" * Subdirectories and images assumed to be labeled as an int, starting from 0, without breaks */ void read_images() { //empty the existing images and labels while (!images.empty()) { images.pop_back(); } while (!labels.empty()) { labels.pop_back(); } Mat load_image, load_image_grayscale; string filename = ""; string directory = "./myfaces/"; string subdirectory = ""; int j = 0; while (true) { subdirectory = to_string(j) + "/"; int i = 0; while (true) { filename = to_string(i); string path = directory + subdirectory + filename + ".png"; load_image = imread(path, 1); if (!load_image.data) { //No image data found - moving to next subdirectory cout << " No image data" << endl; break; } //Convert loaded images to grayscale load_image_grayscale = load_image.clone(); cvtColor(load_image, load_image_grayscale, CV_BGR2GRAY); //Add image to vector, along with the label for this subdirectory images.push_back(load_image_grayscale); labels.push_back(j); i++; } if (i == 0) { //No images in subdirectory/subdirectory does not exist num_subdirectories = j; break; } else { //Move to the next subdirectory j++; } } //Resize all images to first image size for (int i=0; i < images.size(); i++) { resize(images[i],images[i],images[0].size(),0,0, INTER_NEAREST ); } } void read_users() { string pathname = "./users.txt"; int user_label = 0; ifstream file(pathname.c_str(), ifstream::in); if (!file) { string error_message = "File pathname not valid."; CV_Error(CV_StsBadArg, error_message); } string line, name, classlabel; while (getline(file, line)) { stringstream liness(line); getline(liness, name); users.push_back(name); cout << "user " << user_label << ": " << name << endl; user_label++; } } int main() { //Starting the video VideoCapture videoCapture(0); if (!videoCapture.isOpened()) { cout << "Unable to open video file." << endl; return 1; } if (!face_cascade.load("haarcascade_frontalface_alt.xml")) { cout << "Error loading face cascade classifier." << endl; return -1; } if (!eyes_cascade.load("haarcascade_eye_tree_eyeglasses.xml")) { cout << "Error loading eye cascade classifier." << endl; return -1; } while(true) { Mat frame; videoCapture.retrieve(frame); bool success = videoCapture.read(frame); if (!success) { cout << "Could not read from video file" << endl; return 1; } //Get webcam image dimensions picture_width = frame.cols; picture_height = frame.rows; face_x = picture_width/3; face_y = picture_height/5; face_width = picture_width/3; face_height = 3 * face_y; Rect face_dims(face_x, face_y, face_width, face_height); face = frame(face_dims); //show some instructional text Mat frame_with_text = frame.clone(); putText(frame_with_text, "Press Spacebar to take a picture", Point2f(110,100), FONT_HERSHEY_SIMPLEX, 2.0, Scalar(255,0,0,0), 3); putText(frame_with_text, "Press ESC to close the application", Point2f(90,700), FONT_HERSHEY_SIMPLEX, 2.0, Scalar(0,0,255,255), 3); //Draw a rectangle where the picture will be taken Point a(face_x, face_y); Point b(face_x, face_y + face_height); Point c(face_x + face_width, face_y + face_height); Point d(face_x + face_width, face_y); line( frame_with_text, a, b, Scalar( 0, 0, 0 ),2, 8); line( frame_with_text, b, c, Scalar( 0, 0, 0 ),2, 8); line( frame_with_text, c, d, Scalar( 0, 0, 0 ),2, 8); line( frame_with_text, d, a, Scalar( 0, 0, 0 ),2, 8); imshow("Webcam", frame_with_text); key = waitKey(30); if (key == 27) { //escape key pressed: stop program cout << "ESC pressed. Program closing..." << endl; break; } else if (key == ' ') { //spacebar pressed: take a picture picture = frame; key = -1; //Convert to grayscale picture_grayscale = picture.clone(); cvtColor(picture, picture_grayscale, CV_BGR2GRAY); face_grayscale = face.clone(); cvtColor(face, face_grayscale, CV_BGR2GRAY); //Read saved images in myfaces read_images(); //Read users read_users(); //Check that images were read correctly cout << "Images read: " << images.size() << endl; cout << "Subdirectories: " << num_subdirectories << endl; //Resize to fit loaded images resize(face_grayscale, face_grayscale,images[0].size(),0,0, INTER_NEAREST ); //Generate FaceRecognizer - using FisherFace Ptr<FaceRecognizer> fisher_model = createFisherFaceRecognizer(); Ptr<FaceRecognizer> eigen_model = createEigenFaceRecognizer(); //using this FaceRecognizer to determine identity Ptr<FaceRecognizer> lbph_model = createLBPHFaceRecognizer(); //Feed FaceRecognizer with images and labels fisher_model->train(images, labels); eigen_model->train(images, labels); lbph_model->train(images, labels); cout << "Face Recognizer created" << endl; //Output predicted label - this will be the matched subject of the picture int fisher_predictedLabel = fisher_model->predict(face_grayscale); int eigen_predictedLabel = eigen_model->predict(face_grayscale); int lbph_predictedLabel = lbph_model->predict(face_grayscale); cout << "Fisher predicted label: " << fisher_predictedLabel << endl; cout << "Eigen predicted label: " << eigen_predictedLabel << " - " << users[eigen_predictedLabel] << endl; cout << "LBPH predicted label: " << lbph_predictedLabel << endl; while (true) { //Add instructions to the screen Mat picture_with_text = picture.clone(); putText(picture_with_text, "Press 's' to save", Point2f(375,100), FONT_HERSHEY_SIMPLEX, 2.0, Scalar(255,0,0,0), 3); putText(picture_with_text, "Predicted User: " + users[eigen_predictedLabel], Point2f(275,600), FONT_HERSHEY_SIMPLEX, 2.0, Scalar(255,0,0,0), 3); putText(picture_with_text, "Press ESC/Spacebar to return", Point2f(160,670), FONT_HERSHEY_SIMPLEX, 2.0, Scalar(0,0,255), 3); imshow("Webcam", picture_with_text); key = waitKey(30); if (key == 27 || key == 32) { //spacebar or ESC pressed cout << "ESC or SPACE pressed. Returning to video..." << endl; break; } else if (key == 115) { //"s" pressed - saving image string name; string directory = "./myfaces/"; cout << "Please select a name for the image." << endl; getline(cin, name); directory.append(name); directory.append(".png"); Point org; org.x = 15; org.y = 100; putText(picture_with_text, name, org, FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 3); bool maybe = imwrite(directory, face); cout << "s was pressed. saving image, success: " << maybe << endl; } } } } return 0; }