-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
Board
Firebeetle2 ESP32-S3
Device Description
Firebeetle2 ESP32-S3 with OV2640 camera attached.
Hardware Configuration
OV2640 68degree standard camera (note that face-detection seems to work even more poorly with wide-angle cameras!)
I also use an active-buzzer on pin A5, but this is not necessary as "Got Face" is also printed to the Serial-terminal.
Version
latest master (checkout manually)
IDE Name
Arduino IDE v1.8.19
Operating System
Windows10
Flash frequency
80Mz
PSRAM enabled
yes
Upload speed
921600
Description
Face-Detecton on ESP32-S3 does not work nearly as well using the below sketch WITHOUT wifi, as it does for the default "Examples/ESP32/Camera/CameraWebServer" wifi example.
This using identical camera-setup (OV2640 68degree standard camera, PIXFORMAT_RGB565, FRAMESIZE_240X240), and identical "TWO_STAGE" face-detection, and running the below "look_for_faces()" task on Core0, which is where I beleive the equivalent "app_httpd.cpp" task is run for the wifi-example.
NB. CONFIG_ESP_FACE_DETECT_ENABLED=1 enabled CONFIG_ESP_FACE_RECOGNITION_ENABLED=0 (ie. detection NOT recognition)
Specifically the below sketch only finds a face if the face is approx 30cm to 45cm away and pretty much in the exact centre of the frame; whereas the "Examples/ESP32/Camera/CameraWebServer" wifi example with identical setup will finds a face pretty reliably between 30cm and 60cm away, and almost anywhere from -22degrees to +22degrees (45degrees total) horizontally from the centre of the frame.
NB. I am using "github.com/espressif/arduino-esp32" as at 16Jan23.
[as the "Examples/ESP32/Camera/CameraWebServer - FACE_DETECT" doesn't work on the current github when using the above ESP32-S3. On the current github 11May24 you even have to modify the example sketch by moving the WiFi.begin() above the esp_camera_init() or else it wont even connect to the wifi, but even then face-detection doesn't work. (Arduino-on-core1, Events-on-core1-or-core0.)] <- Ignore this as I suspect my github 11May24 software was corrupted.
But note that this below (non-wifi) sketch runs the same on both github v16Jan23 and github v11May24.
Sketch
// Note that this below (non-wifi) sketch runs the same on both github v16Jan23 and gitub v11May24.
#ifndef BOARD_HAS_PSRAM
#error This sketch needs psram
#endif
#define TWO_STAGE 1
#include "esp_camera.h"
#include <WiFi.h>
#define BEEP_PIN_active A5
#define CAMERA_WIRING_FB2_0V2640
#ifdef CAMERA_WIRING_FB2_0V2640
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 45
#define SIOD_GPIO_NUM 1
#define SIOC_GPIO_NUM 2
#define Y9_GPIO_NUM 48
#define Y8_GPIO_NUM 46
#define Y7_GPIO_NUM 8 // A3
#define Y6_GPIO_NUM 7 // D5
#define Y5_GPIO_NUM 4 // A0
#define Y4_GPIO_NUM 41
#define Y3_GPIO_NUM 40
#define Y2_GPIO_NUM 39
#define VSYNC_GPIO_NUM 6 // A2
#define HREF_GPIO_NUM 42
#define PCLK_GPIO_NUM 5 // A1
#include "DFRobot_AXP313A.h"
DFRobot_AXP313A axp;
#endif
#include "human_face_detect_msr01.hpp"
#include "human_face_detect_mnp01.hpp"
TaskHandle_t My_Task;
void setup() {
WiFi.mode(WIFI_OFF); // Necessary as otherwise seems to effect core0 speed
pinMode(BEEP_PIN_active, OUTPUT); beep(3); // 100*5 = 1secs
Serial.begin(115200);
Serial.println("Start up\n--------");
Serial.print("setup/loop running on core="); Serial.println(xPortGetCoreID());
psramInit();
if (psramFound()) {
int spare = ESP.getFreePsram();
Serial.printf("PSRAM=%i/%ikB\n", spare/1024, ESP.getPsramSize()/1024);
if (spare == 0) Serial.println("Err: PSRAM issue");
} else Serial.println("Err: PSRAM issue");
#ifdef CAMERA_WIRING_FB2_0V2640
Serial.println("Do axp.begin...");
while (axp.begin()!=0) {Serial.println("\nERR: axp.begin fail\n"); delay(1000);}
Serial.println("D0 axp.enableCameraPower...");
axp.enableCameraPower(axp.eOV2640); //Enable the power for camera
delay(2000);
#endif
if (!initialiseCamera()) Serial.println("Err: initialiseCamera FAILED");
else{
Serial.print("Camera OK, staring look_for_faces...\n");
xTaskCreatePinnedToCore(
look_for_faces
, "look_for_faces"
, (2048+512) // Stack size // 2048->uxTaskGetStackHighWaterMark=32, with occasional crashes
, NULL
, (configMAX_PRIORITIES-2) // Priority
, &My_Task
, 0); // Core0
}
}
void loop() {
delay(8000);
Serial.printf("uxTaskGetStackHighWaterMark=%i\n",uxTaskGetStackHighWaterMark(My_Task));
}
void beep(int count) { // count==0 gives a short-pip
int max_x; if (count) max_x = count * 2; else max_x = 2;
boolean toggle = true;
for (int x = 1; x <= max_x; x++) {
digitalWrite(BEEP_PIN_active, toggle);
toggle = !toggle;
if (x < max_x) {if (count) delay(100); else delay(50);}
} }
bool initialiseCamera() {
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.jpeg_quality = 10; // 0-63 lower number means higher quality (can cause failed image capture if set too low at higher resolutions)
config.fb_location = CAMERA_FB_IN_PSRAM;
config.grab_mode = CAMERA_GRAB_LATEST;
config.fb_count = 1; // if RGB
config.xclk_freq_hz = 10000000; // seems better than 20MHz
config.pixel_format = PIXFORMAT_RGB565;
config.frame_size = FRAMESIZE_240X240;
esp_err_t cam_err = esp_camera_init(&config); // initialise the camera
if (cam_err!=ESP_OK) Serial.printf("Err: Camera init failed with error 0x%x\n", cam_err);
else Serial.println("Camera using RGB at 240x240");
return (cam_err==ESP_OK);
}
void look_for_faces(void * pvParameters) {
(void) pvParameters;
Serial.printf("Task is running on core=%i\n",xPortGetCoreID());
camera_fb_t *fb = NULL;
#if TWO_STAGE
HumanFaceDetectMSR01 s1(0.1F, 0.5F, 10, 0.2F);
HumanFaceDetectMNP01 s2(0.5F, 0.3F, 5);
#else
#error
#endif
for (;;) {
fb = esp_camera_fb_get();
if (!fb) Serial.println("Camera capture failed");
else {
if ((fb->width) > 400) Serial.println("size too big");
else {
if (fb->format == PIXFORMAT_RGB565) {
#if TWO_STAGE
std::list<dl::detect::result_t> &candidates = s1.infer((uint16_t *)fb->buf, {(int)fb->height, (int)fb->width, 3});
std::list<dl::detect::result_t> &results = s2.infer((uint16_t *)fb->buf, {(int)fb->height, (int)fb->width, 3}, candidates);
#endif
if (results.size() > 0) {beep(0); Serial.println("Got Face");}
}
}
}
if (fb) {esp_camera_fb_return(fb); fb = NULL;}
// vTaskDelay(1 / portTICK_PERIOD_MS); // 1ms // portTICK_PERIOD_MS=1
}
}
Debug Message
n/a
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.