基于树莓派实现人脸识别开锁

人脸识别的环境搭建可以看一下https://blog.csdn.net/weixin_48856218/article/details/124407139?spm=1001.2014.3001.5501
我这里就不再赘述了

翔云方案

翔云官网https://www.netocr.com/
代码编写
需要修改的地方:
填写自己的翔云账号的 keysecret

    char *key = "";
    char *secret = "";

修改为自己图片的名称:

    char *bufPic1 = getPicBase64FromFile("./img1.jpg");
    char *bufPic2 = getPicBase64FromFile("./img2.jpg");

xianyundemo.c

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define true  1
#define false 0

typedef unsigned int bool;

char buf[1024] = {'\0'};

size_t readData( void *ptr, size_t size, size_t nmemb, void *stream)
{
        strncpy(buf, ptr, 1024);
//        printf("=======================get Data=========================\n");
//        printf("%s\n",buf);
}

char* getPicBase64FromFile(char *filePath)
{
    char *bufPic;
    char cmd[128] = {'\0'};
    sprintf(cmd, "base64 %s > tmpFile",filePath);
    system(cmd);
    int fd = open("./tmpFile", O_RDWR);
    int filelen = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);
    bufPic = (char *)malloc(filelen + 2);
    memset(bufPic, '\0', filelen+2);
    read(fd, bufPic, filelen);
    close(fd);

    system("rm -f tmpFile");
    return bufPic;
}

bool postUrl()
{
    CURL *curl;
    CURLcode res;
    char *postString;

    char *key = "";
    char *secret = "";
    int typeId = 21;
    char *format = "xml";

    char *bufPic1 = getPicBase64FromFile("./img1.jpg");
    char *bufPic2 = getPicBase64FromFile("./img2.jpg");


    int len = strlen(key)+strlen(secret)+strlen(bufPic1)+strlen(bufPic2)+124;
    postString = (char *)malloc(len);
    memset(postString, '\0', len);

    sprintf(postString, "&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",
                    bufPic1,bufPic2,key,secret,21,format);

    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);    // 指定post内容
        curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");   // 指定url
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);
        res = curl_easy_perform(curl);
        printf("OK:%d\n",res);
        if(strstr(buf,"是") != NULL){
                printf("yes\n");
        }else{
                printf("no\n");
        }
        curl_easy_cleanup(curl);
    }
    return true;
}
int main(void)
{
    postUrl();
}

编译

gcc xianyundemo.c -lcurl -lssl -o xyface

百度方案

官网地址:需要自己注册认证领取免费资源,网上注册教程很多,自行百度
https://login.bce.baidu.com/?redirect=https%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F%3F_%3D1650961199726%26fromai%3D1#/ai/face/report/index~apiId=206
需要修改的地方:
填写自己的百度账号的 keysecret

        char AK[] = "";
        char SK[] = "";

修改对应图片名:

        char *image1_base64 = getbase64("img1.jpg");
        char *image2_base64 = getbase64("img2.jpg");

baidudemo.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <cjson/cJSON.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

size_t access_token_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{

        char *buf = (char *)malloc (size * nmemb + 8 );
        memset(buf,'\0',size * nmemb + 8);
        strncpy(buf, ptr, size * nmemb);

        cJSON *json= cJSON_Parse(buf);


        char *access_token_result = (char *)stream;

        strncpy(access_token_result,cJSON_GetObjectItem(json,"access_token")->valuestring,128);

        //printf("stream:%s\n",(char *)stream);

        cJSON_Delete(json);
        free(buf);
        return size * nmemb;
}
int post_access_token(char *access_token)
{
        CURL *curl;
        CURLcode result_code;
        int error_code = 0;

        char url[256] = {0};
        char access_token_url[] = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials";
        char AK[] = "";
        char SK[] = "";
        char access_token_result[128] = {0};

        curl = curl_easy_init();
        if (curl) {
                //std::string url = access_token_url + "&client_id=" + AK + "&client_secret=" + SK;
                sprintf(url,"%s&client_id=%s&client_secret=%s",access_token_url,AK,SK);
                //printf("url: %s\n",url );
                curl_easy_setopt(curl, CURLOPT_URL, url);
                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);


                curl_easy_setopt(curl, CURLOPT_WRITEDATA, access_token_result);
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, access_token_callback);
                result_code = curl_easy_perform(curl);
                if (result_code != CURLE_OK) {
                        fprintf(stderr, "curl_easy_perform() failed: %s\n",
                                        curl_easy_strerror(result_code));
                        return 1;
                }
                //printf("access_token_result:%s\n",access_token_result);
                strcpy(access_token,access_token_result);
                curl_easy_cleanup(curl);
                error_code = 0;
        } else {
                fprintf(stderr, "curl_easy_init() failed.");
                error_code = 1;
        }

        return error_code;
}

