基于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:45 编辑
文件已发 占楼备用 你好 请问这个项目还有其他的工程文件吗 学习了, 炸酱面007 发表于 2022-4-9 15:21
你好 请问这个项目还有其他的工程文件吗
没,参考示例>Blinker>Blinker_ESP32_CAM 526598 发表于 2022-4-20 08:48
没,参考示例>Blinker>Blinker_ESP32_CAM
博主可以给个联系方式么 有点问题想请教一下 526598 发表于 2022-4-20 08:48
没,参考示例>Blinker>Blinker_ESP32_CAM
为什么我编译的时候总是在 json封装哪里报错 说差一个冒号呢 缺少库文件,楼主可不可以发下 缺少ESP32_CAM_SERVER.h库文件
页:
[1]
2