19
19
#include " Arduino.h"
20
20
21
21
#include " fb_gfx.h"
22
+
23
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
24
+
22
25
#include " fd_forward.h"
26
+
27
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
23
28
#include " fr_forward.h"
24
29
25
30
#define ENROLL_CONFIRM_TIMES 5
26
31
#define FACE_ID_SAVE_NUMBER 7
32
+ #endif
27
33
28
- #define FACE_COLOR_WHITE 0x00FFFFFF
29
- #define FACE_COLOR_BLACK 0x00000000
30
- #define FACE_COLOR_RED 0x000000FF
31
- #define FACE_COLOR_GREEN 0x0000FF00
32
- #define FACE_COLOR_BLUE 0x00FF0000
34
+ #define FACE_COLOR_WHITE 0x00FFFFFF
35
+ #define FACE_COLOR_BLACK 0x00000000
36
+ #define FACE_COLOR_RED 0x000000FF
37
+ #define FACE_COLOR_GREEN 0x0000FF00
38
+ #define FACE_COLOR_BLUE 0x00FF0000
33
39
#define FACE_COLOR_YELLOW (FACE_COLOR_RED | FACE_COLOR_GREEN)
34
- #define FACE_COLOR_CYAN (FACE_COLOR_BLUE | FACE_COLOR_GREEN)
40
+ #define FACE_COLOR_CYAN (FACE_COLOR_BLUE | FACE_COLOR_GREEN)
35
41
#define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED)
42
+ #endif
36
43
37
44
typedef struct {
38
45
size_t size; // number of values used for filtering
@@ -56,12 +63,6 @@ static ra_filter_t ra_filter;
56
63
httpd_handle_t stream_httpd = NULL ;
57
64
httpd_handle_t camera_httpd = NULL ;
58
65
59
- static mtmn_config_t mtmn_config = {0 };
60
- static int8_t detection_enabled = 0 ;
61
- static int8_t recognition_enabled = 0 ;
62
- static int8_t is_enrolling = 0 ;
63
- static face_id_list id_list = {0 };
64
-
65
66
static ra_filter_t * ra_filter_init (ra_filter_t * filter, size_t sample_size){
66
67
memset (filter, 0 , sizeof (ra_filter_t ));
67
68
@@ -90,6 +91,16 @@ static int ra_filter_run(ra_filter_t * filter, int value){
90
91
return filter->sum / filter->count ;
91
92
}
92
93
94
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
95
+
96
+ static mtmn_config_t mtmn_config = {0 };
97
+ static int8_t detection_enabled = 0 ;
98
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
99
+ static int8_t recognition_enabled = 0 ;
100
+ static int8_t is_enrolling = 0 ;
101
+ static face_id_list id_list = {0 };
102
+ #endif
103
+
93
104
static void rgb_print (dl_matrix3du_t *image_matrix, uint32_t color, const char * str){
94
105
fb_data_t fb;
95
106
fb.width = image_matrix->w ;
@@ -161,6 +172,7 @@ static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes, in
161
172
}
162
173
}
163
174
175
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
164
176
static int run_face_recognition (dl_matrix3du_t *image_matrix, box_array_t *net_boxes){
165
177
dl_matrix3du_t *aligned_face = NULL ;
166
178
int matched_id = 0 ;
@@ -202,6 +214,8 @@ static int run_face_recognition(dl_matrix3du_t *image_matrix, box_array_t *net_b
202
214
dl_matrix3du_free (aligned_face);
203
215
return matched_id;
204
216
}
217
+ #endif
218
+ #endif
205
219
206
220
static size_t jpg_encode_stream (void * arg, size_t index, const void * data, size_t len){
207
221
jpg_chunking_t *j = (jpg_chunking_t *)arg;
@@ -231,12 +245,14 @@ static esp_err_t capture_handler(httpd_req_t *req){
231
245
httpd_resp_set_hdr (req, " Content-Disposition" , " inline; filename=capture.jpg" );
232
246
httpd_resp_set_hdr (req, " Access-Control-Allow-Origin" , " *" );
233
247
248
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
234
249
size_t out_len, out_width, out_height;
235
250
uint8_t * out_buf;
236
251
bool s;
237
252
bool detected = false ;
238
253
int face_id = 0 ;
239
254
if (!detection_enabled || fb->width > 400 ){
255
+ #endif
240
256
size_t fb_len = 0 ;
241
257
if (fb->format == PIXFORMAT_JPEG){
242
258
fb_len = fb->len ;
@@ -251,6 +267,7 @@ static esp_err_t capture_handler(httpd_req_t *req){
251
267
int64_t fr_end = esp_timer_get_time ();
252
268
Serial.printf (" JPG: %uB %ums\n " , (uint32_t )(fb_len), (uint32_t )((fr_end - fr_start)/1000 ));
253
269
return res;
270
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
254
271
}
255
272
256
273
dl_matrix3du_t *image_matrix = dl_matrix3du_alloc (1 , fb->width , fb->height , 3 );
@@ -279,9 +296,12 @@ static esp_err_t capture_handler(httpd_req_t *req){
279
296
280
297
if (net_boxes){
281
298
detected = true ;
282
- if (recognition_enabled){
299
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
300
+ if (recognition_enabled)
301
+ {
283
302
face_id = run_face_recognition (image_matrix, net_boxes);
284
303
}
304
+ #endif
285
305
draw_face_boxes (image_matrix, net_boxes, face_id);
286
306
free (net_boxes->score );
287
307
free (net_boxes->box );
@@ -300,6 +320,7 @@ static esp_err_t capture_handler(httpd_req_t *req){
300
320
int64_t fr_end = esp_timer_get_time ();
301
321
Serial.printf (" FACE: %uB %ums %s%d\n " , (uint32_t )(jchunk.len ), (uint32_t )((fr_end - fr_start)/1000 ), detected?" DETECTED " :" " , face_id);
302
322
return res;
323
+ #endif
303
324
}
304
325
305
326
static esp_err_t stream_handler (httpd_req_t *req){
@@ -308,6 +329,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
308
329
size_t _jpg_buf_len = 0 ;
309
330
uint8_t * _jpg_buf = NULL ;
310
331
char * part_buf[64 ];
332
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
311
333
dl_matrix3du_t *image_matrix = NULL ;
312
334
bool detected = false ;
313
335
int face_id = 0 ;
@@ -316,6 +338,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
316
338
int64_t fr_face = 0 ;
317
339
int64_t fr_recognize = 0 ;
318
340
int64_t fr_encode = 0 ;
341
+ #endif
319
342
320
343
static int64_t last_frame = 0 ;
321
344
if (!last_frame) {
@@ -330,19 +353,24 @@ static esp_err_t stream_handler(httpd_req_t *req){
330
353
httpd_resp_set_hdr (req, " Access-Control-Allow-Origin" , " *" );
331
354
332
355
while (true ){
356
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
333
357
detected = false ;
334
358
face_id = 0 ;
359
+ #endif
335
360
fb = esp_camera_fb_get ();
336
361
if (!fb) {
337
362
Serial.println (" Camera capture failed" );
338
363
res = ESP_FAIL;
339
364
} else {
365
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
340
366
fr_start = esp_timer_get_time ();
341
367
fr_ready = fr_start;
342
368
fr_face = fr_start;
343
369
fr_encode = fr_start;
344
370
fr_recognize = fr_start;
345
- if (!detection_enabled || fb->width > 400 ){
371
+ if (!detection_enabled || fb->width > 400 )
372
+ {
373
+ #endif
346
374
if (fb->format != PIXFORMAT_JPEG){
347
375
bool jpeg_converted = frame2jpg (fb, 80 , &_jpg_buf, &_jpg_buf_len);
348
376
esp_camera_fb_return (fb);
@@ -355,6 +383,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
355
383
_jpg_buf_len = fb->len ;
356
384
_jpg_buf = fb->buf ;
357
385
}
386
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
358
387
} else {
359
388
360
389
image_matrix = dl_matrix3du_alloc (1 , fb->width , fb->height , 3 );
@@ -377,10 +406,13 @@ static esp_err_t stream_handler(httpd_req_t *req){
377
406
if (net_boxes || fb->format != PIXFORMAT_JPEG){
378
407
if (net_boxes){
379
408
detected = true ;
380
- if (recognition_enabled){
409
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
410
+ if (recognition_enabled)
411
+ {
381
412
face_id = run_face_recognition (image_matrix, net_boxes);
382
413
}
383
414
fr_recognize = esp_timer_get_time ();
415
+ #endif
384
416
draw_face_boxes (image_matrix, net_boxes, face_id);
385
417
free (net_boxes->score );
386
418
free (net_boxes->box );
@@ -402,6 +434,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
402
434
dl_matrix3du_free (image_matrix);
403
435
}
404
436
}
437
+ #endif
405
438
}
406
439
if (res == ESP_OK){
407
440
res = httpd_resp_send_chunk (req, _STREAM_BOUNDARY, strlen (_STREAM_BOUNDARY));
@@ -426,22 +459,31 @@ static esp_err_t stream_handler(httpd_req_t *req){
426
459
}
427
460
int64_t fr_end = esp_timer_get_time ();
428
461
429
- int64_t ready_time = (fr_ready - fr_start)/1000 ;
430
- int64_t face_time = (fr_face - fr_ready)/1000 ;
431
- int64_t recognize_time = (fr_recognize - fr_face)/1000 ;
432
- int64_t encode_time = (fr_encode - fr_recognize)/1000 ;
433
- int64_t process_time = (fr_encode - fr_start)/1000 ;
462
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
463
+ int64_t ready_time = (fr_ready - fr_start) / 1000 ;
464
+ int64_t face_time = (fr_face - fr_ready) / 1000 ;
465
+ int64_t recognize_time = (fr_recognize - fr_face) / 1000 ;
466
+ int64_t encode_time = (fr_encode - fr_recognize) / 1000 ;
467
+ int64_t process_time = (fr_encode - fr_start) / 1000 ;
468
+ #endif
434
469
435
470
int64_t frame_time = fr_end - last_frame;
436
471
last_frame = fr_end;
437
472
frame_time /= 1000 ;
438
473
uint32_t avg_frame_time = ra_filter_run (&ra_filter, frame_time);
439
- Serial.printf (" MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps), %u+%u+%u+%u=%u %s%d\n " ,
440
- (uint32_t )(_jpg_buf_len),
441
- (uint32_t )frame_time, 1000.0 / (uint32_t )frame_time,
442
- avg_frame_time, 1000.0 / avg_frame_time,
443
- (uint32_t )ready_time, (uint32_t )face_time, (uint32_t )recognize_time, (uint32_t )encode_time, (uint32_t )process_time,
444
- (detected)?" DETECTED " :" " , face_id
474
+ Serial.printf (" MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps)"
475
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
476
+ " , %u+%u+%u+%u=%u %s%d"
477
+ #endif
478
+ ,
479
+ (uint32_t )(_jpg_buf_len),
480
+ (uint32_t )frame_time, 1000.0 / (uint32_t )frame_time,
481
+ avg_frame_time, 1000.0 / avg_frame_time
482
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
483
+ ,
484
+ (uint32_t )ready_time, (uint32_t )face_time, (uint32_t )recognize_time, (uint32_t )encode_time, (uint32_t )process_time,
485
+ (detected) ? " DETECTED " : " " , face_id
486
+ #endif
445
487
);
446
488
}
447
489
@@ -511,19 +553,26 @@ static esp_err_t cmd_handler(httpd_req_t *req){
511
553
else if (!strcmp (variable, " special_effect" )) res = s->set_special_effect (s, val);
512
554
else if (!strcmp (variable, " wb_mode" )) res = s->set_wb_mode (s, val);
513
555
else if (!strcmp (variable, " ae_level" )) res = s->set_ae_level (s, val);
514
- else if (!strcmp (variable, " face_detect" )) {
556
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
557
+ else if (!strcmp (variable, " face_detect" )) {
515
558
detection_enabled = val;
516
- if (!detection_enabled) {
559
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
560
+ if (!detection_enabled) {
517
561
recognition_enabled = 0 ;
518
562
}
563
+ #endif
519
564
}
520
- else if (!strcmp (variable, " face_enroll" )) is_enrolling = val;
521
- else if (!strcmp (variable, " face_recognize" )) {
565
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
566
+ else if (!strcmp (variable, " face_enroll" ))
567
+ is_enrolling = val;
568
+ else if (!strcmp (variable, " face_recognize" )) {
522
569
recognition_enabled = val;
523
- if (recognition_enabled){
570
+ if (recognition_enabled) {
524
571
detection_enabled = val;
525
572
}
526
573
}
574
+ #endif
575
+ #endif
527
576
else {
528
577
res = -1 ;
529
578
}
@@ -568,9 +617,13 @@ static esp_err_t status_handler(httpd_req_t *req){
568
617
p+=sprintf (p, " \" hmirror\" :%u," , s->status .hmirror );
569
618
p+=sprintf (p, " \" dcw\" :%u," , s->status .dcw );
570
619
p+=sprintf (p, " \" colorbar\" :%u," , s->status .colorbar );
571
- p+=sprintf (p, " \" face_detect\" :%u," , detection_enabled);
572
- p+=sprintf (p, " \" face_enroll\" :%u," , is_enrolling);
573
- p+=sprintf (p, " \" face_recognize\" :%u" , recognition_enabled);
620
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
621
+ p += sprintf (p, " ,\" face_detect\" :%u" , detection_enabled);
622
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
623
+ p += sprintf (p, " ,\" face_enroll\" :%u," , is_enrolling);
624
+ p += sprintf (p, " \" face_recognize\" :%u" , recognition_enabled);
625
+ #endif
626
+ #endif
574
627
*p++ = ' }' ;
575
628
*p++ = 0 ;
576
629
httpd_resp_set_type (req, " application/json" );
@@ -629,6 +682,9 @@ void startCameraServer(){
629
682
630
683
ra_filter_init (&ra_filter, 20 );
631
684
685
+
686
+ #if CONFIG_ESP_FACE_DETECT_ENABLED
687
+
632
688
mtmn_config.type = FAST;
633
689
mtmn_config.min_face = 80 ;
634
690
mtmn_config.pyramid = 0.707 ;
@@ -642,8 +698,12 @@ void startCameraServer(){
642
698
mtmn_config.o_threshold .score = 0.7 ;
643
699
mtmn_config.o_threshold .nms = 0.7 ;
644
700
mtmn_config.o_threshold .candidate_number = 1 ;
645
-
701
+
702
+ #if CONFIG_ESP_FACE_RECOGNITION_ENABLED
646
703
face_id_init (&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);
704
+ #endif
705
+
706
+ #endif
647
707
648
708
Serial.printf (" Starting web server on port: '%d'\n " , config.server_port );
649
709
if (httpd_start (&camera_httpd, &config) == ESP_OK) {
0 commit comments