size_t faceMatch_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    // 获取到的body存放在ptr中,先将其转换为string格式
        char *buf = (char *)malloc (size * nmemb + 8 );
        memset(buf,'\0',size * nmemb + 8);
        strncpy(buf, ptr, size * nmemb);

        cJSON *json = cJSON_Parse(buf);
        printf("data:%s\n",cJSON_Print(json));
        if(strstr(cJSON_Print(json),"SUCCESS") ==NULL){
                *((double *)stream) = 0;
        }else{

                cJSON *result = cJSON_GetObjectItem(json,"result");

                //printf("data:%s\n",cJSON_Print(result));      

                double *faceMatch_result = (double *)stream;

                *faceMatch_result = cJSON_GetObjectItem(result,"score")->valuedouble;

                //printf("stream:%f\n",*faceMatch_result);
        }

        cJSON_Delete(json);
        free(buf);

    return size * nmemb;
}

/**
 * 人脸对比
 * @return 调用成功返回0,发生错误返回其他错误码
 */
int post_faceMatch(double *faceMatch, char *access_token)
{
    //std::string url = request_url + "?access_token=" + access_token;
        char url[256] = {0};
        char request_url[] = "https://aip.baidubce.com/rest/2.0/face/v3/match";
        sprintf(url,"%s?access_token=%s",request_url,access_token);

        char *getbase64(char *photoname);
        char image[] = "\"image\": ";
        char image_type[] = "\"image_type\": \"BASE64\"";
        char *image1_base64 = getbase64("img1.jpg");
        char *image2_base64 = getbase64("img2.jpg");
        char *params = (char *)malloc(strlen(image1_base64) + strlen(image2_base64)
                        + 2 * strlen(image) + 2 * strlen(image_type) + 128 );
        sprintf(params,"[{%s\"%s\", %s}, {%s\"%s\", %s}]",image,image1_base64,image_type
                ,image,image2_base64,image_type);
        cJSON *json = cJSON_Parse(params);
//      printf("%s\n",cJSON_Print(json));
        //printf("param : %s\n",params);
        CURL *curl = NULL;
        CURLcode result_code;
        int is_success;
        curl = curl_easy_init();
        double faceMatch_result;
        if (curl) {
                curl_easy_setopt(curl, CURLOPT_URL, url);
                curl_easy_setopt(curl, CURLOPT_POST, 1);
                struct curl_slist *headers = NULL;
                headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
                //curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params);
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, cJSON_Print(json));
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, &faceMatch_result);
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, faceMatch_callback);
                result_code = curl_easy_perform(curl);

                free(image1_base64);
                free(image2_base64);
                free(params);
                cJSON_Delete(json);
        if (result_code != CURLE_OK) {
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                          curl_easy_strerror(result_code));
                is_success = 1;
                return is_success;
        }
                *faceMatch = faceMatch_result;
                curl_easy_cleanup(curl);
                is_success = 0;
        } else {
                fprintf(stderr, "curl_easy_init() failed.");
                is_success = 1;
        }
        return is_success;
}

char *getbase64(char *photoname)
{
        char order[128] = {0};
        char file[32] = {0};
        char *base64 = NULL;

        sprintf(order,"base64 %s > %s_base64",photoname,photoname);
        system(order);
        sprintf(file,"%s_base64",photoname);
        int fd = open(file,O_RDWR);
        int len = lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);
        base64 = (char *)malloc(len+1);
        read(fd,base64,len);
        base64[len] = '\0';


        //printf("%d\n",strlen(base64));
        return base64;
}

