Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HCI Practical Assignment 1 #10

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ source_group("" FILES ${INCLUDE} ${SOURCES} ${HEADERS})
source_group("Source Files" FILES "src/main.cpp")

# OpenCV package
find_package(OpenCV 4.0 REQUIRED core highgui imgproc imgcodecs PATHS "$ENV{OPENCVDIR}/build")
find_package(OpenCV 4.0 REQUIRED core highgui imgproc imgcodecs PATHS "$ENV{OPENCV_DIR}/build")

# Turn on the ability to create folders to organize projects (.vcproj)
# It creates "CMakePredefinedTargets" folder by default and adds CMake defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
**Dealine**: 27.09.2021

Please put your name here:
**Name:** .......
**Name:** Clichici Calin
## Problem 1.1
### Calculate Frames-per-Second (FPS) (Points 30)
1. Fork the current repository
Expand All @@ -13,6 +13,10 @@ Please put your name here:
### Note
MacOS users may need to launch the application with the administrator rights, to grant access to the web-camera.

**Solution:**
The FPS varies from 17 FPS to 25 FPS during runtime, with a total average of 24.54 FPS at the end.


## Problem 1.2
### Face detection (Points 70)
1. Read the OpenCV documentation about Viola-Jones face detector: [Cascade Classifier](https://docs.opencv.org/4.2.0/db/d28/tutorial_cascade_classifier.html)
Expand All @@ -21,6 +25,9 @@ MacOS users may need to launch the application with the administrator rights, to
### Note
Please do not copy-paste the example code from the OpenCV documentation, but try to understand the example code and implement the solution to the problem by yourself.

**Solution:**
The implemented face detection algorithm as explained by the OpenCV documentation resulted in a heavy decline in FPS, now averaging between 1 FPS and 3 FPS during runtime, with a total average of 2.49 FPS at the end. Overall, it is a 90% reduction in performance.

## Submission
Please submit the assignment by making a pull request.
**Important** : Please make sure that
Expand Down
128 changes: 126 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,144 @@
#include "types.h"
#include <time.h>>
#include <chrono>

int main() {
Mat detect(Mat img);

using namespace cv;

CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;

int main(int argc, const char** argv) {

// Set up parser
CommandLineParser parser(argc, argv,
"{help h||}"
"{face_cascade|data/haarcascades/haarcascade_frontalface_alt.xml|Path to face cascade.}"
"{eyes_cascade|data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|Path to eyes cascade.}"
"{camera|0|Camera device number.}");

parser.about("\nThis program demonstrates using the cv::CascadeClassifier class to detect objects (Face + eyes) in a video stream.\n"
"You can use Haar or LBP features.\n\n");
parser.printMessage();

// Set up cascades
String face_cascade_name = samples::findFile(parser.get<String>("face_cascade"));
String eyes_cascade_name = samples::findFile(parser.get<String>("eyes_cascade"));

// Load the cascades
if (!face_cascade.load(face_cascade_name))
{
std::cout << "--(!)Error loading face cascade\n";
return -1;
};
if (!eyes_cascade.load(eyes_cascade_name))
{
std::cout << "--(!)Error loading eyes cascade\n";
return -1;
};

// Check if camera is available
VideoCapture camera;
if (!camera.open(0)) {
printf("Can't find a camera\n");
return 1;
};

// Number of frames to capture
int num_frames = 1;
double fps;

// Start and end times for FPS estimation
time_t start, end;

// Start and end timers for elapsed time estiamtion
time_t timerStart, timerEnd;

// Main loop
Mat img;
for(;;) {

// Start timer for elapsed time estimation
timerStart = clock();
for(;;)
{
// Start clock for FPS estimation
// Happens before image processing begins
start = clock();

// Get image from camera
camera >> img;

// Detect face and draw recognition
img = detect(img);

// Show the image with facial regonition features
imshow("Camera", img);

// End clock for FPS estimation
// Happens after image processing ends
end = clock();

// Detect quit key
int key = waitKey(5);
if (key == 27 || key == 'q') break;

// Calculate number of seconds elapsed during image processing
double seconds = (double(end) - double(start)) / double(CLOCKS_PER_SEC);

// Calculate average FPS
fps = double(num_frames) / double(seconds);

// Take current clock value
timerEnd = clock();

// Recalculate number of seconds to estimate elapsed time so far
seconds = (double(timerEnd) - double(timerStart)) / double(CLOCKS_PER_SEC);

// If elapsed time greater than 2 seconds, print FPS and reset timer
if (seconds >+ 2)
{
timerStart = clock();
std::cout << "Average FPS: " << fps << "\n";
}
}

camera.release();
return 0;
}

// Function to detect face and eyes
Mat detect(Mat img)
{
// Initialize blank mat for gray image
Mat img_gray;
cvtColor(img, img_gray, COLOR_BGR2GRAY);
equalizeHist(img_gray, img_gray);

// Initialize vector for faces
std::vector<Rect> faces;
face_cascade.detectMultiScale(img_gray, faces);

// Process and recognize face and eyes
for (size_t i = 0; i < faces.size(); i++)
{
Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
ellipse(img, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4);

Mat faceROI = img_gray(faces[i]);

// In each face, detect eyes
std::vector<Rect> eyes;
eyes_cascade.detectMultiScale(faceROI, eyes);

for (size_t j = 0; j < eyes.size(); j++)
{
Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
int radius = cvRound((eyes[j].width + eyes[j].height) * 0.25);
circle(img, eye_center, radius, Scalar(255, 0, 0), 4);
}
}

// Return image with detection circles
return img;
}