11import sensor
22import image
3- import utime
43import math
4+ import ml
5+ from ml .utils import NMS
56
67class 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 ]
0 commit comments