-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
143 lines (104 loc) · 3.97 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* main.cpp / GestureControl
*
* Triet Ngo / CS 8674 / Northeastern University
* Spring 2024 / Apr 25, 2024
*
* Haar Cascade Hand Models created by Sandeep Sthapit: https://github.com/Sandeep-Sthapit/HandGestureDetection
*/
#include <stdio.h>
#include <iostream>
#include <cmath>
// SendInput only supported in Windows 2000 and later
#define WINVER 0x0500
#include <Windows.h>
#include <winuser.h>
// Import OpenCV C++ Module
#include <opencv2/opencv.hpp>
// Import header files containing helper functions
#include "gestureControlHelper.hpp"
// Define monitor resolution
#define monWidth 3840
#define monHeight 2160
using namespace std;
using namespace cv;
// Viewing window name
string WINDOW_STR = "Webcam";
// Main function that captures hand gestures to perform appropriate move and select actions
int main() {
// Initialize img
Mat img;
// Init VideoCapture object cap(<cameraID>) or cap(<path to video>)
int cameraMain = 0;
VideoCapture cap(cameraMain);
// Haar Cascade Detection Method
// Load Cascade Model
// Left hand model
CascadeClassifier rightHandCascade;
rightHandCascade.load("INSERT rpalm.xml LOCATION");
// Fist model
CascadeClassifier fistCascade;
fistCascade.load("INSERT fist.xml LOCATION");
// Check if loaded
if (rightHandCascade.empty() || fistCascade.empty()) {
cout << "XML files not loaded." << endl;
exit(1);
}
// Set frame
cap.set(cv::CAP_PROP_BUFFERSIZE, 3);
cap.set(cv::CAP_PROP_FPS, 60);
// While the camera is still capturing frame by frame
while (true) {
// Hide cursor
ShowCursor(false);
// Read and extract information from the current frame
cap.read(img);
// Detect right hand
vector<cv::Rect> rightHands;
rightHandCascade.detectMultiScale(img, rightHands, 1.3, 5, 0 | CASCADE_SCALE_IMAGE, Size(150, 150));
// Detect fist
vector<cv::Rect> fists;
fistCascade.detectMultiScale(img, fists, 1.3, 5, 0 | CASCADE_SCALE_IMAGE, Size(150, 150));
// Get prev mouse cursor
POINT mousePos;
if (!GetCursorPos(&mousePos)) {
cout << "Cannot get mouse position" << endl;
}
int mouseCurPosX = mousePos.x;
int mouseCurPosY = mousePos.y;
// Draw right hand box
for (int i = 0; i < rightHands.size(); i++) {
rectangle(img, rightHands[i].tl(), rightHands[i].br(), Scalar(255, 0, 255), 2);
// Put text above bound box
putText(img, "Right Hand", {rightHands[i].x, rightHands[i].y - 5}, FONT_HERSHEY_PLAIN, 1, Scalar(255, 0, 255), 1);
// Print debug
//cout << "Right Hand" << " " << rightHands[i].x << " " << rightHands[i].y << endl;
// Control the selection based on current hand movements
cursorControl(mouseCurPosX, mouseCurPosY, rightHands[i].x, rightHands[i].y);
// Interval
Sleep(300);
}
// Draw fists
for (int i = 0; i < fists.size(); i++) {
pressKey("enter");
rectangle(img, fists[i].tl(), fists[i].br(), Scalar(0, 255, 255), 2);
// Put text above bound box
putText(img, "Fist", {fists[i].x, fists[i].y - 5}, FONT_HERSHEY_PLAIN, 1, Scalar(0, 255, 255), 1);
// Print debug
//cout << "Fist" << " " << fists[i].x << " " << fists[i].y << endl;
// Interval
Sleep(300);
break;
}
// Show the stream
imshow(WINDOW_STR, img);
int key = waitKey(1);
// Press q or ESC to quit
if (key == 'q' || key == 27) {
cap.release();
destroyAllWindows();
exit(1);
}
}
return 0;
}