[ADD] multiple hand detection squares

This commit is contained in:
Sem van der Hoeven
2021-06-08 13:17:07 +02:00
parent ef470bd4f1
commit 1e55736615
7 changed files with 238 additions and 9 deletions

View File

@@ -1,10 +1,105 @@
#include "HandDetectRegion.h" #include "HandDetectRegion.h"
namespace computervision namespace computervision
{ {
HandDetectRegion::HandDetectRegion()
HandDetectRegion::HandDetectRegion(std::string id,int x_pos, int y_pos, int width, int height)
{ {
region_id = id;
start_x_pos = x_pos;
start_y_pos = y_pos;
region_width = width;
region_height = height;
hand_mask_generated = false;
hand_present = false;
} }
void HandDetectRegion::DetectHand(cv::Mat& camera_frame)
{
Mat input_frame = GenerateHandMaskSquare(camera_frame);
frame_out = input_frame.clone();
// detect skin color
skin_detector.drawSkinColorSampler(camera_frame,start_x_pos,start_y_pos,region_width,region_height);
// remove background from image
foreground = background_remover.getForeground(input_frame);
// detect the hand contours
handMask = skin_detector.getSkinMask(foreground);
// count the amount of fingers and put the info on the matrix
//fingerCountDebug = finger_count.findFingersCount(handMask, frame_out);
//// get the amount of fingers
//int fingers_amount = finger_count.getAmountOfFingers();
// draw the hand rectangle on the camera input, and draw text showing if the hand is open or closed.
DrawHandMask(&camera_frame);
//hand_calibrator.SetAmountOfFingers(fingers_amount);
//finger_count.DrawHandContours(camera_frame);
//hand_calibrator.DrawHandCalibrationText(camera_frame);
//imshow("camera", camera_frame);
imshow("output" + region_id, frame_out);
imshow("foreground" + region_id, foreground);
imshow("handMask" + region_id, handMask);
/*imshow("handDetection", fingerCountDebug);*/
hand_present = hand_calibrator.CheckIfHandPresent(handMask);
std::string text = (hand_present ? "hand" : "no");
cv::putText(camera_frame, text, cv::Point(start_x_pos, start_y_pos), cv::FONT_HERSHEY_COMPLEX, 2.0, cv::Scalar(0, 255, 255), 2);
hand_calibrator.SetHandPresent(hand_present);
}
cv::Mat HandDetectRegion::GenerateHandMaskSquare(cv::Mat img)
{
cv::Mat mask = cv::Mat::zeros(img.size(), img.type());
cv::Mat distance_img = cv::Mat::zeros(img.size(), img.type());
cv::rectangle(mask, cv::Rect(start_x_pos, start_y_pos, region_width, region_height), cv::Scalar(255, 255, 255), -1);
img.copyTo(distance_img, mask);
hand_mask_generated = true;
return distance_img;
}
bool HandDetectRegion::DrawHandMask(cv::Mat* input)
{
if (!hand_mask_generated) return false;
rectangle(*input, Rect(start_x_pos, start_y_pos, region_width, region_height), Scalar(255, 255, 255));
return true;
}
bool HandDetectRegion::IsHandPresent()
{
return hand_present;
}
void HandDetectRegion::CalibrateBackground()
{
background_remover.calibrate(frame_out);
hand_calibrator.SetBackGroundCalibrated(true);
}
void HandDetectRegion::CalibrateSkin()
{
skin_detector.calibrate(frame_out);
hand_calibrator.SetSkinCalibration(true);
}
std::vector<int> HandDetectRegion::CalculateSkinTresholds()
{
return skin_detector.calibrateAndReturn(frame_out);
}
void HandDetectRegion::setSkinTresholds(std::vector<int>& tresholds)
{
skin_detector.setTresholds(tresholds);
}
} }

View File

@@ -1,22 +1,46 @@
#pragma once #pragma once
#include <opencv2/core.hpp> #include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "async/StaticCameraInstance.h"
#include "calibration/HandCalibrator.h"
#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FingerCount.h"
namespace computervision namespace computervision
{ {
class HandDetectRegion class HandDetectRegion
{ {
public: public:
HandDetectRegion(); HandDetectRegion(std::string id,int x_pos, int y_pos, int width, int height);
cv::Mat GenerateHandMaskSquare(); cv::Mat GenerateHandMaskSquare(cv::Mat img);
void detectHand(cv::Mat camera_frame); void DetectHand(cv::Mat& camera_frame);
bool IsHandPresent();
void CalibrateBackground();
void CalibrateSkin();
std::vector<int> CalculateSkinTresholds();
void setSkinTresholds(std::vector<int>& tresholds);
private: private:
int start_x_pos; int start_x_pos;
int start_y_pos; int start_y_pos;
int height; int region_height;
int width; int region_width;
bool hand_mask_generated;
bool hand_present;
cv::Mat frame, frame_out, handMask, foreground, fingerCountDebug;
BackgroundRemover background_remover;
SkinDetector skin_detector;
handcalibration::HandCalibrator hand_calibrator;
std::string region_id;
bool DrawHandMask(cv::Mat* input);
}; };
} }