int main ()
{

        char access_token[128];
        double faceMatch = 0;

        post_access_token(access_token);
        //printf("access_token: %s\n", access_token);

        post_faceMatch(&faceMatch,access_token);
        //printf("faceMatch : %f \n",faceMatch);

        if(faceMatch > 80){
                printf("yes\n");
        }else{
                printf("no\n");
        }

        return 0;
}

编译

gcc baidudemo.c -lcurl -lcjson -o bdface  

主函数编写

用继电器来连接电磁锁,继电器引脚初始化为输出(OUTPUT),电磁锁吸合,继电器引脚初始化为输出(INPUT),电磁锁松开。
main.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<wiringPi.h>


void initWiringPi()
{
    int ret = wiringPiSetup();
    if(ret == -1){
        printf("wiringPi初始化失败\n");
        perror("init");
    }

}

int main(int argc, char const *argv[])
{
    FILE *fp;
    int n_read;
    char buff[1280];
    int num = 0;
    //1.初始化wiringPi库
    initWiringPi();
    //2.初始化门锁(保持闭合的状态)
    pinMode(24, INPUT);
    while(1){
        //3.摄像头拍照,获取一张照片
        printf("是否进行人脸识别开锁?1是,0否\n");
        scanf("%d",&num);
        if(num == 1){
            printf("准备开启摄像头拍照\n");
            system("raspistill  -o img2.jpg -q 5");
            memset(buff,'\0',1280);//清空数据
            //4.得到照片后和之前的照片进行对比
            fp = popen("./bdface","r");//(用百度方案)运行人脸识别的程序(两张照片对比,取出结果,是或否)
            //fp = popen("./xyface","r");//(用翔云方案)
            //5.读取fp内容,根据结果来判断是否要开锁

            n_read = fread(buff,1,1280,fp);
            if(n_read < 0){
                printf("读取失败\n");
                perror("n_read");
            }
            if(strstr(buff,"yes") != NULL){
                pinMode(24,OUTPUT);
                printf("好家伙,是自己人,门已经打开,3s后关闭\n");
                delay(3000);
                pinMode(24,INPUT);
            }else{
                printf("好家伙,不认识你\n");
                printf("buff = %s\n",buff);
            }
        }
    }

    return 0;
}

编译

gcc main.c -lwiringPi -o chack 

运行

./chack
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
基于树莓派人脸识别考勤项目是利用树莓派和Python语言开发的一种考勤系统。该系统可以通过摄像头捕捉到员工的面部图像,并通过人脸识别算法进行人脸识别。通过与已经注册的员工面部信息进行对比,可以判断员工是否是合法员工,从而实现考勤功能。 首先,我们需要在树莓派上安装摄像头,并使用Python编程语言进行图像采集和处理。通过调用树莓派摄像头模块拍摄照片,并对照片进行预处理,例如灰度化、裁剪、归一化等操作,以提高识别精度。 接下来,我们需要使用适当的人脸识别算法。常见的人脸识别算法有基于特征的算法(如LBP、Haar特征等)和基于深度学习的算法(如卷积神经网络)。我们可以选择合适的算法,并使用Python进行实现和调用。 然后,我们需要建立员工人脸数据库。可以让每位员工在初始注册时拍摄照片,并将其存储在数据库中。在日常考勤时,系统会将摄取到的人脸图像与数据库中的员工面部信息进行比对,判断是否为合法员工。 最后,我们可以根据比对结果进行考勤统计。系统可以记录员工的到岗时间、离岗时间等信息,并生成考勤报表。此外,还可以增加其他功能,如远程查看考勤记录、异常考勤的报警等。 综上所述,基于树莓派人脸识别考勤项目是一种利用树莓派和Python开发的考勤系统,具有较高的准确性和便捷性。通过这种系统可以提高考勤的自动化水平,减少人力成本,提升办公效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从入门到捕蛇者说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值