Skip to content

Commit f724d89

Browse files
committed
Add Edge Impulse Faster Objects More Objects
1 parent 79b6095 commit f724d89

6 files changed

Lines changed: 55 additions & 23 deletions

File tree

release/firmware.bin

1.11 KB
Binary file not shown.

software/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def __init__(self):
3535
self.default['CreateGifs'] = 1
3636
self.default['TrackFace'] = 1
3737
self.default['TrackEyes'] = 0
38+
self.default['TensorFlow'] = 1
3839
self.default['FaceFeatures'] = 16
3940
self.default['DrawFaceRegion'] = 1
4041
self.default['FaceStages'] = 25

software/face.py

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import sensor
22
import image
3-
import utime
43
import math
4+
import ml
5+
from ml.utils import NMS
56

67
class face_detection:
78
def __init__(self, config, comms):
@@ -12,16 +13,35 @@ def __init__(self, config, comms):
1213
self.face_object = [0, 0, 1, 1]
1314
self.face_angle = 0
1415
self.correct_angle = False
16+
self.ml_model = None
17+
self.min_confidence = 0.4
18+
self.threshold_list = [(math.ceil(self.min_confidence * 255), 255)]
1519

1620
self.extra_fb = sensor.alloc_extra_fb(sensor.width(), sensor.height(), sensor.GRAYSCALE)
1721

18-
def detect(self, img):
22+
def detect(self, img, global_variance):
1923
if not self.config.get('TrackFace'):
2024
self.face_object = [0, 0, img.width(), img.height()]
2125
self.has_face = False
2226
return
2327

24-
now = utime.ticks_ms()
28+
if global_variance >= self.config.get('TossThreshold'):
29+
self.face_object = [0, 0, img.width(), img.height()]
30+
self.has_face = False
31+
32+
if self.config.get('TensorFlow'):
33+
if self.ml_model == None:
34+
self.ml_model = ml.Model('fomo_face_detection')
35+
36+
for i, detection_list in enumerate(self.ml_model.predict([img], callback=self.post_process)):
37+
if i == 0 or len(detection_list) == 0:
38+
continue
39+
40+
for (x, y, w, h), score in detection_list:
41+
self.face_object = (x - w, y - h, w * 4, h * 4)
42+
self.has_face = True
43+
return
44+
2545
self.face_angle = 0
2646
face_objects = img.find_features(self.face_cascade, threshold=self.config.get('FaceThreshold'), scale_factor=self.config.get('FaceScaleFactor'))
2747

@@ -38,6 +58,7 @@ def detect(self, img):
3858
if face_objects:
3959
self.face_object = face_objects[0]
4060
self.has_face = True
61+
4162
if self.config.get('TrackEyes'):
4263
self.face_object = [self.face_object[0], self.face_object[1] + int(self.face_object[3] * 1/5), self.face_object[2], int(self.face_object[3] * 2/5)]
4364

@@ -47,9 +68,6 @@ def detect(self, img):
4768
eyes_width = self.face_object[2] - int(self.face_object[2] * 1/5)
4869
eyes_height = int(self.face_object[3] * 2/5)
4970
self.face_object = [eyes_x, eyes_y, eyes_width, eyes_height]
50-
else:
51-
self.face_object = [0, 0, img.width(), img.height()]
52-
self.has_face = False
5371

5472
def draw_region(self, img):
5573
if not self.config.get('DrawFaceRegion'):
@@ -84,13 +102,30 @@ def draw_region(self, img):
84102
img.draw_line((rotated_rect[3][0], rotated_rect[3][1], rotated_rect[0][0], rotated_rect[0][1]), color=(220, 220, 0))
85103
img.draw_string(face_x, face_y + face_height - 10, str(self.face_angle) + "^", color=(70, 130, 180), mono_space=False)
86104

87-
def rotate(xy, theta):
88-
cos_theta, sin_theta = math.cos(theta), math.sin(theta)
89-
90-
return (
91-
int(xy[0] * cos_theta - xy[1] * sin_theta),
92-
int(xy[0] * sin_theta + xy[1] * cos_theta)
93-
)
94-
95-
def translate(xy, offset):
96-
return xy[0] + offset[0], xy[1] + offset[1]
105+
def post_process(self, model, inputs, outputs):
106+
n, oh, ow, oc = model.output_shape[0]
107+
nms = NMS(ow, oh, inputs[0].roi)
108+
for i in range(oc):
109+
img = image.Image(outputs[0][0, :, :, i] * 255)
110+
blobs = img.find_blobs(
111+
self.threshold_list, x_stride=1, area_threshold=1, pixels_threshold=1
112+
)
113+
for b in blobs:
114+
rect = b.rect()
115+
x, y, w, h = rect
116+
score = (
117+
img.get_statistics(thresholds=self.threshold_list, roi=rect).l_mean() / 255.0
118+
)
119+
nms.add_bounding_box(x, y, x + w, y + h, score, i)
120+
return nms.get_bounding_boxes()
121+
122+
def rotate(xy, theta):
123+
cos_theta, sin_theta = math.cos(theta), math.sin(theta)
124+
125+
return (
126+
int(xy[0] * cos_theta - xy[1] * sin_theta),
127+
int(xy[0] * sin_theta + xy[1] * cos_theta)
128+
)
129+
130+
def translate(xy, offset):
131+
return xy[0] + offset[0], xy[1] + offset[1]

software/inspec.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,7 @@ def monitor(self):
9898
try:
9999
self.img = sensor.snapshot()
100100

101-
if self.config.get('TrackFace'):
102-
self.img.gamma(gamma=1.0, contrast=1.5, brightness=0.0)
103-
else:
104-
time.sleep_ms(64)
105-
106-
self.face.detect(self.img)
101+
self.face.detect(self.img, self.global_variance)
107102
self.global_variance, self.variance = self.img.variance(self.extra_fb, self.config.get('PixelThreshold'), self.config.get('PixelRange'), self.face.face_object)
108103

109104
if self.variance > self.peak_variance:

software/rem.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def __init__(self, config, face):
1010
def detect(self, variance, global_variance):
1111
if global_variance >= self.config.get('TossThreshold'):
1212
self.eye_movements = 0
13+
self.last_eye_movement = now + 1000 * 10
1314

1415
now = utime.ticks_ms()
1516
if now - self.last_eye_movement > 1000 * 60:

software/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = '1.2.5'
1+
version = '1.2.6'

0 commit comments

Comments
 (0)