[EDIT] improve hand detection with mask

This commit is contained in:
Sem van der Hoeven
2021-05-25 14:19:18 +02:00
parent 276aa1a449
commit 3696e2eb30
4 changed files with 126 additions and 61 deletions

View File

@@ -15,6 +15,9 @@ namespace computervision
cv::Mat img, imgGray, img2, img2Gray, img3, img4; cv::Mat img, imgGray, img2, img2Gray, img3, img4;
int handMaskStartXPos, handMaskStartYPos, handMaskWidth, handMaskHeight;
bool handMaskGenerated = false;
Mat frame, frameOut, handMask, foreground, fingerCountDebug; Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover; BackgroundRemover backgroundRemover;
SkinDetector skinDetector; SkinDetector skinDetector;
@@ -22,6 +25,8 @@ namespace computervision
FingerCount fingerCount; FingerCount fingerCount;
ObjectDetection::ObjectDetection() ObjectDetection::ObjectDetection()
{ {
} }
@@ -67,6 +72,36 @@ namespace computervision
return true; return true;
} }
bool ObjectDetection::detectHand(Mat inputFrame)
{
frameOut = inputFrame.clone();
skinDetector.drawSkinColorSampler(frameOut);
foreground = backgroundRemover.getForeground(inputFrame);
//faceDetector.removeFaces(inputFrame, foreground);
handMask = skinDetector.getSkinMask(foreground);
fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);
//backgroundRemover.calibrate(frame);
imshow("output", frameOut);
imshow("foreground", foreground);
imshow("handMask", handMask);
imshow("handDetection", fingerCountDebug);
int key = waitKey(1);
if (key == 98) // b
backgroundRemover.calibrate(inputFrame);
else if (key == 115) // s
skinDetector.calibrate(inputFrame);
return true;
}
void ObjectDetection::calculateDifference() void ObjectDetection::calculateDifference()
{ {
cap.read(img); cap.read(img);
@@ -84,22 +119,31 @@ namespace computervision
cv::Mat ObjectDetection::generateHandMaskSquare(cv::Mat img) cv::Mat ObjectDetection::generateHandMaskSquare(cv::Mat img)
{ {
handMaskStartXPos = 20;
handMaskStartYPos = img.rows / 5;
handMaskWidth = img.cols / 3;
handMaskHeight = img.cols / 3;
cv::Mat mask = cv::Mat::zeros(img.size(), img.type()); cv::Mat mask = cv::Mat::zeros(img.size(), img.type());
cv::Mat dstImg = cv::Mat::zeros(img.size(), img.type()); cv::Mat dstImg = cv::Mat::zeros(img.size(), img.type());
cv::rectangle(mask, Rect(0, img.rows * 0.2, img.cols / 3, img.cols / 3), Scalar(255, 255, 255), -1); cv::rectangle(mask, Rect(handMaskStartXPos, handMaskStartYPos, handMaskWidth, handMaskHeight), Scalar(255, 255, 255), -1);
//cv::circle(mask, cv::Point(mask.cols / 2, mask.rows / 2), 50, cv::Scalar(255, 0, 0), -1, 8, 0);
img.copyTo(dstImg, mask); img.copyTo(dstImg, mask);
rectangle(img, Rect(0, img.rows * 0.2, img.cols / 3, img.cols / 3), Scalar(0, 255, 255, 255)); handMaskGenerated = true;
return dstImg; return dstImg;
} }
bool ObjectDetection::drawHandMaskRect(cv::Mat* input)
{
if (!handMaskGenerated) return false;
rectangle(*input, Rect(handMaskStartXPos, handMaskStartYPos, handMaskWidth, handMaskHeight), Scalar(255, 255, 255));
return true;
}
void ObjectDetection::detect() void ObjectDetection::detect()
{ {
int key = waitKey(1); int key = waitKey(1);

View File

@@ -61,6 +61,21 @@ namespace computervision
*/ */
cv::Mat readCamera(); cv::Mat readCamera();
/**
* @brief detects a hand based on the given hand mask input frame.
*
* @param inputFrame the input frame with only the hand
* @return true if the webcam is connected, false if not.
*/
bool detectHand(cv::Mat inputFrame);
/**
* @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);
}; };

View File

@@ -22,7 +22,7 @@ namespace computervision
void SkinDetector::drawSkinColorSampler(Mat input) { void SkinDetector::drawSkinColorSampler(Mat input) {
int frameWidth = input.size().width, frameHeight = input.size().height; int frameWidth = input.size().width, frameHeight = input.size().height;
int rectangleSize = 20; int rectangleSize = 25;
Scalar rectangleColor = Scalar(255, 0, 255); Scalar rectangleColor = Scalar(255, 0, 255);
skinColorSamplerRectangle1 = Rect(frameWidth / 5, frameHeight / 2, rectangleSize, rectangleSize); skinColorSamplerRectangle1 = Rect(frameWidth / 5, frameHeight / 2, rectangleSize, rectangleSize);

View File

@@ -4,6 +4,7 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
#include <ostream> #include <ostream>
#include <stdlib.h>
#include <opencv2/core.hpp> #include <opencv2/core.hpp>
#include <opencv2/videoio.hpp> #include <opencv2/videoio.hpp>
@@ -29,81 +30,86 @@ static GLFWwindow* window;
int main(void) int main(void)
{ {
#pragma region OPENGL_SETTINGS #pragma region OPENGL_SETTINGS
if (!glfwInit()) if (!glfwInit())
throw "Could not inditialize glwf"; throw "Could not inditialize glwf";
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGT, "SDBA", NULL, NULL); window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGT, "SDBA", NULL, NULL);
if (!window) if (!window)
{ {
glfwTerminate(); glfwTerminate();
throw "Could not initialize glwf"; throw "Could not initialize glwf";
} }
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glewInit(); glewInit();
glGetError(); glGetError();
#pragma endregion #pragma endregion
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
if (key == GLFW_KEY_ESCAPE) if (key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
}); });
models::RawModel raw_model = LoadObjModel("res/Tree.obj"); models::RawModel raw_model = LoadObjModel("res/Tree.obj");
models::ModelTexture texture = { render_engine::loader::LoadTexture("res/TreeTexture.png") }; models::ModelTexture texture = { render_engine::loader::LoadTexture("res/TreeTexture.png") };
models::TexturedModel model = { raw_model, texture }; models::TexturedModel model = { raw_model, texture };
entities::Entity entity(model, glm::vec3(0, -5, -20), glm::vec3(0, 0, 0), 1); entities::Entity entity(model, glm::vec3(0, -5, -20), glm::vec3(0, 0, 0), 1);
shaders::StaticShader shader; shaders::StaticShader shader;
shader.Init(); shader.Init();
render_engine::renderer::Init(shader); render_engine::renderer::Init(shader);
entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0)); entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0));
// create object detection object instance // create object detection object instance
computervision::ObjectDetection objDetect; computervision::ObjectDetection objDetect;
// set up object detection // set up object detection
//objDetect.setup(); //objDetect.setup();
cv::Mat cameraFrame;
// Main game loop // Main game loop
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
// Update // Update
const double delta = UpdateDelta(); const double delta = UpdateDelta();
entity.IncreaseRotation(glm::vec3(0, 1, 0)); entity.IncreaseRotation(glm::vec3(0, 1, 0));
camera.Move(window); camera.Move(window);
// Render // Render
render_engine::renderer::Prepare(); render_engine::renderer::Prepare();
shader.Start(); shader.Start();
shader.LoadViewMatrix(camera); shader.LoadViewMatrix(camera);
render_engine::renderer::Render(entity, shader);
objDetect.generateHandMaskSquare(objDetect.readCamera()); render_engine::renderer::Render(entity, shader);
cameraFrame = objDetect.readCamera();
objDetect.detectHand(objDetect.generateHandMaskSquare(cameraFrame));
objDetect.drawHandMaskRect(&cameraFrame);
cv::imshow("camera",cameraFrame);
// Finish up // Finish up
shader.Stop(); shader.Stop();
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
} }
// Clean up // Clean up
shader.CleanUp(); shader.CleanUp();
render_engine::loader::CleanUp(); render_engine::loader::CleanUp();
glfwTerminate(); glfwTerminate();
return 0; return 0;
} }
static double UpdateDelta() static double UpdateDelta()
{ {
double current_time = glfwGetTime(); double current_time = glfwGetTime();
static double last_frame_time = current_time; static double last_frame_time = current_time;
double delt_time = current_time - last_frame_time; double delt_time = current_time - last_frame_time;
last_frame_time = current_time; last_frame_time = current_time;
return delt_time; return delt_time;
} }