diff --git a/src/computervision/FaceDetector.cpp b/src/computervision/FaceDetector.cpp deleted file mode 100644 index a628983..0000000 --- a/src/computervision/FaceDetector.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "FaceDetector.h" - - -/* - Author: Pierfrancesco Soffritti https://github.com/PierfrancescoSoffritti -*/ -namespace computervision -{ - Rect getFaceRect(Mat input); - - String faceClassifierFileName = "res/haarcascade_frontalface_alt.xml"; - CascadeClassifier faceCascadeClassifier; - - FaceDetector::FaceDetector(void) { - if (!faceCascadeClassifier.load(faceClassifierFileName)) - throw runtime_error("can't load file " + faceClassifierFileName); - } - - void FaceDetector::removeFaces(Mat input, Mat output) { - vector faces; - Mat frameGray; - - cvtColor(input, frameGray, CV_BGR2GRAY); - equalizeHist(frameGray, frameGray); - - faceCascadeClassifier.detectMultiScale(frameGray, faces, 1.1, 2, 0 | 2, Size(120, 120)); // HAAR_SCALE_IMAGE is 2 - - for (size_t i = 0; i < faces.size(); i++) { - rectangle( - output, - Point(faces[i].x, faces[i].y), - Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), - Scalar(0, 0, 0), - -1 - ); - } - } - - Rect getFaceRect(Mat input) { - vector faceRectangles; - Mat inputGray; - - cvtColor(input, inputGray, CV_BGR2GRAY); - equalizeHist(inputGray, inputGray); - - faceCascadeClassifier.detectMultiScale(inputGray, faceRectangles, 1.1, 2, 0 | 2, Size(120, 120)); // HAAR_SCALE_IMAGE is 2 - - if (faceRectangles.size() > 0) - return faceRectangles[0]; - else - return Rect(0, 0, 1, 1); - } -} \ No newline at end of file diff --git a/src/computervision/FaceDetector.h b/src/computervision/FaceDetector.h deleted file mode 100644 index 208e051..0000000 --- a/src/computervision/FaceDetector.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -/* - Author: Pierfrancesco Soffritti https://github.com/PierfrancescoSoffritti -*/ - -using namespace cv; -using namespace std; - -namespace computervision -{ - class FaceDetector { - public: - /** - * @brief Constructor for the class FaceDetector, loads training data from a file - * - */ - FaceDetector(void); - /** - * @brief Detects faces on an image and blocks them with a black rectangle - * - * @param input Input image - * @param output Output image - */ - void removeFaces(Mat input, Mat output); - }; -} \ No newline at end of file diff --git a/src/computervision/HandPresentChecker.cpp b/src/computervision/HandPresentChecker.cpp deleted file mode 100644 index 31a9e00..0000000 --- a/src/computervision/HandPresentChecker.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "HandPresentChecker.h" -#include -#include - -#define MIN_HAND_SIZE 10000 - -namespace computervision -{ - bool check_if_hand_present(cv::Mat input_image) - { - std::vector> points; - cv::findContours(input_image, points, cv::RetrievalModes::RETR_LIST, cv::ContourApproximationModes::CHAIN_APPROX_SIMPLE); - - if (points.size() == 0) return false; - - for (int p = 0; p < points.size(); p++) - { - int area = cv::contourArea(points[p]); - if (area > MIN_HAND_SIZE) return true; - } - - return false; - } - -} diff --git a/src/computervision/ObjectDetection.cpp b/src/computervision/ObjectDetection.cpp index 5fcac46..669a229 100644 --- a/src/computervision/ObjectDetection.cpp +++ b/src/computervision/ObjectDetection.cpp @@ -6,23 +6,24 @@ #include "ObjectDetection.h" #include "BackgroundRemover.h" #include "SkinDetector.h" -#include "FaceDetector.h" #include "FingerCount.h" #include "async/StaticCameraInstance.h" -#include "HandPresentChecker.h" +#include "calibration/HandPresentChecker.h" +#include "calibration/HandCalibrator.h" namespace computervision { - cv::Mat img, imgGray, img2, img2Gray, img3, img4; + cv::Mat img, img_gray, img2, img2_gray, img3, img4; - int handMaskStartXPos, handMaskStartYPos, handMaskWidth, handMaskHeight; - bool handMaskGenerated = false; + int hand_mask_start_x_pos, hand_mask_start_y_pos, hand_mask_width, hand_mask_height; + bool hand_mask_generated = false; Mat frame, frame_out, handMask, foreground, fingerCountDebug; BackgroundRemover background_remover; SkinDetector skin_detector; FingerCount finger_count; + handcalibration::HandCalibrator hand_calibrator; cv::VideoCapture cap = static_camera::getCap(); @@ -46,7 +47,7 @@ namespace computervision frame_out = input_frame.clone(); // detect skin color - skin_detector.drawSkinColorSampler(frame_out); + skin_detector.drawSkinColorSampler(camera_frame); // remove background from image foreground = background_remover.getForeground(input_frame); @@ -63,7 +64,9 @@ namespace computervision // draw the hand rectangle on the camera input, and draw text showing if the hand is open or closed. DrawHandMask(&camera_frame); string hand_text = fingers_amount > 0 ? "open" : "closed"; - putText(camera_frame,hand_text, Point(10, 75), FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 255),3); + putText(camera_frame, hand_text, Point(10, 75), FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 255), 3); + + hand_calibrator.DrawHandCalibrationText(camera_frame); imshow("camera", camera_frame); //imshow("output", frame_out); @@ -71,16 +74,25 @@ namespace computervision //imshow("handMask", handMask); //imshow("handDetection", fingerCountDebug); - hand_present = CheckIfHandPresent(handMask); + hand_present = hand_calibrator.CheckIfHandPresent(handMask); + hand_calibrator.SetHandPresent(hand_present); int key = waitKey(1); if (key == 98) // b, calibrate the background + { background_remover.calibrate(input_frame); + hand_calibrator.SetBackGroundCalibrated(true); + } else if (key == 115) // s, calibrate the skin color + { skin_detector.calibrate(input_frame); + hand_calibrator.SetSkinCalibration(true); + + } + return fingers_amount > 0; } @@ -90,10 +102,10 @@ namespace computervision cap.read(img); cap.read(img2); - cv::cvtColor(img, imgGray, cv::COLOR_RGBA2GRAY); - cv::cvtColor(img2, img2Gray, cv::COLOR_RGBA2GRAY); + cv::cvtColor(img, img_gray, cv::COLOR_RGBA2GRAY); + cv::cvtColor(img2, img2_gray, cv::COLOR_RGBA2GRAY); - cv::absdiff(imgGray, img2Gray, img3); + cv::absdiff(img_gray, img2_gray, img3); cv::threshold(img3, img4, 50, 170, cv::THRESH_BINARY); imshow("threshold", img4); @@ -102,28 +114,28 @@ namespace computervision cv::Mat ObjectDetection::GenerateHandMaskSquare(cv::Mat img) { - handMaskStartXPos = 20; - handMaskStartYPos = img.rows / 5; - handMaskWidth = img.cols / 3; - handMaskHeight = img.cols / 3; + hand_mask_start_x_pos = 20; + hand_mask_start_y_pos = img.rows / 5; + hand_mask_width = img.cols / 3; + hand_mask_height = img.cols / 3; cv::Mat mask = cv::Mat::zeros(img.size(), img.type()); - cv::Mat dstImg = cv::Mat::zeros(img.size(), img.type()); + cv::Mat distance_img = cv::Mat::zeros(img.size(), img.type()); - cv::rectangle(mask, Rect(handMaskStartXPos, handMaskStartYPos, handMaskWidth, handMaskHeight), Scalar(255, 255, 255), -1); + cv::rectangle(mask, Rect(hand_mask_start_x_pos, hand_mask_start_y_pos, hand_mask_width, hand_mask_height), Scalar(255, 255, 255), -1); - img.copyTo(dstImg, mask); + img.copyTo(distance_img, mask); - handMaskGenerated = true; - return dstImg; + hand_mask_generated = true; + return distance_img; } bool ObjectDetection::DrawHandMask(cv::Mat* input) { - if (!handMaskGenerated) return false; - rectangle(*input, Rect(handMaskStartXPos, handMaskStartYPos, handMaskWidth, handMaskHeight), Scalar(255, 255, 255)); + if (!hand_mask_generated) return false; + rectangle(*input, Rect(hand_mask_start_x_pos, hand_mask_start_y_pos, hand_mask_width, hand_mask_height), Scalar(255, 255, 255)); return true; } diff --git a/src/computervision/ObjectDetection.h b/src/computervision/ObjectDetection.h index 5deeaa6..1b65e1f 100644 --- a/src/computervision/ObjectDetection.h +++ b/src/computervision/ObjectDetection.h @@ -27,13 +27,13 @@ namespace computervision * @brief Displays an image of the current webcam-footage * */ - void showWebcam(); + void ShowWebcam(); /** * @brief Calculates the difference between two images * and outputs an image that only shows the difference * */ - void calculateDifference(); + void CalculateDifference(); /** * @brief generates the square that will hold the mask in which the hand will be detected. @@ -41,14 +41,14 @@ namespace computervision * @param img the current camear frame * @return a matrix containing the mask */ - cv::Mat generateHandMaskSquare(cv::Mat img); + cv::Mat GenerateHandMaskSquare(cv::Mat img); /** * @brief reads the camera and returns it in a matrix. * * @return the camera frame in a matrix */ - cv::Mat readCamera(); + cv::Mat ReadCamera(); /** * @brief detects a hand based on the given hand mask input frame. @@ -57,17 +57,17 @@ namespace computervision * @param hand_present boolean that will hold true if the hand is detected, false if not. * @return true if hand is open, false if hand is closed */ - bool detectHand(cv::Mat cameraFrame, bool& hand_present); + bool DetectHand(cv::Mat camera_frame, bool& hand_present); /** * @brief draws the hand mask rectangle on the given input matrix. * * @param input the input matrix to draw the rectangle on */ - bool drawHandMaskRect(cv::Mat *input); + bool DrawHandMask(cv::Mat *input); - cv::VideoCapture getCap(); + cv::VideoCapture GetCap(); }; diff --git a/src/computervision/SkinDetector.cpp b/src/computervision/SkinDetector.cpp index 088cce0..971ff2a 100644 --- a/src/computervision/SkinDetector.cpp +++ b/src/computervision/SkinDetector.cpp @@ -23,7 +23,7 @@ namespace computervision int frameWidth = input.size().width, frameHeight = input.size().height; int rectangleSize = 25; - Scalar rectangleColor = Scalar(255, 0, 255); + Scalar rectangleColor = Scalar(0, 255, 255); skinColorSamplerRectangle1 = Rect(frameWidth / 5, frameHeight / 2, rectangleSize, rectangleSize); skinColorSamplerRectangle2 = Rect(frameWidth / 5, frameHeight / 3, rectangleSize, rectangleSize); diff --git a/src/computervision/async/async_arm_detection.cpp b/src/computervision/async/async_arm_detection.cpp index e9649a1..a43b7dc 100644 --- a/src/computervision/async/async_arm_detection.cpp +++ b/src/computervision/async/async_arm_detection.cpp @@ -17,7 +17,7 @@ namespace computervision VideoCapture cap = static_camera::getCap(); std::cout << "STARTING THREAD LAMBDA" << std::endl; - /*cv::VideoCapture cap = static_camera::getCap();*/ + /*cv::VideoCapture cap = static_camera::GetCap();*/ if (!cap.isOpened()) { diff --git a/src/computervision/calibration/HandCalibrator.cpp b/src/computervision/calibration/HandCalibrator.cpp new file mode 100644 index 0000000..9d91a46 --- /dev/null +++ b/src/computervision/calibration/HandCalibrator.cpp @@ -0,0 +1,68 @@ + +#include "HandCalibrator.h" + +#define MIN_HAND_SIZE 10000 +namespace computervision +{ + namespace handcalibration + { + + static bool background_calibrated; + static bool skintone_calibrated; + static bool hand_present; + + HandCalibrator::HandCalibrator() + { + + } + + void HandCalibrator::DrawHandCalibrationText(cv::Mat& output_frame) + { + cv::rectangle(output_frame,cv::Rect(0, 0, output_frame.cols, 40),cv::Scalar(0,0,0),-1); + cv::putText(output_frame, "Hand calibration", cv::Point(output_frame.cols/2-100, 25), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(18, 219, 65), 2); + cv::putText(output_frame, "press 'b' to calibrate background,then press 's' to calibrate skin tone", cv::Point(5, 35), cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(18, 219, 65), 1); + + cv::putText(output_frame, "hand in frame:", cv::Point(5, output_frame.rows - 50), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 0), 1); + cv::rectangle(output_frame, cv::Rect(270, output_frame.rows - 70, 20, 20), hand_present ? cv::Scalar(0, 255, 0) : cv::Scalar(0,0,255), -1); + + + cv::putText(output_frame, (background_calibrated ? "background calibrated" : "background not calibrated"), cv::Point(5, output_frame.rows-30), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 0), 1); + cv::putText(output_frame, (skintone_calibrated ? "skincolor calibrated" : "skincolor not calibrated"), cv::Point(5, output_frame.rows-10), cv::FONT_HERSHEY_PLAIN, 2.0, cv::Scalar(255, 255, 0), 1); + } + + void HandCalibrator::SetSkinCalibration(bool val) + { + skintone_calibrated = val; + } + + void HandCalibrator::SetBackGroundCalibrated(bool val) + { + background_calibrated = val; + } + + void HandCalibrator::SetHandPresent(bool val) + { + hand_present = val; + } + + bool HandCalibrator::CheckIfHandPresent(cv::Mat input_image) + { + std::vector> points; + cv::findContours(input_image, points, cv::RetrievalModes::RETR_LIST, cv::ContourApproximationModes::CHAIN_APPROX_SIMPLE); + + if (points.size() == 0) return false; + + for (int p = 0; p < points.size(); p++) + { + int area = cv::contourArea(points[p]); + if (area > MIN_HAND_SIZE) return true; + } + + return false; + } + + + + + } +} diff --git a/src/computervision/calibration/HandCalibrator.h b/src/computervision/calibration/HandCalibrator.h new file mode 100644 index 0000000..40fdd95 --- /dev/null +++ b/src/computervision/calibration/HandCalibrator.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include +#include + +namespace computervision +{ + namespace handcalibration + { + class HandCalibrator + { + public: + HandCalibrator(); + + /** + * @brief draws the text to show the status of the calibration on the image + * + * @param output_frame the frame to draw on. + */ + void DrawHandCalibrationText(cv::Mat& output_frame); + + /** + * @brief sets the skin calibration variable. + * + * @param val the value to set + */ + void SetSkinCalibration(bool val); + + /** + * @brief sets the background calibration variable. + * + * @param val the value to set + */ + void SetBackGroundCalibrated(bool val); + + bool CheckIfHandPresent(cv::Mat input_image); + + void SetHandPresent(bool val); + }; + + } +} diff --git a/src/computervision/calibration/HandPresentChecker.cpp b/src/computervision/calibration/HandPresentChecker.cpp new file mode 100644 index 0000000..194f6c9 --- /dev/null +++ b/src/computervision/calibration/HandPresentChecker.cpp @@ -0,0 +1,14 @@ +#include "HandPresentChecker.h" +#include +#include + + + +namespace computervision +{ + namespace handcalibration + { + + } + +} diff --git a/src/computervision/HandPresentChecker.h b/src/computervision/calibration/HandPresentChecker.h similarity index 100% rename from src/computervision/HandPresentChecker.h rename to src/computervision/calibration/HandPresentChecker.h diff --git a/src/scenes/startup_Scene.cpp b/src/scenes/startup_Scene.cpp index 3a990f1..e889139 100644 --- a/src/scenes/startup_Scene.cpp +++ b/src/scenes/startup_Scene.cpp @@ -31,7 +31,7 @@ namespace scene void scene::Startup_Scene::update(GLFWwindow* window) { bool hand_detected = false; - objDetect.detectHand(objDetect.readCamera(),hand_detected); + objDetect.DetectHand(objDetect.ReadCamera(),hand_detected); if (hand_detected) std::cout << "there's a hand!" << std::endl; } diff --git a/wk2_fps.vcxproj b/wk2_fps.vcxproj index f962a64..ba853d9 100644 --- a/wk2_fps.vcxproj +++ b/wk2_fps.vcxproj @@ -20,10 +20,10 @@ - + + - @@ -46,12 +46,12 @@ - + + - diff --git a/wk2_fps.vcxproj.filters b/wk2_fps.vcxproj.filters index a60c7ce..129165a 100644 --- a/wk2_fps.vcxproj.filters +++ b/wk2_fps.vcxproj.filters @@ -4,7 +4,6 @@ - @@ -23,7 +22,8 @@ - + + @@ -32,7 +32,6 @@ - @@ -55,7 +54,8 @@ - + +