2626#include " src/logo.h"
2727#include " storage.h"
2828
29- // #define DEBUG_STREAM_DATA // Debug: dump info for each stream frame on serial port
30-
3129// Functions from the main .ino
3230extern void flashLED (int flashtime);
3331extern void setLamp (int newVal);
3432
35- // External variables declared in main .ino
33+ // External variables declared in the main .ino
3634extern char myName[];
3735extern char myVer[];
3836extern IPAddress ip;
@@ -51,6 +49,7 @@ extern int lampVal;
5149extern int8_t detection_enabled;
5250extern int8_t recognition_enabled;
5351extern bool filesystem;
52+ extern bool debugData;
5453extern int sketchSize;
5554extern int sketchSpace;
5655extern String sketchMD5;
@@ -96,6 +95,7 @@ httpd_handle_t camera_httpd = NULL;
9695static mtmn_config_t mtmn_config = {0 };
9796static int8_t is_enrolling = 0 ;
9897static face_id_list id_list = {0 };
98+ int id_list_alloc = 0 ;
9999
100100static ra_filter_t * ra_filter_init (ra_filter_t * filter, size_t sample_size){
101101 memset (filter, 0 , sizeof (ra_filter_t ));
@@ -110,22 +110,20 @@ static ra_filter_t * ra_filter_init(ra_filter_t * filter, size_t sample_size){
110110 return filter;
111111}
112112
113- #if defined(DEBUG_STREAM_DATA)
114- static int ra_filter_run (ra_filter_t * filter, int value) {
115- if (!filter->values ){
116- return value;
117- }
118- filter->sum -= filter->values [filter->index ];
119- filter->values [filter->index ] = value;
120- filter->sum += filter->values [filter->index ];
121- filter->index ++;
122- filter->index = filter->index % filter->size ;
123- if (filter->count < filter->size ) {
124- filter->count ++;
125- }
126- return filter->sum / filter->count ;
127- }
128- #endif
113+ static int ra_filter_run (ra_filter_t * filter, int value) {
114+ if (!filter->values ){
115+ return value;
116+ }
117+ filter->sum -= filter->values [filter->index ];
118+ filter->values [filter->index ] = value;
119+ filter->sum += filter->values [filter->index ];
120+ filter->index ++;
121+ filter->index = filter->index % filter->size ;
122+ if (filter->count < filter->size ) {
123+ filter->count ++;
124+ }
125+ return filter->sum / filter->count ;
126+ }
129127
130128static void rgb_print (dl_matrix3du_t *image_matrix, uint32_t color, const char * str){
131129 fb_data_t fb;
@@ -209,16 +207,17 @@ static int run_face_recognition(dl_matrix3du_t *image_matrix, box_array_t *net_b
209207 }
210208 if (align_face (net_boxes, image_matrix, aligned_face) == ESP_OK){
211209 if (is_enrolling == 1 ){
210+ int8_t this_face = id_list.tail ;
212211 int8_t left_sample_face = enroll_face (&id_list, aligned_face);
213212
214213 if (left_sample_face == (ENROLL_CONFIRM_TIMES - 1 )){
215- Serial.printf (" Enrolling Face ID: %d\n " , id_list. tail );
214+ Serial.printf (" Enrolling Face ID: %d\n " , this_face );
216215 }
217- Serial.printf (" Enrolling Face ID: %d sample %d\n " , id_list. tail , ENROLL_CONFIRM_TIMES - left_sample_face);
218- rgb_printf (image_matrix, FACE_COLOR_CYAN, " ID[%u] Sample[%u]" , id_list. tail , ENROLL_CONFIRM_TIMES - left_sample_face);
216+ Serial.printf (" Enrolling Face ID: %d sample %d\n " , this_face , ENROLL_CONFIRM_TIMES - left_sample_face);
217+ rgb_printf (image_matrix, FACE_COLOR_CYAN, " ID[%u] Sample[%u]" , this_face , ENROLL_CONFIRM_TIMES - left_sample_face);
219218 if (left_sample_face == 0 ){
220219 is_enrolling = 0 ;
221- Serial.printf (" Enrolled Face ID: %d\n " , id_list. tail );
220+ Serial.printf (" Enrolled Face ID: %d\n " , this_face );
222221 }
223222 } else {
224223 matched_id = recognize_face (&id_list, aligned_face);
@@ -255,7 +254,9 @@ static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size
255254static esp_err_t capture_handler (httpd_req_t *req){
256255 camera_fb_t * fb = NULL ;
257256 esp_err_t res = ESP_OK;
258-
257+
258+ Serial.println (" Capture Requested" );
259+
259260 flashLED (75 ); // little flash of status LED
260261
261262 int64_t fr_start = esp_timer_get_time ();
@@ -338,7 +339,9 @@ static esp_err_t capture_handler(httpd_req_t *req){
338339 }
339340
340341 int64_t fr_end = esp_timer_get_time ();
341- Serial.printf (" FACE: %uB %ums %s%d\n " , (uint32_t )(jchunk.len ), (uint32_t )((fr_end - fr_start)/1000 ), detected?" DETECTED " :" " , face_id);
342+ if (debugData) {
343+ Serial.printf (" FACE: %uB %ums %s%d\n " , (uint32_t )(jchunk.len ), (uint32_t )((fr_end - fr_start)/1000 ), detected?" DETECTED " :" " , face_id);
344+ }
342345 return res;
343346}
344347
@@ -350,16 +353,15 @@ static esp_err_t stream_handler(httpd_req_t *req){
350353 char * part_buf[64 ];
351354 dl_matrix3du_t *image_matrix = NULL ;
352355 int face_id = 0 ;
353- #if defined(DEBUG_STREAM_DATA)
354- bool detected = false ;
355- int64_t fr_start = 0 ;
356- int64_t fr_face = 0 ;
357- int64_t fr_recognize = 0 ;
358- int64_t fr_encode = 0 ;
359- int64_t fr_ready = 0 ;
360- #endif
356+ bool detected = false ;
357+ int64_t fr_start = 0 ;
358+ int64_t fr_face = 0 ;
359+ int64_t fr_recognize = 0 ;
360+ int64_t fr_encode = 0 ;
361+ int64_t fr_ready = 0 ;
361362
362- Serial.println (" Stream started" );
363+
364+ Serial.println (" Stream requested" );
363365
364366 flashLED (75 ); // double flash of status LED
365367 delay (75 );
@@ -378,22 +380,18 @@ static esp_err_t stream_handler(httpd_req_t *req){
378380 httpd_resp_set_hdr (req, " Access-Control-Allow-Origin" , " *" );
379381
380382 while (true ){
381- #if defined (DEBUG_STREAM_DATA)
382- detected = false ;
383- #endif
383+ detected = false ;
384384 face_id = 0 ;
385385 fb = esp_camera_fb_get ();
386386 if (!fb) {
387387 Serial.println (" Camera capture failed" );
388388 res = ESP_FAIL;
389389 } else {
390- #if defined(DEBUG_STREAM_DATA)
391- fr_start = esp_timer_get_time ();
392- fr_ready = fr_start;
393- fr_face = fr_start;
394- fr_encode = fr_start;
395- fr_recognize = fr_start;
396- #endif
390+ fr_start = esp_timer_get_time ();
391+ fr_ready = fr_start;
392+ fr_face = fr_start;
393+ fr_encode = fr_start;
394+ fr_recognize = fr_start;
397395 if (!detection_enabled || fb->width > 400 ){
398396 if (fb->format != PIXFORMAT_JPEG){
399397 bool jpeg_converted = frame2jpg (fb, 80 , &_jpg_buf, &_jpg_buf_len);
@@ -419,28 +417,20 @@ static esp_err_t stream_handler(httpd_req_t *req){
419417 Serial.println (" fmt2rgb888 failed" );
420418 res = ESP_FAIL;
421419 } else {
422- #if defined(DEBUG_STREAM_DATA)
423- fr_ready = esp_timer_get_time ();
424- #endif
420+ fr_ready = esp_timer_get_time ();
425421 box_array_t *net_boxes = NULL ;
426422 if (detection_enabled){
427423 net_boxes = face_detect (image_matrix, &mtmn_config);
428424 }
429- #if defined(DEBUG_STREAM_DATA)
430- fr_face = esp_timer_get_time ();
431- fr_recognize = fr_face;
432- #endif
425+ fr_face = esp_timer_get_time ();
426+ fr_recognize = fr_face;
433427 if (net_boxes || fb->format != PIXFORMAT_JPEG){
434428 if (net_boxes){
435- #if defined(DEBUG_STREAM_DATA)
436- detected = true ;
437- #endif
429+ detected = true ;
438430 if (recognition_enabled){
439431 face_id = run_face_recognition (image_matrix, net_boxes);
440432 }
441- #if defined(DEBUG_STREAM_DATA)
442- fr_recognize = esp_timer_get_time ();
443- #endif
433+ fr_recognize = esp_timer_get_time ();
444434 draw_face_boxes (image_matrix, net_boxes, face_id);
445435 free (net_boxes->score );
446436 free (net_boxes->box );
@@ -457,9 +447,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
457447 _jpg_buf = fb->buf ;
458448 _jpg_buf_len = fb->len ;
459449 }
460- #if defined(DEBUG_STREAM_DATA)
461- fr_encode = esp_timer_get_time ();
462- #endif
450+ fr_encode = esp_timer_get_time ();
463451 }
464452 dl_matrix3du_free (image_matrix);
465453 }
@@ -487,25 +475,25 @@ static esp_err_t stream_handler(httpd_req_t *req){
487475 break ;
488476 }
489477
490- # ifdef DEBUG_STREAM_DATA
491- int64_t fr_end = esp_timer_get_time () ;
492- int64_t ready_time = (fr_ready - fr_start )/1000 ;
493- int64_t face_time = (fr_face - fr_ready )/1000 ;
494- int64_t recognize_time = (fr_recognize - fr_face )/1000 ;
495- int64_t encode_time = (fr_encode - fr_recognize )/1000 ;
496- int64_t process_time = (fr_encode - fr_start)/ 1000 ;
497- int64_t frame_time = fr_end - last_frame ;
498- last_frame = fr_end ;
499- frame_time /= 1000 ;
500- uint32_t avg_frame_time = ra_filter_run (&ra_filter, frame_time);
501- Serial.printf (" MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps), %u+%u+%u+%u=%u %s%d\n " ,
502- (uint32_t )(_jpg_buf_len),
503- (uint32_t )frame_time, 1000.0 / (uint32_t )frame_time,
504- avg_frame_time, 1000.0 / avg_frame_time,
505- (uint32_t )ready_time, (uint32_t )face_time, (uint32_t )recognize_time, (uint32_t )encode_time, (uint32_t )process_time,
506- (detected)?" DETECTED " :" " , face_id
507- );
508- # endif
478+ int64_t fr_end = esp_timer_get_time ();
479+ int64_t ready_time = (fr_ready - fr_start)/ 1000 ;
480+ int64_t face_time = (fr_face - fr_ready )/1000 ;
481+ int64_t recognize_time = (fr_recognize - fr_face )/1000 ;
482+ int64_t encode_time = (fr_encode - fr_recognize )/1000 ;
483+ int64_t process_time = (fr_encode - fr_start )/1000 ;
484+ int64_t frame_time = fr_end - last_frame ;
485+ last_frame = fr_end;
486+ frame_time /= 1000 ;
487+ uint32_t avg_frame_time = ra_filter_run (&ra_filter, frame_time) ;
488+ if (debugData) {
489+ Serial.printf (" MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps), %u+%u+%u+%u=%u %s%d\n " ,
490+ (uint32_t )(_jpg_buf_len),
491+ (uint32_t )frame_time, 1000.0 / (uint32_t )frame_time,
492+ avg_frame_time, 1000.0 / avg_frame_time,
493+ (uint32_t )ready_time, (uint32_t )face_time, (uint32_t )recognize_time, (uint32_t )encode_time, (uint32_t )process_time,
494+ (detected)?" DETECTED " :" " , face_id
495+ );
496+ }
509497 }
510498
511499 last_frame = 0 ;
@@ -794,9 +782,9 @@ static esp_err_t dump_handler(httpd_req_t *req){
794782 d+= sprintf (d," Spiffs: %i, used: %i<br>\n " , SPIFFS.totalBytes (), SPIFFS.usedBytes ());
795783 Serial.printf (" Spiffs: %i, used: %i\n " , SPIFFS.totalBytes (), SPIFFS.usedBytes ());
796784 }
797- // Following is debug while implementing FaceDB dump
798- // d+= sprintf(d,"mtmn_config size : %u<br>ra_filter size: %u<br>id_list %u<br> \n", sizeof(mtmn_config), sizeof(ra_filter), sizeof( id_list) );
799- // Serial.printf("mtmn_config size: %u<br>ra_filter size: %u<br>id_list %u\n", sizeof(mtmn_config), sizeof(ra_filter), sizeof(id_list));
785+ d+= sprintf (d, " Enrolled faces: %i (max %i)<br> \n " , id_list. count , id_list. size );
786+ Serial. printf ( " Enrolled faces : %i (max %i) \n " , id_list. count , id_list. size );
787+
800788 // Footer
801789 d+= sprintf (d," <br><div class=\" input-group\" >\n " );
802790 d+= sprintf (d," <button title=\" Refresh this page\" onclick=\" location.replace(document.URL)\" >Refresh</button>\n " );
@@ -977,7 +965,10 @@ void startCameraServer(int hPort, int sPort){
977965 .user_ctx = NULL
978966 };
979967
968+ // Filter list; used during face detection
980969 ra_filter_init (&ra_filter, 20 );
970+
971+ // Mtmn config values (face detection and recognition parameters)
981972 mtmn_config.type = FAST;
982973 mtmn_config.min_face = 80 ;
983974 mtmn_config.pyramid = 0.707 ;
@@ -991,7 +982,14 @@ void startCameraServer(int hPort, int sPort){
991982 mtmn_config.o_threshold .score = 0.7 ;
992983 mtmn_config.o_threshold .nms = 0.7 ;
993984 mtmn_config.o_threshold .candidate_number = 1 ;
985+
986+ // Face ID list (settings + pointer to the data allocation)
994987 face_id_init (&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);
988+ // The size of the allocated data block; calculated in dl_lib_calloc()
989+ id_list_alloc = FACE_ID_SAVE_NUMBER * sizeof (dl_matrix3d_t *) + sizeof (void *);
990+ Serial.print (" FACE DB SIZE: " );
991+ Serial.println (id_list_alloc);
992+ Serial.printf (" FACE DB POINTER: %p\n " , id_list.id_list );
995993
996994 config.server_port = hPort;
997995 config.ctrl_port = hPort;
0 commit comments