From 514237113fd689e181adad29312a34d9919fbd78 Mon Sep 17 00:00:00 2001 From: youssef Shaban <85808789+youssef-shaban@users.noreply.github.com> Date: Thu, 11 May 2023 22:32:21 +0300 Subject: [PATCH] adding face recognition class --- CV-Toolbox.pro | 16 ++++----- CV/face_recognition.cpp | 78 +++++++++++++++++++++++++++++++++++------ CV/face_recognition.h | 14 ++++++-- CV/faces_detection.cpp | 2 +- CV/faces_detection.h | 1 + pages/mainwindow.h | 2 -- pages/page11.h | 1 - resources.qrc | 1 + 8 files changed, 91 insertions(+), 24 deletions(-) diff --git a/CV-Toolbox.pro b/CV-Toolbox.pro index 609cf2d..549f041 100644 --- a/CV-Toolbox.pro +++ b/CV-Toolbox.pro @@ -85,15 +85,15 @@ FORMS += \ -INCLUDEPATH += C:\opencv\build\include +INCLUDEPATH += C:\Users\youss\Documents\libraries\opencv\build\include -LIBS += C:\opencv\release\bin\libopencv_core470.dll -LIBS += C:\opencv\release\bin\libopencv_highgui470.dll -LIBS += C:\opencv\release\bin\libopencv_imgcodecs470.dll -LIBS += C:\opencv\release\bin\libopencv_imgproc470.dll -LIBS += C:\opencv\release\bin\libopencv_features2d470.dll -LIBS += C:\opencv\release\bin\libopencv_calib3d470.dll -LIBS += C:\opencv\release\bin\libopencv_objdetect470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_core470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_highgui470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_imgcodecs470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_imgproc470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_features2d470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_calib3d470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_objdetect470.dll # Default rules for deployment. diff --git a/CV/face_recognition.cpp b/CV/face_recognition.cpp index d9d6eff..9e05763 100644 --- a/CV/face_recognition.cpp +++ b/CV/face_recognition.cpp @@ -1,6 +1,49 @@ #include "face_recognition.h" -void face_recognition:: performPCA(cv::Mat& dataPoints, cv::Mat& eigenvalues, cv::Mat& eigenvectors, cv:: Mat& convertedData,int numComponents) +void face_recognition::setModel(std::string filePath, cv::Mat images, std::vector labels) +{ + cv::FileStorage fs(filePath, cv::FileStorage::READ); + fs["eigenValues"] >> eigenValues; + fs["eigenVectors"] >> eigenVectors; + fs.release(); + this->labels = labels; + this->images = images; + cv::Mat tempVectors = eigenVectors.rowRange(0, this->n_component); + multiplyEigen(tempVectors, images, this->transformedImages); + +} + +void face_recognition::train(cv::Mat images, std::vector labels) +{ + performPCA(images); + this->labels = labels; + this->images = images; + cv::Mat tempVectors = eigenVectors.rowRange(0, this->n_component); + multiplyEigen(tempVectors, images, this->transformedImages); + +} + +void face_recognition::setNComponent(int n_component) +{ + this->n_component = n_component; + cv::Mat tempVectors = eigenVectors.rowRange(0, this->n_component); + multiplyEigen(tempVectors, this->images, this->transformedImages); +} + +std::string face_recognition::getPerson(cv::Mat image) +{ + + cv::Mat reshapedImage = image.reshape(1, 1); + reshapedImage.convertTo(reshapedImage, CV_32F); + cv::Mat tempEigen = eigenVectors.rowRange(0, n_component); + cv::Mat output; + multiplyEigen(tempEigen, reshapedImage, output); + return labels[getNearest(this->transformedImages, output)]; + + +} + +void face_recognition:: performPCA(cv::Mat& dataPoints) { cv::Mat mean; cv::reduce(dataPoints, mean, 0, cv::REDUCE_AVG); @@ -11,16 +54,31 @@ void face_recognition:: performPCA(cv::Mat& dataPoints, cv::Mat& eigenvalues, cv cv::Mat covariance; cv::mulTransposed(dataPoints, covariance, true); covariance = covariance / (dataPoints.rows - 1); - cv::eigen(covariance, eigenvalues, eigenvectors); - eigenvalues=eigenvalues.rowRange(0, numComponents); - eigenvectors = eigenvectors.rowRange(0, numComponents); - convertedData = dataPoints * eigenvectors.t(); + cv::eigen(covariance, this->eigenValues, this->eigenVectors); + + + } -void face_recognition:: multiplyEigen(cv::Mat& eigenvectors, cv::Mat& image, cv::Mat& result) +void face_recognition:: multiplyEigen(cv::Mat& eigenvectors, cv::Mat& images, cv::Mat& result) { - cv::Mat reshapedImage = image.reshape(1, 1); - cv::Mat floatImage; - reshapedImage.convertTo(floatImage, CV_32F); - result = floatImage * eigenvectors.t(); + + result = images * eigenvectors.t(); +} + +int face_recognition::getNearest(cv::Mat images, cv::Mat image) { + cv::Mat distances= cv::Mat(images.rows, 1, CV_32F); + + for (int row = 0; row < images.rows; row++) { + double distance = 0; + for (int col = 0; col < images.cols; col++) { + distance += (images.at(row, col) - image.at(col)) * (images.at(row, col) - image.at(col)); + } + distances.at(row) = distance; + } + + double minValue; + cv::Point minLocation; + cv::minMaxLoc(distances, &minValue, nullptr, &minLocation, nullptr); + return minLocation.y; } diff --git a/CV/face_recognition.h b/CV/face_recognition.h index 5694e35..46c1cb4 100644 --- a/CV/face_recognition.h +++ b/CV/face_recognition.h @@ -10,9 +10,19 @@ class face_recognition { public: face_recognition(); + void setModel(std::string filePath, cv::Mat images, std::vector labels); + void train(cv::Mat images, std::vector labels); + void setNComponent(int n_component); + std::string getPerson(cv::Mat image); + private: - void performPCA(cv::Mat& dataPoints, cv::Mat& eigenvalues, cv::Mat& eigenvectors, cv:: Mat& convertedData,int numComponents); - void multiplyEigen(cv::Mat& eigenvectors, cv::Mat& image, cv::Mat& result); + void performPCA(cv::Mat& dataPoints); + void multiplyEigen(cv::Mat& eigenvectors,cv::Mat& images, cv::Mat& result); + int getNearest(cv::Mat images, cv::Mat image); + cv::Mat eigenValues, eigenVectors, transformedImages, images; + std::vector labels; + int n_component = 100; + }; diff --git a/CV/faces_detection.cpp b/CV/faces_detection.cpp index ee9c29a..32ed3c5 100644 --- a/CV/faces_detection.cpp +++ b/CV/faces_detection.cpp @@ -7,7 +7,7 @@ void faces_detection::detect_faces(cv::Mat& inputImage, cv::Mat& outputImage, bo { // Load the cascade classifier cv::CascadeClassifier face_cascade; - face_cascade.load("C://Users/kamel/OneDrive/Documents/GitKraken/CV-Toolbox/models/haarcascade_frontalface_default.xml"); + face_cascade.load("D:\\Projects\\CV\\Cv-Toolbox\\models\\haarcascade_frontalface_default.xml"); cv::Mat gray; cvtColor(inputImage, gray, cv::COLOR_BGR2GRAY); diff --git a/CV/faces_detection.h b/CV/faces_detection.h index af961b0..6cee092 100644 --- a/CV/faces_detection.h +++ b/CV/faces_detection.h @@ -4,6 +4,7 @@ #include #include #include +#include class faces_detection { diff --git a/pages/mainwindow.h b/pages/mainwindow.h index 1cf3bc0..ddf8825 100644 --- a/pages/mainwindow.h +++ b/pages/mainwindow.h @@ -33,8 +33,6 @@ class MainWindow : public QMainWindow ~MainWindow(); -private slots: - void on_pushButton_11_clicked(); private: Ui::MainWindow *ui; diff --git a/pages/page11.h b/pages/page11.h index a29baa7..12b14fe 100644 --- a/pages/page11.h +++ b/pages/page11.h @@ -20,7 +20,6 @@ class page11 : public QWidget private slots: void on_inputImageLabel_clicked(); - void on_outputImageLabel_clicked(); void on_applyButton_clicked(); diff --git a/resources.qrc b/resources.qrc index 1cfde10..471d004 100644 --- a/resources.qrc +++ b/resources.qrc @@ -6,6 +6,7 @@ resources/handpointing.png resources/textcursor.png style/Cstartpage.qss + models/haarcascade_frontalface_default.xml resources/icons8-upload-32.png