View File

@@ -1,4 +1,5 @@
#include "SkinDetector.h" #include "SkinDetector.h"
#include <iostream>
/* /*
Author: Pierfrancesco Soffritti https://github.com/PierfrancescoSoffritti Author: Pierfrancesco Soffritti https://github.com/PierfrancescoSoffritti
@@ -41,6 +42,29 @@ namespace computervision
); );
} }
void SkinDetector::drawSkinColorSampler(Mat input,int x, int y,int width, int height) {
int frameWidth = width, frameHeight = height;
int rectangleSize = 25;
Scalar rectangleColor = Scalar(0, 255, 255);
skinColorSamplerRectangle1 = Rect(frameWidth / 5 + x, frameHeight / 2 + y, rectangleSize, rectangleSize);
skinColorSamplerRectangle2 = Rect(frameWidth / 5 + x, frameHeight / 3 + y, rectangleSize, rectangleSize);
rectangle(
input,
skinColorSamplerRectangle1,
rectangleColor
);
rectangle(
input,
skinColorSamplerRectangle2,
rectangleColor
);
}
void SkinDetector::calibrate(Mat input) { void SkinDetector::calibrate(Mat input) {
Mat hsvInput; Mat hsvInput;
@@ -54,6 +78,19 @@ namespace computervision
calibrated = true; calibrated = true;
} }
std::vector<int> SkinDetector::calibrateAndReturn(Mat input)
{
Mat hsvInput;
cvtColor(input, hsvInput, CV_BGR2HSV);
Mat sample1 = Mat(hsvInput, skinColorSamplerRectangle1);
Mat sample2 = Mat(hsvInput, skinColorSamplerRectangle2);
calibrated = true;
return calculateAndReturnTresholds(sample1, sample2);
}
void SkinDetector::calculateThresholds(Mat sample1, Mat sample2) { void SkinDetector::calculateThresholds(Mat sample1, Mat sample2) {
int offsetLowThreshold = 80; int offsetLowThreshold = 80;
int offsetHighThreshold = 30; int offsetHighThreshold = 30;
@@ -75,6 +112,39 @@ namespace computervision
//vHighThreshold = 255; //vHighThreshold = 255;
} }
std::vector<int> SkinDetector::calculateAndReturnTresholds(Mat sample1, Mat sample2)
{
calculateThresholds(sample1, sample2);
std::vector<int> res;
res.push_back(hLowThreshold);
res.push_back(hHighThreshold);
res.push_back(sLowThreshold);
res.push_back(sHighThreshold);
res.push_back(vLowThreshold);
res.push_back(vHighThreshold);
return res;
}
void SkinDetector::setTresholds(std::vector<int>& tresholds)
{
if (tresholds.size() != 6)
{
std::cout << "tresholds array not the right size!" << std::endl;
return;
}
hLowThreshold = tresholds[0];
hHighThreshold = tresholds[1];
sLowThreshold = tresholds[2];
sHighThreshold = tresholds[3];
vLowThreshold = tresholds[4];
vHighThreshold = tresholds[5];
calibrated = true;
}
Mat SkinDetector::getSkinMask(Mat input) { Mat SkinDetector::getSkinMask(Mat input) {
Mat skinMask; Mat skinMask;

View File

@@ -24,6 +24,9 @@ namespace computervision
*/ */
void drawSkinColorSampler(Mat input); void drawSkinColorSampler(Mat input);
void drawSkinColorSampler(Mat input, int x, int y, int width, int heigth);
/* /*
* @brief calibrates the skin color detector with the given input frame * @brief calibrates the skin color detector with the given input frame
* *
@@ -31,6 +34,10 @@ namespace computervision
*/ */
void calibrate(Mat input); void calibrate(Mat input);
std::vector<int> calibrateAndReturn(Mat input);
void setTresholds(std::vector<int>& tresholds);
/* /*
* @brief gets the mask for the hand * @brief gets the mask for the hand
* *
@@ -63,6 +70,8 @@ namespace computervision
*/ */
void calculateThresholds(Mat sample1, Mat sample2); void calculateThresholds(Mat sample1, Mat sample2);
std::vector<int> calculateAndReturnTresholds(Mat sample1, Mat sample2);
/** /**
* @brief the opening. it generates the structuring element and performs the morphological transformations required to detect the hand. * @brief the opening. it generates the structuring element and performs the morphological transformations required to detect the hand.
* This needs to be done to get the skin mask. * This needs to be done to get the skin mask.

View File

@@ -3,14 +3,20 @@
#include <map> #include <map>
#include "startup_Scene.h" #include "startup_Scene.h"
#include "../computervision/ObjectDetection.h" #include "../computervision/ObjectDetection.h"
#include "../computervision/HandDetectRegion.h"
#include <iostream> #include <iostream>
namespace scene namespace scene
{ {
std::vector<computervision::HandDetectRegion> regions;
computervision::ObjectDetection objDetect; computervision::ObjectDetection objDetect;
computervision::HandDetectRegion reg1("left",20,100,150,150);
computervision::HandDetectRegion reg2("right",200,200,150,150);
scene::Scenes scene::Startup_Scene::start(GLFWwindow *window) scene::Scenes scene::Startup_Scene::start(GLFWwindow *window)
{ {
regions.push_back(reg1);
regions.push_back(reg2);
while (return_value == scene::Scenes::STARTUP) while (return_value == scene::Scenes::STARTUP)
{ {
render(); render();
@@ -30,9 +36,30 @@ namespace scene
void scene::Startup_Scene::update(GLFWwindow* window) void scene::Startup_Scene::update(GLFWwindow* window)
{ {
bool hand_detected = false; cv::Mat camera_frame = objDetect.ReadCamera();
objDetect.DetectHand(objDetect.ReadCamera(),hand_detected); reg1.DetectHand(camera_frame);
if (hand_detected) std::cout << "there's a hand!" << std::endl; reg2.DetectHand(camera_frame);
cv::imshow("camera", camera_frame);
int key = cv::waitKey(1);
if (key == 98) // b, calibrate the background
{
for (int i = 0; i < regions.size(); i++)
{
regions[i].CalibrateBackground();
}
}
else if (key == 115) // s, calibrate the skin color
{
std::vector<int> tresholds = regions[0].CalculateSkinTresholds();
for (int i = 1; i < regions.size(); i++)
{
regions[i].setSkinTresholds(tresholds);
}
}
} }

View File

@@ -21,6 +21,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="src\collision\collision_handler.cpp" /> <ClCompile Include="src\collision\collision_handler.cpp" />
<ClCompile Include="src\computervision\calibration\HandCalibrator.cpp" /> <ClCompile Include="src\computervision\calibration\HandCalibrator.cpp" />
<ClCompile Include="src\computervision\HandDetectRegion.cpp" />
<ClCompile Include="src\scenes\in_Game_Scene.cpp" /> <ClCompile Include="src\scenes\in_Game_Scene.cpp" />
<ClCompile Include="src\computervision\async\async_arm_detection.cpp" /> <ClCompile Include="src\computervision\async\async_arm_detection.cpp" />
<ClCompile Include="src\computervision\ObjectDetection.cpp" /> <ClCompile Include="src\computervision\ObjectDetection.cpp" />
@@ -46,6 +47,7 @@
<ClInclude Include="src\collision\collision.h" /> <ClInclude Include="src\collision\collision.h" />
<ClInclude Include="src\collision\collision_handler.h" /> <ClInclude Include="src\collision\collision_handler.h" />
<ClInclude Include="src\computervision\calibration\HandCalibrator.h" /> <ClInclude Include="src\computervision\calibration\HandCalibrator.h" />
<ClInclude Include="src\computervision\HandDetectRegion.h" />
<ClInclude Include="src\scenes\in_Game_Scene.h" /> <ClInclude Include="src\scenes\in_Game_Scene.h" />
<ClInclude Include="src\scenes\scene.h" /> <ClInclude Include="src\scenes\scene.h" />
<ClInclude Include="src\computervision\async\async_arm_detection.h" /> <ClInclude Include="src\computervision\async\async_arm_detection.h" />

View File

@@ -23,6 +23,7 @@
<ClCompile Include="src\toolbox\toolbox.cpp" /> <ClCompile Include="src\toolbox\toolbox.cpp" />
<ClCompile Include="src\scenes\startup_Scene.cpp" /> <ClCompile Include="src\scenes\startup_Scene.cpp" />
<ClCompile Include="src\computervision\calibration\HandCalibrator.cpp" /> <ClCompile Include="src\computervision\calibration\HandCalibrator.cpp" />
<ClCompile Include="src\computervision\HandDetectRegion.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\collision\collision.h" /> <ClInclude Include="src\collision\collision.h" />
@@ -54,6 +55,7 @@
<ClInclude Include="src\toolbox\toolbox.h" /> <ClInclude Include="src\toolbox\toolbox.h" />
<ClInclude Include="src\scenes\startup_Scene.h" /> <ClInclude Include="src\scenes\startup_Scene.h" />
<ClInclude Include="src\computervision\calibration\HandCalibrator.h" /> <ClInclude Include="src\computervision\calibration\HandCalibrator.h" />
<ClInclude Include="src\computervision\HandDetectRegion.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Xml Include="res\haarcascade_frontalface_alt.xml" /> <Xml Include="res\haarcascade_frontalface_alt.xml" />