-
Notifications
You must be signed in to change notification settings - Fork 0
/
camera.py
134 lines (113 loc) · 4.92 KB
/
camera.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
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
import io
import socket
import struct
import os
import time
import cv2
import cv2.cv as cv
import numpy as np
from pantilthat import *
class VideoCamera(object):
def __init__(self):
os.system('sudo modprobe bcm2835-v4l2') # Use pi camera as usb device
self.camera = cv.CreateCameraCapture(0) # Set up camera
# Load cascade data
self.cascade = cv.Load(
'/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml')
self.cam_pan = 90 # Initial pan angle
self.cam_tilt = 90 # Initial tilt angle
pan(self.cam_pan - 90) # Pan to initial position
tilt(self.cam_tilt - 90) # Tilt to initial position
self.min_size = (15, 15) # Minimum window size
self.image_scale = 5 # Image shrink scale
# The factor by which the search window is scaled between the
# subsequent scans
self.haar_scale = 1.2
self.min_neighbors = 2 # Minimum number of neighbor rectangles that makes up an object
self.haar_flags = cv.CV_HAAR_DO_CANNY_PRUNING # Mode of operation
if self.camera:
self.frame_copy = None
# Camera warm up
time.sleep(2)
def get_frame(self):
try:
frame = cv.QueryFrame(self.camera)
if not frame:
print('Camera error')
return
if not self.frame_copy:
self.frame_copy = cv.CreateImage(
(frame.width, frame.height), cv.IPL_DEPTH_8U, frame.nChannels)
if frame.origin == cv.IPL_ORIGIN_TL:
cv.Flip(frame, frame, -1)
# Our operations on the frame come here
gray = cv.CreateImage((frame.width, frame.height), 8, 1)
small_img = cv.CreateImage(
(cv.Round(
frame.width /
self.image_scale),
cv.Round(
frame.height /
self.image_scale)),
8,
1)
# convert color input image to grayscale
cv.CvtColor(frame, gray, cv.CV_BGR2GRAY)
# Scale input image for faster processing
cv.Resize(gray, small_img, cv.CV_INTER_LINEAR)
cv.EqualizeHist(small_img, small_img)
midFace = None
if(self.cascade):
t = cv.GetTickCount()
# Do haar detection
faces = cv.HaarDetectObjects(
small_img,
self.cascade,
cv.CreateMemStorage(0),
self.haar_scale,
self.min_neighbors,
self.haar_flags,
self.min_size)
t = cv.GetTickCount() - t
if faces:
if not os.path.isfile('face.jpg'):
# Save temporary image if no existing one
image = cv2.imencode(
'.jpeg', np.asarray(frame[:, :]))[1]
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
cv2.imwrite('face.jpg', image)
for ((x, y, w, h), n) in faces:
# Resize the input, scale the bounding box of each face and convert to two
# CvPoints
pt1 = (int(x * self.image_scale),
int(y * self.image_scale))
pt2 = (int((x + w) * self.image_scale),
int((y + h) * self.image_scale))
cv.Rectangle(
frame, pt1, pt2, cv.RGB(
100, 220, 255), 1, 8, 0)
# Calculate mid point of the face
x1, y1 = pt1
x2, y2 = pt2
midFaceX = x1 + ((x2 - x1) / 2)
midFaceY = y1 + ((y2 - y1) / 2)
midFace = (midFaceX, midFaceY)
# Calculate offset of camera angle
offsetX = midFaceX / float(frame.width / 2)
offsetY = midFaceY / float(frame.height / 2)
offsetX -= 1
offsetY -= 1
self.cam_pan -= (offsetX * 5)
self.cam_tilt += (offsetY * 5)
self.cam_pan = max(0, min(180, self.cam_pan))
self.cam_tilt = max(0, min(180, self.cam_tilt))
# Pan and tilt to the next position
pan(int(self.cam_pan - 90))
tilt(int(self.cam_tilt - 90))
# Push processed framge image to flask
image = cv2.imencode('.jpeg', np.asarray(frame[:, :]))[
1].tostring()
return image
except Exception as e:
print(e)
return