-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfacehand.cpp
153 lines (122 loc) · 3.33 KB
/
facehand.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
144
145
146
147
148
149
150
151
152
153
// Combines both face and hand detection, possibility of threading here
// Libraries used : OpenCV, LibVLC
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <vlc/vlc.h>
using namespace std;
using namespace cv;
// Create CC for HaarClassification
CascadeClassifier face_cascade;
CascadeClassifier hand_cascade;
// Face detection function, returns whether present
int faceDetect(Mat frame)
{
std::vector<Rect> faces;
Mat frame_gray;
// Convert to GRAY scale for cascade
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
// Detect face
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0, Size(30,30));
// Return whether present
if(faces.size() == 0)
return 0;
return 1;
}
// Hand detection function, returns the average x-coordinate
float handDetect(Mat frame)
{
std::vector<Rect> hands;
Mat frame_gray;
float avgPos = 0;
// Convert to GRAY scale for cascade
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
// Detect hand
hand_cascade.detectMultiScale(frame_gray, hands, 1.1, 2, 0, Size(30,30));
for(size_t i = 0; i < hands.size(); i++)
{
avgPos += (hands[i].x + hands[i].width/2);
}
avgPos = avgPos / hands.size();
return avgPos;
}
int main(int argc, char** argv)
{
// Variable declarations
VideoCapture capture;
Mat frame;
int esc, volume;
int facePresent, facePast = 1;
float handPos, minFWidth, maxFWidth;
// LibVLC requirements, plays video specified as a command line argument
libvlc_instance_t *instance = libvlc_new(0, NULL);
libvlc_media_t *media = libvlc_media_new_path(instance, argv[1]);
libvlc_media_player_t *mplayer = libvlc_media_player_new_from_media(media);
libvlc_media_release(media);
// Error checking
if(!face_cascade.load("XML/face.xml"))
{
printf("Error loading XML/face.xml\n");
return -1;
}
if(!hand_cascade.load("XML/palm.xml"))
{
printf("Error loading XML/palm.xml\n");
return -1;
}
capture.open(-1);
if(!capture.isOpened())
{
printf("Error opening video capture.\n");
return -1;
}
libvlc_media_player_play(mplayer);
capture.read(frame);
maxFWidth = (0.65) * capture.get(CV_CAP_PROP_FRAME_WIDTH);
minFWidth = (0.35) * capture.get(CV_CAP_PROP_FRAME_WIDTH);
volume = libvlc_audio_get_volume(mplayer);
// Processing
while(capture.read(frame))
{
// More error checking
if(frame.empty())
{
printf("Empty frame.\n");
break;
}
// Function call, and pause/play depending on return value
facePresent = faceDetect(frame);
if(!facePresent && facePast)
libvlc_media_player_pause(mplayer);
if(facePresent && !facePast)
libvlc_media_player_play(mplayer);
facePast = facePresent;
// Function call that returns x-coordinate of detected hand
handPos = handDetect(frame);
// Increase or Decrease volume based on palm position
if(handPos >= maxFWidth && volume >= 0)
{
volume -= 10;
libvlc_audio_set_volume(mplayer, volume);
//printf("%d\n", volume);
}
else if(handPos <= minFWidth && volume <= 100)
{
volume += 10;
libvlc_audio_set_volume(mplayer, volume);
//printf("%d\n", volume);
}
// Premature break condition
esc = waitKey(10);
if((char)esc == 27)
{
printf("Escape pressed, breaking out.\n");
break;
}
}
return 0;
}