ESP32 Cam Face Enroll Error in AP Mode
Posted: Fri Sep 29, 2023 9:34 am
Hi Everyone!
All the Fd and Fr functions work perfectly in the camerawebserver sample codes but for some reason when I try to enroll a new face in my AP mode code I get guru meditation error:
Using Arduino ide 2.2.1
ESP32 1.0.4 Core
ESP32_CAM Module
I also tried:
External power
Code from main example in app_httpd.cpp file
Code from Fr-flash library
Main code is:
also the previous code leads to the same error:
All the Fd and Fr functions work perfectly in the camerawebserver sample codes but for some reason when I try to enroll a new face in my AP mode code I get guru meditation error:
- Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
- Core 1 register dump:
- PC : 0x401178b9 PS : 0x00060930 A0 : 0x800d2010 A1 : 0x3ffb1e60
- A2 : 0xfb00005e A3 : 0x3ffe1230 A4 : 0x3ffb8488 A5 : 0x000000f0
- A6 : 0x3ffe1230 A7 : 0x3ffb8488 A8 : 0x8000beca A9 : 0x3ffb1e80
- A10 : 0x3ffb80c0 A11 : 0x3ffe4374 A12 : 0x3ffb9380 A13 : 0x00000000
- A14 : 0x00000000 A15 : 0x3ffc1f5c SAR : 0x0000001b EXCCAUSE: 0x0000001c
- EXCVADDR: 0xfb00005e LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
- Backtrace: 0x401178b9:0x3ffb1e60 0x400d200d:0x3ffb1ec0 0x400d76e1:0x3ffb1fb0 0x4008db91:0x3ffb1fd0
- Rebooting...
Using Arduino ide 2.2.1
ESP32 1.0.4 Core
ESP32_CAM Module
I also tried:
External power
Code from main example in app_httpd.cpp file
Code from Fr-flash library
Main code is:
- #include "esp_camera.h"
- #include <WiFi.h>
- #include <WebSocketsServer.h>
- #include <EEPROM.h>
- #include <Preferences.h>
- #include <stdio.h>
- #include "driver/uart.h"
- #include "driver/gpio.h"
- #include "sdkconfig.h"
- #define CAMERA_MODEL_AI_THINKER
- #include "camera_pins.h"
- /////////////face detection?//////////////////
- #include "fb_gfx.h"
- #include "fd_forward.h"
- #include "fr_forward.h"
- #include <fr_flash.h>
- #define FACE_COLOR_WHITE 0x00FFFFFF
- #define FACE_COLOR_BLACK 0x00000000
- #define FACE_COLOR_RED 0x000000FF
- #define FACE_COLOR_GREEN 0x0000FF00
- #define FACE_COLOR_BLUE 0x00FF0000
- #define FACE_COLOR_YELLOW (FACE_COLOR_RED | FACE_COLOR_GREEN)
- #define FACE_COLOR_CYAN (FACE_COLOR_BLUE | FACE_COLOR_GREEN)
- #define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED)
- static int8_t recognition_enabled = 1;
- static int8_t is_enrolling = 0;
- #define ENROLL_CONFIRM_TIMES 5
- #define FACE_ID_SAVE_NUMBER 7
- face_id_list id_list = {0};
- // Face detection/recognition variables
- camera_fb_t *fb; // Frame buffer pointer for picture from camera
- box_array_t *detected_face; // Information for a detected face
- dl_matrix3du_t *image_matrix; // Image matrix pointer
- dl_matrix3du_t *aligned_face; // Aligned face pointer
- //dl_matrix3d_t *face_id; // Face ID pointer
- face_id_node *face_recognized; // Recognized face pointer
- mtmn_config_t mtmn_config; // MTMN detection settings
- char enroll_name[ENROLL_NAME_LEN+1]; // Name for face ID to be stored
- face_id_name_list st_face_list;
- const int numReadings = 5;
- int readings[numReadings]; // the readings from the analog input
- int readIndex = 0; // the index of the current reading
- int total = 0; // the running total
- int average_face_size = 0; // the average
- int face_distance;
- int face_id = 0;
- char time_str[40];
- typedef struct
- {
- char enroll_name[ENROLL_NAME_LEN];
- } httpd_resp_value;
- httpd_resp_value st_name ;
- typedef struct
- {
- uint8_t *image;
- box_array_t *net_boxes;
- dl_matrix3d_t *face_id;
- } http_img_process_result;
- /////////////face detection?//////////////////
- Preferences prefs;
- const uint8_t* ssid2;
- String cmd;
- char inByte;
- bool commandEnd=0;
- WebSocketsServer webSocket = WebSocketsServer(9898);
- WebSocketsServer webSocket2 = WebSocketsServer(8888);
- WebSocketsServer webSocket3 = WebSocketsServer(8585);
- bool isClientConnected;
- static void rgb_print(dl_matrix3du_t *image_matrix, uint32_t color, const char * str){
- fb_data_t fb;
- fb.width = image_matrix->w;
- fb.height = image_matrix->h;
- fb.data = image_matrix->item;
- fb.bytes_per_pixel = 3;
- fb.format = FB_BGR888;
- fb_gfx_print(&fb, (fb.width - (strlen(str) * 14)) / 2, 10, color, str);
- }
- static int rgb_printf(dl_matrix3du_t *image_matrix, uint32_t color, const char *format, ...){
- char loc_buf[64];
- char * temp = loc_buf;
- int len;
- va_list arg;
- va_list copy;
- va_start(arg, format);
- va_copy(copy, arg);
- len = vsnprintf(loc_buf, sizeof(loc_buf), format, arg);
- va_end(copy);
- if(len >= sizeof(loc_buf)){
- temp = (char*)malloc(len+1);
- if(temp == NULL) {
- return 0;
- }
- }
- vsnprintf(temp, len+1, format, arg);
- va_end(arg);
- rgb_print(image_matrix, color, temp);
- if(len > 64){
- free(temp);
- }
- return len;
- }
- static inline int do_enrollment(face_id_name_list *face_list, dl_matrix3d_t *new_id)
- {
- ESP_LOGD(TAG, "START ENROLLING");
- int left_sample_face = enroll_face_id_to_flash_with_name(face_list, new_id, st_name.enroll_name);
- ESP_LOGD(TAG, "Face ID %s Enrollment: Sample %d",
- st_name.enroll_name,
- ENROLL_CONFIRM_TIMES - left_sample_face);
- return left_sample_face;
- }
- static int run_face_recognition(dl_matrix3du_t *image_matrix, box_array_t *net_boxes){
- dl_matrix3du_t *aligned_face = NULL;
- int matched_id = 0;
- aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3);
- if(!aligned_face){
- Serial.println("Could not allocate face recognition buffer");
- return matched_id;
- }
- if (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK){
- matched_id = recognize_face(&id_list, aligned_face);
- if (matched_id >= 0) {
- Serial.printf("Match Face ID: %u\n", matched_id);
- rgb_printf(image_matrix, FACE_COLOR_GREEN, "Sorush", matched_id);
- } else {
- //Serial.println("No Match Found");
- rgb_print(image_matrix, FACE_COLOR_RED, "Not Sorush!");
- matched_id = -1;
- }
- }else {
- //Serial.println("Face Not Aligned");
- //rgb_print(image_matrix, FACE_COLOR_YELLOW, "Human Detected");
- }
- dl_matrix3du_free(aligned_face);
- return matched_id;
- }
- static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes)
- {
- int x, y, w, h, i, half_width, half_height;
- uint32_t color = FACE_COLOR_YELLOW;
- if(face_id < 0){
- color = FACE_COLOR_RED;
- } else if(face_id > 0){
- color = FACE_COLOR_GREEN;
- }
- fb_data_t fb;
- fb.width = image_matrix->w;
- fb.height = image_matrix->h;
- fb.data = image_matrix->item;
- fb.bytes_per_pixel = 3;
- fb.format = FB_BGR888;
- for (i = 0; i < boxes->len; i++) {
- // Convoluted way of finding face centre...
- x = ((int)boxes->box[i].box_p[0]);
- w = (int)boxes->box[i].box_p[2] - x + 1;
- half_width = w / 2;
- int face_center_pan = x + half_width; // current face centre x co-ordinate
- y = (int)boxes->box[i].box_p[1];
- h = (int)boxes->box[i].box_p[3] - y + 1;
- half_height = h / 2;
- int face_center_tilt = y + half_height; // current face centre y co-ordinate
- //Serial.println(h);
- fb_gfx_drawFastHLine(&fb, x, y, w, color);
- fb_gfx_drawFastHLine(&fb, x, y + h - 1, w, color);
- fb_gfx_drawFastVLine(&fb, x, y, h, color);
- fb_gfx_drawFastVLine(&fb, x + w - 1, y, h, color);
- // subtract the last reading:
- total = total - readings[readIndex];
- // add current face height:
- readings[readIndex] = h;
- // add the reading to the total:
- total = total + readings[readIndex];
- // advance to the next position in the array:
- readIndex = readIndex + 1;
- // if we're at the end of the array...
- if (readIndex >= numReadings) {
- // ...wrap around to the beginning:
- readIndex = 0;
- }
- // calculate the average:
- average_face_size = total / numReadings;
- int eq_top = 3.6 * 200 * 240; //f(mm) x real height(mm) x image height(px)
- int eq_bottom = average_face_size * 2.7; //object height(px) x sensor height(mm)
- int face_distance = eq_top / eq_bottom;
- /*Serial.print('<'); // start marker
- Serial.print(face_center_pan);
- Serial.print(','); // comma separator
- Serial.print(face_center_tilt);
- Serial.print(','); // comma separator
- Serial.print(face_distance);
- Serial.println('>'); // end marker*/
- Serial.print("pan=");
- Serial.println(face_center_pan);
- Serial.print("tilt=");
- Serial.println(face_center_tilt);
- Serial.print("distance=");
- Serial.println(face_distance);
- }
- }
- void saveSSID(uint8_t ssid[]){
- prefs.putBytes("ssid", ssid, sizeof(ssid));
- }
- void savePassword(uint8_t pass[]){
- prefs.putBytes("password", pass, sizeof(pass));
- }
- char* getSSID(){
- size_t cfgLen = prefs.getBytesLength("ssid");
- char buffer[cfgLen];
- prefs.getBytes("ssid", buffer, cfgLen);
- return buffer;
- }
- char* getPassword(){
- size_t cfgLen = prefs.getBytesLength("password");
- char buffer[cfgLen];
- prefs.getBytes("password", buffer, cfgLen);
- return buffer;
- }
- void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
- switch(type) {
- case WStype_DISCONNECTED:
- {
- webSocket.sendTXT(num, "Disconnected!");
- }
- break;
- case WStype_CONNECTED:
- {
- IPAddress ip = webSocket.remoteIP(num);
- Serial.print("Connected IP address:");
- Serial.println(ip);
- isClientConnected = true;
- webSocket.sendTXT(num, "phase2");
- webSocket.sendTXT(num, "connected");
- }
- break;
- case WStype_TEXT:
- {
- String msg = (char*)payload;
- Serial.println(msg);
- if(msg.startsWith("ssid=")){
- ssid2 = reinterpret_cast<const uint8_t*>(msg.substring(5).c_str());
- //EEP_Write_String(1,msg);
- //Serial.print("aaaaaaaaaaaaaaaa");
- //Serial.println(ssid2.toString());
- String s = msg.substring(5);
- prefs.begin("config");
- prefs.begin("ssid");
- prefs.putBytes("ssid", s.c_str() , sizeof(s));
- }
- else if(msg.startsWith("password=")){
- const uint8_t* pass = reinterpret_cast<const uint8_t*>(msg.substring(9).c_str());
- //EEP_Write_String(3,"12345678");
- //prefs.putBytes("password", pass, sizeof(pass));
- }
- else if(msg.startsWith("getSSID")){
- size_t cfgLen = prefs.getBytesLength("ssid");
- char ssid[cfgLen];
- //prefs.getBytes("ssid", ssid, cfgLen);
- webSocket.sendTXT(num, msg + "=" + "ssid");
- }
- else if(msg.startsWith("getPassword")){
- size_t cfgLen = prefs.getBytesLength("password");
- char pass[cfgLen];
- //prefs.getBytes("password", pass, cfgLen);
- webSocket.sendTXT(num, msg + "=" + "pass");
- }
- else if(msg.startsWith("uv-true")){
- is_enrolling = 1;
- //prefs.getBytes("password", pass, cfgLen);
- webSocket.sendTXT(num, "enrolling");
- }
- else {
- //webSocket.sendTXT(num, msg);
- }
- }
- case WStype_BIN:
- case WStype_ERROR:
- case WStype_FRAGMENT_TEXT_START:
- case WStype_FRAGMENT_BIN_START:
- case WStype_FRAGMENT:
- case WStype_FRAGMENT_FIN:
- break;
- }
- }
- void webSocketEvent3(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
- switch(type) {
- case WStype_DISCONNECTED:
- {
- Serial.println("DC");
- }
- break;
- case WStype_CONNECTED:
- {
- isClientConnected = true;
- Serial.println("C");
- }
- break;
- }
- }
- void setup() {
- Serial.begin(9600);
- Serial.println();
- prefs.begin("config");
- prefs.begin("ssid");
- prefs.begin("password");
- size_t cfgLen = prefs.getBytesLength("config");
- char buffer[cfgLen];
- prefs.getBytes("config", buffer, cfgLen);
- uint8_t ssidd[] = "Aibot";
- uint8_t passs[] = "11223344";
- prefs.putBytes("ssid", ssidd, sizeof(ssidd));
- prefs.putBytes("password", passs, sizeof(passs));
- size_t cfgLen3 = prefs.getBytesLength("ssid");
- char ssid[cfgLen3];
- prefs.getBytes("ssid", ssid, cfgLen3);
- //Serial.print("serialllllllllllllllllllll");
- Serial.println(ssid);
- size_t cfgLen4 = prefs.getBytesLength("password");
- char pass[cfgLen4];
- prefs.getBytes("password", pass, cfgLen4);
- camera_config_t config;
- config.ledc_channel = LEDC_CHANNEL_0;
- config.ledc_timer = LEDC_TIMER_0;
- config.pin_d0 = Y2_GPIO_NUM;
- config.pin_d1 = Y3_GPIO_NUM;
- config.pin_d2 = Y4_GPIO_NUM;
- config.pin_d3 = Y5_GPIO_NUM;
- config.pin_d4 = Y6_GPIO_NUM;
- config.pin_d5 = Y7_GPIO_NUM;
- config.pin_d6 = Y8_GPIO_NUM;
- config.pin_d7 = Y9_GPIO_NUM;
- config.pin_xclk = XCLK_GPIO_NUM;
- config.pin_pclk = PCLK_GPIO_NUM;
- config.pin_vsync = VSYNC_GPIO_NUM;
- config.pin_href = HREF_GPIO_NUM;
- config.pin_sscb_sda = SIOD_GPIO_NUM;
- config.pin_sscb_scl = SIOC_GPIO_NUM;
- config.pin_pwdn = PWDN_GPIO_NUM;
- config.pin_reset = RESET_GPIO_NUM;
- config.xclk_freq_hz = 10000000;
- config.pixel_format = PIXFORMAT_JPEG;
- //init with high specs to pre-allocate larger buffers
- if(psramFound()){
- config.frame_size = FRAMESIZE_QVGA;//VGA
- config.jpeg_quality = 10;
- config.fb_count = 2;
- } else {
- config.frame_size = FRAMESIZE_QVGA;//SVGA
- config.jpeg_quality = 12;
- config.fb_count = 1;
- }
- mtmn_config = mtmn_init_config(); // Set MTMN face detection details (default values)
- image_matrix = dl_matrix3du_alloc(1, 320, 240, 3); // Allocate memory for image matrix
- aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3); // Allocate memory for aligned face
- // camera init
- esp_err_t err = esp_camera_init(&config);
- if (err != ESP_OK) {
- Serial.printf("Camera init failed with error 0x%x", err);
- return;
- }
- delay(1000);
- WiFi.softAP(ssid, pass);
- IPAddress IP = WiFi.softAPIP();
- Serial.print("AP IP address: ");
- Serial.println(IP);
- webSocket.begin();
- webSocket.onEvent(webSocketEvent);
- webSocket2.begin();
- webSocket3.begin();
- webSocket3.onEvent(webSocketEvent3);
- }
- void loop() {
- webSocket.loop();
- webSocket2.loop();
- webSocket3.loop();
- if(isClientConnected){
- camera_fb_t *fb = NULL;
- esp_err_t res = ESP_OK;
- fb = esp_camera_fb_get();
- if(!fb){
- Serial.println("Camera capture failed");
- esp_camera_fb_return(fb);
- return;
- }
- face_id = 0;
- size_t fb_len = 0;
- uint8_t * _jpg_buf = NULL;
- dl_matrix3du_t *image_matrix = NULL;
- if(fb->format != PIXFORMAT_JPEG){
- Serial.println("Non-JPEG data not implemented");
- return;
- }
- fb_len = fb->len;
- _jpg_buf = fb->buf;
- image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3);
- fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item);
- box_array_t *net_boxes = NULL;
- net_boxes = face_detect(image_matrix, &mtmn_config);
- if (net_boxes) {
- if(recognition_enabled){
- face_id = run_face_recognition(image_matrix, net_boxes);
- }
- draw_face_boxes(image_matrix, net_boxes);
- free(net_boxes->score);
- free(net_boxes->box);
- free(net_boxes->landmark);
- free(net_boxes);
- }
- fmt2jpg(image_matrix->item, fb->width * fb->height * 3, fb->width, fb->height, PIXFORMAT_RGB888, 90, &_jpg_buf, &fb_len);
- ////////////////////////////////Video Stream////////////////////////////////
- webSocket2.broadcastBIN((const uint8_t*) _jpg_buf, fb_len);
- ////////////////////////////////Video Stream////////////////////////////////
- esp_camera_fb_return(fb);
- fb = NULL;
- dl_matrix3du_free(image_matrix);
- free(_jpg_buf);
- _jpg_buf = NULL;
- /////////////////////////////face detection////////////////////////////////
- if(is_enrolling){
- if (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK )
- {
- http_img_process_result out_res = {0};
- out_res.image = image_matrix->item;
- int left_sample_face = do_enrollment(&st_face_list, out_res.face_id);
- char enrolling_message[64];
- sprintf(enrolling_message, "SAMPLE NUMBER %d FOR %s", ENROLL_CONFIRM_TIMES - left_sample_face, st_name.enroll_name);
- webSocket.broadcastTXT(enrolling_message);
- if (left_sample_face == 0)
- {
- ESP_LOGI(TAG, "Enrolled Face ID: %s", st_face_list.tail->id_name);
- char captured_message[64];
- sprintf(captured_message, "FACE CAPTURED FOR %s", st_face_list.tail->id_name);
- is_enrolling = 0;
- webSocket.broadcastTXT(captured_message);
- }
- }
- }
- /////////////////////////////face detection////////////////////////////////
- /*char qwe = Serial.read();
- String asd;
- asd=qwe;
- webSocket.sendTXT(sizeof(asd),asd);*/
- ///////////////////////////////////////////////////////////////
- if(Serial.available() > 0){
- if(commandEnd){
- cmd="";
- commandEnd=false;
- }
- inByte = Serial.read();
- if (inByte != '\n') {
- cmd += inByte;
- }else{
- webSocket.broadcastTXT(cmd);
- commandEnd=true;
- }
- }
- ////////////////////////////////////////////////////////////////
- }
- }
- //*****************************************************************************
- // Handle uptime request
- // Last start date/time and free heap size (to detect memory leaks)
- //
- void handleUptime() {
- char text[80];
- snprintf(text, 80, "Last start: %s \nFree Heap: %d\n", time_str, ESP.getFreeHeap());
- //webSocket.broadcastTXT(200, "text/plain", text);
- }
also the previous code leads to the same error:
- static int run_face_recognition(dl_matrix3du_t *image_matrix, box_array_t *net_boxes){
- dl_matrix3du_t *aligned_face = NULL;
- int matched_id = 0;
- aligned_face = dl_matrix3du_alloc(1, FACE_WIDTH, FACE_HEIGHT, 3);
- if(!aligned_face){
- Serial.println("Could not allocate face recognition buffer");
- return matched_id;
- }
- if (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK){
- if (is_enrolling == 1){
- int8_t left_sample_face = enroll_face(&id_list, aligned_face);
- if(left_sample_face == (ENROLL_CONFIRM_TIMES - 1)){
- Serial.printf("Enrolling Face ID: %d\n", id_list.tail);
- }
- Serial.printf("Enrolling Face ID: %d sample %d\n", id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face);
- rgb_printf(image_matrix, FACE_COLOR_CYAN, "ID[%u] Sample[%u]", id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face);
- if (left_sample_face == 0){
- is_enrolling = 0;
- Serial.printf("Enrolled Face ID: %d\n", id_list.tail);
- }
- } else {
- matched_id = recognize_face(&id_list, aligned_face);
- if (matched_id >= 0) {
- Serial.printf("Match Face ID: %u\n", matched_id);
- rgb_printf(image_matrix, FACE_COLOR_GREEN, "Hello Subject %u", matched_id);
- } else {
- Serial.println("No Match Found");
- rgb_print(image_matrix, FACE_COLOR_RED, "Intruder Alert!");
- matched_id = -1;
- }
- }
- } else {
- Serial.println("Face Not Aligned");
- //rgb_print(image_matrix, FACE_COLOR_YELLOW, "Human Detected");
- }
- dl_matrix3du_free(aligned_face);
- return matched_id;
- }