[ADD] multiple hand detection squares
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user