有一个名为 CameraWebServer 的 esp32 摄像头示例代码,在其中您可以流式传输 esp32 摄像头的视频输出,并且有一个打开面部识别的选项,所以我问我如何访问面部的坐标esp32 cam 正在检测。
我尝试在谷歌中寻找答案并使用chatGPT,但我发现没有任何效果
我遇到了确切的问题,因为我正在使用 ESP32-Cam 构建面部跟踪系统,并设法弄清楚如何在不使用网络服务器的情况下获取面部位置,但我不确定如何使用这些信息每当我使用 ESP32-Cam 运行伺服系统时,它都会自行重置,因为相机功能和伺服功能会相互干扰。 我首先使用了来自 https://robotzero.one/face-tracking-esp32-cam/ 的旧面部跟踪代码 要使其运行,您需要首先安装 ESP32 库版本 1.0.4,因为新版本不起作用。 然后,我删除了代码中所有 WiFi 和网络服务器部分,现在只要运行它,我就可以在串行端口上获取 320x240 图像大小上的脸部屏幕位置,而无需将其连接为网络服务器。 下一阶段是从属 Arduino nano 并使用我正在研究的 I2C 接口获取数据。
这是当前通过串口读取人脸位置数据的代码,希望对您有所帮助。除了此代码之外,您还需要下载 上面链接中的camera_index.h和camera_pins.h并将它们放在同一目录中。
// MoveHead_ESP_V1_5
// Board AI Thinker ESP-CAM
// This module requires ESP32 ver 1.0.4 to run
// This works identifying the face position without the need of server
#include <ArduinoWebsockets.h>
#include "camera_index.h"
#include "esp_camera.h"
#include "fb_gfx.h"
#include "fd_forward.h"
#include <Wire.h>
// ESP32-CAM doesn't have dedicated i2c pins, so we define our own. Let's choose 15 and 14
#define I2C_SDA 15
#define I2C_SCL 14
TwoWire I2Cbus = TwoWire(0);
int NewPositionX=0;
int NewPositionY=0;
int ScreenPosX = 0;
int ScreenPosY=0;
int ScreenSizeX = 320;
int ScreenSizeY=240;
int MinPan = 30;
int MaxPan = 150;
int MinTilt = 0;
int MaxTilt = 55;
#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"
static inline mtmn_config_t app_mtmn_config()
{
mtmn_config_t mtmn_config = {0};
mtmn_config.type = FAST;
mtmn_config.min_face = 80;
mtmn_config.pyramid = 0.707;
mtmn_config.pyramid_times = 4;
mtmn_config.p_threshold.score = 0.6;
mtmn_config.p_threshold.nms = 0.7;
mtmn_config.p_threshold.candidate_number = 20;
mtmn_config.r_threshold.score = 0.7;
mtmn_config.r_threshold.nms = 0.7;
mtmn_config.r_threshold.candidate_number = 10;
mtmn_config.o_threshold.score = 0.7;
mtmn_config.o_threshold.nms = 0.7;
mtmn_config.o_threshold.candidate_number = 1;
return mtmn_config;
}
mtmn_config_t mtmn_config = app_mtmn_config();
void setup()
{
Serial.begin(115200);
Serial.println("Loadong...");
Serial.println();
// Initialize I2C with our defined pins
I2Cbus.begin(I2C_SDA, I2C_SCL, 100000);
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 = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
//init with high specs to pre-allocate larger buffers
if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
#if defined(CAMERA_MODEL_ESP_EYE)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
// 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;
}
sensor_t * s = esp_camera_sensor_get();
s->set_framesize(s, FRAMESIZE_QVGA);
}
static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes)
{
int x, y, w, h, i, half_width, half_height;
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; // image frame 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; // image frame face centre y co-ordinate
// assume QVGA 320x240
// int sensor_width = 320;
// int sensor_height = 240;
// int lens_fov = 45
Serial.print("Face:");
Serial.print(face_center_pan);
Serial.print(" X ");
Serial.print(face_center_tilt);
// Map the screen positions to Servo positions
NewPositionX = map(face_center_pan, 0, ScreenSizeX, MinPan, MaxPan);
NewPositionY = map(face_center_tilt, 0, ScreenSizeY, MinTilt, MaxTilt);
// Display X,Y screen coordinate, speed, Pan and Tilt
Serial.print(" Pan:");
Serial.print(NewPositionX);
Serial.print(" Tilt:");
Serial.println(NewPositionY);
// this doesn't work, it seems that the servo interfere with the camera
// this is the place to use I2C to send the pan and tilt position to Arduino via I2C
}
}
void loop()
{
// auto client = socket_server.accept();
camera_fb_t * fb = NULL;
dl_matrix3du_t *image_matrix = NULL;
while (true) {
fb = esp_camera_fb_get();
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) {
draw_face_boxes(image_matrix, net_boxes);
free(net_boxes->score);
free(net_boxes->box);
free(net_boxes->landmark);
free(net_boxes);
}
esp_camera_fb_return(fb);
fb = NULL;
dl_matrix3du_free(image_matrix);
}
}