本帖最后由 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) {
- String payload=http.getString();
- DynamicJsonDocument jsonBuffer(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"][0]["user_id"].as<const char*>();
- String search_buff_group_id=reload_Json["result"]["user_list"][0]["group_id"].as<const char*>();
- float search_buff_score=reload_Json["result"]["user_list"][0]["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("[HTTP] ... 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) {
- String payload=http.getString();
- DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2)+strlen(payload.c_str())*sizeof(String));
- //DynamicJsonDocument jsonBuffer(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("[HTTP] ... failed, error: %s\n", http.errorToString(httpCode).c_str());
- }
- http.end();
- delay(500);
- }
- //获取用户组列表
- static void Baidu_AI_Group_list(){
- HTTPClient http;
- Serial.println("[HTTPS] 获取组列表...");
- 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] 获取用户列表 ... ");
- // HTTP header has been send and Server response header has been handled
- // file found at server
- if (httpCode == HTTP_CODE_OK) {
- String payload=http.getString();
- int payload_len=strlen(payload.c_str());
- DynamicJsonDocument group_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"][0].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"][i+1].as<const char*>();
- }
- //Serial.println(Group_list_str);
- }
- }
- } else {
- Serial.printf("[HTTP] ... 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、通电后等待时间稍长,估计是与连接网络及连接各平台有关
以上如果大家有更好的办法,请多多指教。
|