-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
106 lines (81 loc) · 2.57 KB
/
main.py
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
import time
from enum import Enum
import cv2
import RPi.GPIO as GPIO
from servo import Servo
from webcam import Webcam
from switch import Button
from led import LED
EPSILON = 50 # tolerance in no. of pixels for being off-center
DIVISION = 0.01 # division in rotation of webcam
# list of pins
SRV_PIN = 18 # servo pin
class State(Enum):
OFF = 0
NOT_FOUND = 1
FINDING = 2
ADJUSTING = 3
CENTERED = 4
import cv2
import RPi.GPIO as IO
from servo import Servo
from webcam import Webcam
EPSILON = 50 # tolerance in no. of pixels for being off-center
DIVISION = 0.005 # division in rotation of webcam
# list of pins
SRV_PIN = 18 # servo pin
def main():
state = State.OFF
GPIO.setmode(GPIO.BCM)
srv = Servo(SRV_PIN)
webcam = Webcam("haarcascade_frontalface_default.xml")
led = LED(16, 12, 25)
led.set(0, 0, 0)
switch = Button(23)
MID_X = webcam.WIDTH / 2
MID_Y = webcam.HEIGHT / 2
MID_X = webcam.WIDTH / 2
MID_Y = webcam.HEIGHT / 2
servo.rotate(0.5)
while True:
if not switch.is_pressed():
continue
state = State.FINDING
start = time.time()
reverse = False
while time.time() - start < 60 or state == State.ADJUSTING or state == State.CENTERED:
_, frame = webcam.cap.read()
faces = webcam.detect_faces()
if len(faces) == 0:
state = State.FINDING
led.set(1, 1, 0)
if srv.duty_cycle >= srv.END:
reverse = True
elif srv.duty_cycle <= srv.START:
reverse = False
if reverse:
srv.rotate_inc(-DIVISION)
else:
srv.rotate_inc(DIVISION)
else:
start = time.time()
state = State.ADJUSTING
led.set(0, 1, 0)
x, y, w, h = max(faces, key=lambda t: (t[2], t[3]))
coord = ((2*x + w) / 2, (2*y + h) / 2)
diff = abs(coord[0] - MID_X)
print(coord, diff)
if diff > EPSILON:
if coord[0] < MID_X:
print(MID_X, "turning towards the left")
srv.rotate_inc(DIVISION)
elif coord[0] > MID_X:
print(MID_X, "turning towards the right")
srv.rotate_inc(-DIVISION)
else:
state = State.CENTERED
time.sleep(0.25)
led.set(0, 0, 0)
state = State.OFF
if __name__ == "__main__":
main()