基于Blinker _ ESP32_CAM与百度云AI开发低成本人脸门禁控制器-Arduino中文社区 - Powered by Discuz! Archiver

526598 发表于 2021-12-19 20:47

基于Blinker_ ESP32_CAM与百度云AI开发低成本人脸门禁控制器

本帖最后由 526598 于 2021-12-19 22:07 编辑

话不多说,先上代码!!!!
#define BLINKER_WIFI
//#define BLINKER_ESP_SMARTCONFIG //自动配网设置

#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <base64.h>
#include <Blinker.h>
#include "ESP32_CAM_SERVER.h"

char auth[] = "Your Device Secret Key";
char ssid[] = "Your WiFi network SSID or name";
char pswd[] = "Your WiFi network WPA password or WEP key";

#define client_id         "************************" //API Key【百度云应用的AK】
#define client_secret   "********************************"//Secret Key【百度云应用的SK】

#define Json_begin      "{\"image\":\""         //Json封装头
//#define Json_end          "\",\"image_type\":\"BASE64\",\"group_id_list\":\"......\"}" //人脸查找API_Json封装尾
String access_token;
String Group_list_str;
bool setup_camera = false;

#define BUTTON_1 "ButtonKey"
BlinkerButton Button1(BUTTON_1);

//人脸验证程序,图像数据需要经过base64编码后以JSON格式发送
static void Baidu_AI(camera_fb_t* &fb){
String base64 = base64::encode(fb->buf,fb->len);
uint16_t len = base64.length();
HTTPClient http;
http.begin("https://aip.baidubce.com/rest/2.0/face/v3/search?access_token="+access_token);
String POST_Code=Json_begin+base64+Json_end;
http.setReuse(true);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
http.addHeader("Accept","application/json");
http.addHeader("Content-Length",String(POST_Code.length()));
http.addHeader("X-Custom-Header", "custom-header-value");
int httpCode = http.POST(POST_Code);


if (httpCode > 0) {
    // HTTP header has been send and Server response header has been handled
    Serial.println("验证人脸... ");
    // file found at server
    if (httpCode == HTTP_CODE_OK) {
      Stringpayload=http.getString();
      DynamicJsonDocumentjsonBuffer(JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2)+strlen(payload.c_str())*sizeof(String));
      DeserializationError error = deserializeJson(jsonBuffer, payload);
      if (error) {
      Serial.print(F("deserializeJson() failed: "));
      BLINKER_LOG(error.c_str());
      http.end();
      return;
      }
      JsonObject reload_Json = jsonBuffer.as<JsonObject>();
      int search_buff_error_code=reload_Json["error_code"].as<int>();
      
      if (search_buff_error_code==0){
      String search_buff_user_id=reload_Json["result"]["user_list"]["user_id"].as<const char*>();
      String search_buff_group_id=reload_Json["result"]["user_list"]["group_id"].as<const char*>();
      float search_buff_score=reload_Json["result"]["user_list"]["score"].as<float>();
      Serial.print("用户名:"+search_buff_user_id);
      Serial.println("相似度: "+String(search_buff_score));
      
      Blinker.print("用户名:"+search_buff_user_id);
      Blinker.print("相似度: "+String(search_buff_score));
      if(search_buff_score>=79){
          //官方建议相似度超过80%即可视为验证通过,可以在这里插入控制门禁设备代码
          Blinker.print("门已开启");
          Serial.print("门已开启");
      }
      
      }else{
      Serial.println("未检测到人脸信息!");
      }
    }
} else {
    //Serial.printf(" ... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();

   
}
//获取百度鉴权认证认证token
static void Baidu_AI_token(){
HTTPClient http;
Serial.printf("获取百度_AI_token ... ");

http.begin("https://aip.baidubce.com/oauth/2.0/token");
http.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

int httpCode = http.POST("grant_type=client_credentials&client_id="+String(client_id) +"&client_secret="+String(client_secret));
if (httpCode > 0) {
    // HTTP header has been send and Server response header has been handled

    // file found at server
    if (httpCode == HTTP_CODE_OK) {
      Stringpayload=http.getString();
      DynamicJsonDocumentjsonBuffer(JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2)+strlen(payload.c_str())*sizeof(String));
      //DynamicJsonDocumentjsonBuffer(20000);
      DeserializationError error = deserializeJson(jsonBuffer, payload);
      if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      http.end();
      return;
      }
      
      JsonObject reload_Json = jsonBuffer.as<JsonObject>();
      access_token=reload_Json["access_token"].as<const char*>();
      Serial.println("SUCCESS");
      //Serial.print("access_token=");
      //Serial.println(access_token);

    }
} else {
    Serial.printf(" ... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();


delay(500);
}
//获取用户组列表
static void Baidu_AI_Group_list(){
HTTPClient http;
Serial.println(" 获取组列表...");

http.begin("https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getlist");
http.addHeader("Content-Type", "application/json; charset=UTF-8");
String POST_Code="access_token="+access_token;
int httpCode = http.POST(POST_Code);
if (httpCode > 0) {
    Serial.println(" 获取用户列表 ... ");
    // HTTP header has been send and Server response header has been handled
    // file found at server
    if (httpCode == HTTP_CODE_OK) {
      Stringpayload=http.getString();
      int payload_len=strlen(payload.c_str());
      DynamicJsonDocumentgroup_list_jsonBuffer(JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2)+payload_len*sizeof(String));
      DeserializationError error = deserializeJson(group_list_jsonBuffer, payload);
      if (error) {
      Serial.print(F("获取用户组列表失败: "));
      Serial.println(error.f_str());
      http.end();
      return;
      }
      //获取组列表
      JsonObject group_list_Json = group_list_jsonBuffer.as<JsonObject>();
      int Group_len=group_list_Json["result"]["group_id_list"].size();
      Serial.print("用户组数量=");
      Serial.println(Group_len);
      int User_list_count=0;
      //http.end();
      if(Group_len>0){
      Group_list_str=group_list_Json["result"]["group_id_list"].as<const char*>();
      for(int i=0;i<Group_len-1;i++){
          Group_list_str=Group_list_str+","+group_list_Json["result"]["group_id_list"].as<const char*>();
      }
      //Serial.println(Group_list_str);
      }
    }
} else {
    Serial.printf(" ... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(500);
}

void button1_callback(const String & state)
{
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    BLINKER_LOG("get button state: ", state);
    camera_fb_t *fb = esp_camera_fb_get();
    if(!fb)return;
    //BLINKER_LOG("Got image");
    Baidu_AI(fb);   //人脸验证程序,图像数据需要经过base64编码后以JSON格式发送
    esp_camera_fb_return(fb);
   
}
void dataRead(const String & data)
{
    BLINKER_LOG("Blinker readString: ", data);

    Blinker.vibrate();
   
    uint32_t BlinkerTime = millis();
   
    Blinker.print("millis", BlinkerTime);
}

void setup()
{
    Serial.begin(115200);
    BLINKER_DEBUG.stream(Serial);

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
   
    //Blinker.begin(auth);//自动配网设置
    Blinker.begin(auth,ssid,pswd);
    Blinker.attachData(dataRead);
    Button1.attach(button1_callback);
}
void loop()
{
    Blinker.run();

    if (Blinker.connected() && !setup_camera)
    {
      setupCamera();
      setup_camera = true;

      Blinker.printObject("video", "{\"str\":\"mjpg\",\"url\":\"http://"+ WiFi.localIP().toString() + "\"}");
      if(access_token==NULL){
            BLINKER_LOG("成功连接网络,尝试获取百度AI_token");
            Baidu_AI_token();//获取百度鉴权认证认证token
            Baidu_AI_Group_list();//获取用户组列表
            Serial.println("设备准备就绪可以进行人脸识别 ... ...");
            Blinker.print("设备准备就绪可以进行人脸识别 ... ...");
      }
    }
}


主要分以下几个步骤:
一、到百度云 https://cloud.baidu.com/申请账号,产品服务搜索 ”人脸识别“——创建应用——领取免费额度
      应用创建后记录好”API Key“及”Secret Key“——查看人脸库——新建组——新建成员并添加用来比对的照片。
二、在手机上点灯APP添加独立设备并记录新设备SecretKey。
三、填写程序中各密钥(API Key、Secret Key、SecretKey)及WIFI的SSID和密码(有条件的可以做自动配网)。
四、程序刷写到模块后在手机点灯app中添加视频及各辅助模块。

由于本人水平有限本程序没有门禁控制部分,各位参考实际情况酌情填写。
目前发现该程序有以下几点情况:
1、在APP视频控件里有白屏现象,不清楚是视频头不工作还是网络问题,关闭app后重新打开能看到图像
2、通电后等待时间稍长,估计是与连接网络及连接各平台有关
以上如果大家有更好的办法,请多多指教。:lol

526598 发表于 2022-4-29 14:40

本帖最后由 526598 于 2022-4-29 14:45 编辑

文件已发

526598 发表于 2021-12-19 20:47

占楼备用

炸酱面007 发表于 2022-4-9 15:21

你好 请问这个项目还有其他的工程文件吗

许普查 发表于 2022-4-12 14:43

学习了,

526598 发表于 2022-4-20 08:48

炸酱面007 发表于 2022-4-9 15:21
你好 请问这个项目还有其他的工程文件吗

没,参考示例>Blinker>Blinker_ESP32_CAM

炸酱面007 发表于 2022-4-22 15:29

526598 发表于 2022-4-20 08:48
没,参考示例>Blinker>Blinker_ESP32_CAM

博主可以给个联系方式么 有点问题想请教一下

炸酱面007 发表于 2022-4-22 15:30

526598 发表于 2022-4-20 08:48
没,参考示例>Blinker>Blinker_ESP32_CAM

为什么我编译的时候总是在 json封装哪里报错 说差一个冒号呢

2748475642 发表于 2022-4-26 12:19

缺少库文件,楼主可不可以发下

2748475642 发表于 2022-4-26 12:35

缺少ESP32_CAM_SERVER.h库文件
页: [1] 2
查看完整版本: 基于Blinker_ ESP32_CAM与百度云AI开发低成本人脸门禁控制器