高级会员
- 积分
- 602
- 金钱
- 602
- 注册时间
- 2013-10-18
- 在线时间
- 59 小时
|
网上基本找不到可以用的ESP32 cam SDK做TCP通讯的例子,ESP8266速度达不到网络摄像头要求的速度。只能转战ESP32,自己移植camera驱动,例子基本思路
1、上位机采用C#编写,包涵普通串口功能,百度AI实时进行人脸识别
public void FaceReg(string[] args)
{
// 设置APPID/AK/SK
var API_KEY = "**************************"; //你的 Api Key
var SECRET_KEY = "***************************"; //你的 Secret Key
var client = new Baidu.Aip.Face.Face(API_KEY, SECRET_KEY);
client.Timeout = 60000; // 修改超时时间
//取决于image_type参数,传入BASE64字符串或URL字符串或FACE_TOKEN字符串
//你共享的图片路径(点击路径可直接查看图片)
//var image = "http://bj.bcebos.com/v1/aip-web/48EBCB80FF7C4DCA9E0139425B76F078?authorization=bce-auth-v1/f86a2044998643b5abc89b59158bad6d/2018-07-27T07:45:30Z/-1//07fd154d3456eea9104b7c467efc0d43aceb7609d1635246d8fdb1272b0cea30";
//注册第1张人脸
var value = File.ReadAllBytes("./人脸注册库/钱大大.JPG");
string image = Convert.ToBase64String(value);
//var imageType = "BASE64";
var imageType = "BASE64";
//注册人脸
var groupId = "Group1";
var userId = "qian_xiao_ping";
// 调用人脸注册,可能会抛出网络等异常,请使用try/catch捕获
//var result = client.UserAdd(image, imageType, groupId, userId);
//注册第二张人脸
var value444 = File.ReadAllBytes("./人脸注册库/美女.JPG");
string image444 = Convert.ToBase64String(value444);
var userId2 = "fan_hai_hong";
// var result1 = client.UserAdd(image444, imageType, groupId, userId2);
//注册第3张人脸
var value555 = File.ReadAllBytes("./人脸注册库/苏小小.JPG");
string image555 = Convert.ToBase64String(value555);
var userId555 = "qian_yi";
//var result555 = client.UserAdd(image555, imageType, groupId, userId555);
//注册第4张人脸
var value123 = File.ReadAllBytes("./人脸注册库/小李子.JPG");
string image123 = Convert.ToBase64String(value123);
var userId123 = "xiao_li_zi";
//var result666 = client.UserAdd(image123, imageType, groupId, userId123);
// Console.WriteLine(result);
// 如果有可选参数
/*var options = new Dictionary<string, object>{
{"user_info", "user's info"},
{"quality_control", "NORMAL"},
{"liveness_control", "LOW"}
};*/
var options = new Dictionary<string, object>
{
/*{"max_face_num", 3},
{"match_threshold", 70},
{"quality_control", "NORMAL"},
{"liveness_control", "LOW"},*/
// {"user_id", "user1"},
{"max_user_num", 1}
};
// 带参数调用人脸注册
//result = client.UserAdd(image, imageType, groupId, userId, options);
//Console.WriteLine(result);
//比对
string image2 = Convert.ToBase64String(TcparrMsgRecCopy);
/* MemoryStream ms = new MemoryStream(TcparrMsgRecCopy);//文件形式//MemoryStream ms = new MemoryStream(byDataReal);非文件形式
ms.Position = 0;
// image999.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
JPEG_TCP = Image.FromStream(ms);
JPEG_TCP.Save("./qxp2.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Close();
var value2 = File.ReadAllBytes("./qxp2.JPG");
string image2 = Convert.ToBase64String(value2);*/
/////////////////相似度查找/////////////////////
var groupIdList = "Group1";
// 调用人脸搜索,可能会抛出网络等异常,请使用try/catch捕获
var result5 = client.Search(image2, imageType, groupIdList, options);
// var result5 = client.MultiSearch(image2, imageType, groupIdList);
string bbb = result5.ToString();
int Indexofcc = bbb.IndexOf("error_code");
int Indexofdd = bbb.IndexOf("error_msg");
//根据索引截取
string str20 = bbb.Substring(Indexofcc+13, 1);
if (str20 == "0")
{
try
{
this.Invoke((EventHandler)(delegate
{
//获取相似度
string xxx = result5.ToString();
int IndexofA = xxx.IndexOf("score");
int IndexofB = xxx.IndexOf(",");
//根据索引截取
string str = xxx.Substring(IndexofA + 8, IndexofB);
label12.Text = str;
//获取姓名
string yyy = result5.ToString();
int IndexofA1 = xxx.IndexOf("user_id");
int IndexofB1 = xxx.IndexOf("user_info");
//根据索引截取
string stryyy = xxx.Substring(IndexofA1 + 11, IndexofB1 - IndexofA1 - 24);
// label16.Text = stryyy;显示百度云平台返回的姓名
if (stryyy == "qian_yi")
{
//显示库中的图片
pictureBox2.Image = new Bitmap("./人脸注册库/钱小小.JPG");
pictureBox2.Refresh();
label16.Text = "钱小小";
}
else if (stryyy == "qian_xiao_ping")
{
//显示库中的图片
pictureBox2.Image = new Bitmap("./人脸注册库/钱大大.JPG");
pictureBox2.Refresh();
label16.Text = "钱大大";
}
else if (stryyy == "fan_hai_hong")
{
//显示库中的图片
pictureBox2.Image = new Bitmap("./人脸注册库/美女.JPG");
pictureBox2.Refresh();
label16.Text = "美女";
}
else if (stryyy == "xiao_li_zi")
{
//显示库中的图片
pictureBox2.Image = new Bitmap("./人脸注册库/小李子.JPG");
pictureBox2.Refresh();
label16.Text = "小李子";
}
else { }
//label12.Text = result5.Last.First.Last.First.First.Last.ToString();
})
);
}
catch
{
}
}
//var result6 = client.Search(image3, imageType, groupIdList);
}
2、终端采用ESP32CAM模块,使用乐鑫IDF环境进行编程,移植esp32-camera驱动。采集完图像后马上进行TCP传输
目前例程还有点粗糙,共勉。
static void tcp_client_task(void *pvParameters)
{
char host_ip[] = HOST_IP_ADDR;
int addr_family = 0;
int ip_protocol = 0;
while (1) {
#if defined(CONFIG_EXAMPLE_IPV4)
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(host_ip);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
#elif defined(CONFIG_EXAMPLE_IPV6)
struct sockaddr_in6 dest_addr = { 0 };
inet6_aton(host_ip, &dest_addr.sin6_addr);
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(PORT);
dest_addr.sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
addr_family = AF_INET6;
ip_protocol = IPPROTO_IPV6;
#elif defined(CONFIG_EXAMPLE_SOCKET_IP_INPUT_STDIN)
struct sockaddr_in6 dest_addr = { 0 };
ESP_ERROR_CHECK(get_addr_from_stdin(PORT, SOCK_STREAM, &ip_protocol, &addr_family, &dest_addr));
#endif
int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (sock < 0) {
ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT);
int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in6));
if (err != 0) {
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
break;
}
ESP_LOGI(TAG, "Successfully connected");
camera_init_app();
while (1)
{
camera_run();
//errno=Get_dma_received_count();
// ESP_LOGE(TAG, "Get_dma_received_count: errno %d", errno);
errno=camera_get_data_size();
//ESP_LOGE(TAG, "camera_get_data_size: errno %d", errno);
fb=camera_get_fb();
/*camera_fb_t * fb,
typedef struct {
uint8_t * buf;
size_t len;
size_t width;
size_t height;
pixformat_t format;
struct timeval timestamp;
} camera_fb_t;
*/
if(fb!=0)
{//50736
if(errno>100)
{
//int err = send(sock, payload, strlen(payload), 0);//int err = send(sock, tx_buffer_test, 50*1024, 0); //
if((fb[1]==0xd8)&&(fb[0]==0xff))
{
for(ii=0;ii<errno;ii++)//查找0XFF,0XD9
{
if((fb[ii]==0XFF)&&(fb[ii+1]==0XD9))break;
}
if(ii==errno)
{
res=1;//没找到0XFF,0XD8
}
else //找到了
{
res=0;
/* errno=fb[ii];
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
errno=fb[ii+1];
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);*/
ii=ii+1;
}
/* if(res==0)
{
int err = send(sock, fb, errno, 0);
ESP_LOGI(TAG, "Send Ok!");
}*/
/* errno=fb->len;
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
errno=(fb->buf[0]);
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
errno=(fb->buf[1]);
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
errno=(fb->buf[fb->len-1]);
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
errno=(fb->buf[fb->len-2]);
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
*/
if(res==0)
{
jj=ii+1;
for(ii=0;ii<jj;ii++)//查找0XFF,0XD9
{
fb_real[ii]=fb[ii];
}
/* errno=fb_real[jj-1];
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
errno=fb_real[jj-2];
ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);*/
int err = send(sock, fb_real, jj, 0);// int err = send(sock, fb_real, errno, 0);
//ESP_LOGI(TAG, "Send Ok!");
}
}
//esp_camera_fb_return(fb);
}
}
else
{
ESP_LOGI(TAG, "caputer err!");
}
if (err < 0)
{
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
break;
}
/* int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
// Error occurred during receiving
if (len < 0) {
ESP_LOGE(TAG, "recv failed: errno %d", errno);
break;
}
// Data received
else {
rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
ESP_LOGI(TAG, "Received %d bytes from %s:", len, host_ip);
//ESP_LOGI(TAG, "%s", rx_buffer);
}*/
vTaskDelay(10 / portTICK_PERIOD_MS);//vTaskDelay(2000 / portTICK_PERIOD_MS);
}
if (sock != -1) {
ESP_LOGE(TAG, "Shutting down socket and restarting...");
shutdown(sock, 0);
close(sock);
}
}
vTaskDelete(NULL);
}
void LED_TASK(void);
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
xTaskCreate(LED_TASK, "LED_TASK", 4096, NULL, 5, NULL);
xTaskCreate(tcp_client_task, "tcp_client", 4096, NULL, 5, NULL);
}
camera_model_t camera_model;
esp_err_t temp;
void camera_init_app(void)
{
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
errno=Y2_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d0: errno %d", errno);
config.pin_d1 = Y3_GPIO_NUM;
errno=Y3_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d1: errno %d", errno);
config.pin_d2 = Y4_GPIO_NUM;
errno=Y4_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d2: errno %d", errno);
config.pin_d3 = Y5_GPIO_NUM;
errno=Y5_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d3: errno %d", errno);
config.pin_d4 = Y6_GPIO_NUM;
errno=Y6_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d4: errno %d", errno);
config.pin_d5 = Y7_GPIO_NUM;
errno=Y7_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d5: errno %d", errno);
config.pin_d6 = Y8_GPIO_NUM;
errno=Y8_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d6: errno %d", errno);
config.pin_d7 = Y9_GPIO_NUM;
errno=Y9_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_d7: errno %d", errno);
config.pin_xclk = XCLK_GPIO_NUM;
errno=XCLK_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_xclk: errno %d", errno);
config.pin_pclk = PCLK_GPIO_NUM;
errno=PCLK_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_pclk: errno %d", errno);
config.pin_vsync = VSYNC_GPIO_NUM;
errno=VSYNC_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_vsync: errno %d", errno);
config.pin_href = HREF_GPIO_NUM;
errno=HREF_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_href: errno %d", errno);
config.pin_sscb_sda = SIOD_GPIO_NUM;
errno=SIOD_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_sscb_sda: errno %d", errno);
config.pin_sscb_scl = SIOC_GPIO_NUM;
errno=SIOC_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_sscb_scl: errno %d", errno);
//config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
errno=RESET_GPIO_NUM;
ESP_LOGE(TAG, "Socket unable to pin_reset: errno %d", errno);
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
config.frame_size = FRAMESIZE_QQVGA;
config.jpeg_quality = 4;// config.jpeg_quality = 12;
//config.fb_count = 1;
// camera init
ESP_LOGE(TAG, "aaa1");
temp=camera_probe(&config, &camera_model);
ESP_LOGE(TAG, "bbb");
if (temp != ESP_OK)
{
ESP_LOGE(TAG, "Camera probe err: errno %d", errno);// ESP_LOGE(TAG, "Camera init failed with err");//Serial.printf("Camera init failed with error 0x%x", err);
return;
}
if(camera_model == 2640)
{
//实际改图像改这里就行
config.frame_size = FRAMESIZE_CIF;//config.frame_size = FRAMESIZE_SVGA;FRAMESIZE_QVGA
config.jpeg_quality = 12;
}
else
{
ESP_LOGE(TAG, "Camera not support");
}
esp_err_t err = camera_init(&config);
if (err != ESP_OK) {
errno=err;
ESP_LOGE(TAG, "Camera init failed: errno %d", errno);// ESP_LOGE(TAG, "Camera init failed with err");//Serial.printf("Camera init failed with error 0x%x", err);
return;
}
// s->set_framesize(s, FRAMESIZE_QVGA);
// startCameraServer();
ESP_LOGE(TAG, "Camera Ready! Use 'http://");//Serial.print("Camera Ready! Use 'http://");
/*
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 = 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();
// initial sensors are flipped vertically and colors are a bit saturated
if (s->id.PID == OV3660_PID) {
s->set_vflip(s, 1); // flip it back
s->set_brightness(s, 1); // up the brightness just a bit
s->set_saturation(s, -2); // lower the saturation
}
// drop down frame size for higher initial frame rate
s->set_framesize(s, FRAMESIZE_QVGA);
#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
#endif
startCameraServer();
Serial.print("Camera Ready! Use 'http://");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
startCameraServer();
Serial.print("Camera Ready! Use 'http://");
Serial.print(WiFi.localIP());
Serial.println("' to connect");*/
}
#define BLINK_GPIO 33
#define BLINK_GPIO1 26
#define BLINK_GPIO2 27
unsigned char temp111=0;
void LED_TASK(void)
{
/* Configure the IOMUX register for pad BLINK_GPIO (some pads are
muxed to GPIO on reset already, but some default to other
functions and need to be switched to GPIO. Consult the
Technical Reference for a list of pads and their default
functions.)
*/
gpio_pad_select_gpio(BLINK_GPIO);
// gpio_pad_select_gpio(BLINK_GPIO1);
// gpio_pad_select_gpio(BLINK_GPIO2);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
// gpio_set_direction(BLINK_GPIO1, GPIO_MODE_OUTPUT);
// gpio_set_direction(BLINK_GPIO2, GPIO_MODE_OUTPUT);
while(1) {
/* Blink off (output low) */
/* if(temp111<=5)
{
temp111++;
gpio_pad_select_gpio(BLINK_GPIO1);
gpio_pad_select_gpio(BLINK_GPIO2);
gpio_set_direction(BLINK_GPIO1, GPIO_MODE_OUTPUT);
gpio_set_direction(BLINK_GPIO2, GPIO_MODE_OUTPUT);
}*/
gpio_set_level(BLINK_GPIO, 0);
// gpio_set_level(BLINK_GPIO1, 0);
// gpio_set_level(BLINK_GPIO2, 0);
// digitalWrite(27, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
/* Blink on (output high) */
gpio_set_level(BLINK_GPIO, 1);
// gpio_set_level(BLINK_GPIO1, 1);
//gpio_set_level(BLINK_GPIO2, 1);
//digitalWrite(27, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
视频详见抖音号:202937710
|
|