-
Notifications
You must be signed in to change notification settings - Fork 10
/
cascade.py
62 lines (54 loc) · 2.08 KB
/
cascade.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
import cv2
import os
import numpy as np
CASE_PATH=os.path.join(os.getcwd(),"haarcascade_frontalface_default.xml")
face_size = 64
def crop_face( imgarray, section, margin=40, size=64):
"""
:param imgarray: full image
:param section: face detected area (x, y, w, h)
:param margin: add some margin to the face detected area to include a full head
:param size: the result image resolution with be (size x size)
:return: resized image in numpy array with shape (size x size x 3)
"""
img_h, img_w, _ = imgarray.shape
if section is None:
section = [0, 0, img_w, img_h]
(x, y, w, h) = section
margin = int(min(w,h) * margin / 100)
x_a = x - margin
y_a = y - margin
x_b = x + w + margin
y_b = y + h + margin
if x_a < 0:
x_b = min(x_b - x_a, img_w-1)
x_a = 0
if y_a < 0:
y_b = min(y_b - y_a, img_h-1)
y_a = 0
if x_b > img_w:
x_a = max(x_a - (x_b - img_w), 0)
x_b = img_w
if y_b > img_h:
y_a = max(y_a - (y_b - img_h), 0)
y_b = img_h
cropped = imgarray[y_a: y_b, x_a: x_b]
resized_img = cv2.resize(cropped, (size, size), interpolation=cv2.INTER_AREA)
resized_img = np.array(resized_img)
return resized_img, (x_a, y_a, x_b - x_a, y_b - y_a)
def detect_face(image):
xmin = ymin = xmax = ymax = 0
frame = np.asarray(image)
face_cascade = cv2.CascadeClassifier(CASE_PATH)
gray_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5,minSize=(face_size, face_size), flags=cv2.CASCADE_SCALE_IMAGE)
face_imgs = np.empty((len(faces), face_size, face_size, 3))
for i, face in enumerate(faces):
face_img, cropped = crop_face(frame, face, margin=40, size=face_size)
(x, y, w, h) = cropped
if i == 0:
xmin = x
ymin = y
xmax = x+w
ymax = y+h
return xmin , ymin , xmax , ymax