智能家居 (11) ——树莓派摄像头捕捉人脸并识别

实现思路

学完前面在Ubuntu系统下的人脸识别内容,本节我们将实现在树莓派上通过一个指令启动摄像头进行拍照并且完成人脸识别,为后面我们的智能家居系统加入人脸识别开锁功能做准备。

首先,去扩容一下SD卡

【树莓派】让你的SD卡快速扩容

其次,使用指令拍一张照片

【树莓派】CSI摄像头简单配置

上文介绍的拍照指令,运行即可拍照

raspistill -o image3.jpg

如果直接使用上面这个指令,那拍出来的图片大概有1.3M左右,不符合祥云后台所要求的图片大小在200k以下
在这里插入图片描述

那么我们可以对图片进行压缩,可以改变摄像头的参数,降低摄像头输出的图片质量。通过查阅树莓派摄像头参数设置,做如下配置:

raspistill -q 5 -t 1 -o image.jpg

-q 是图片质量,在0~100之间,我们调成5,压缩图片质量
-t 是拍照延时,设定1s后拍照

经过测试,拍出来的图片由原来的1.3M变成了90多K,而且图片还很清晰。

做好上述准备工作,我们就可以发送指令open-c1启动摄像头线程了,在这个线程中,需要完成下列操作:

①摄像头拍照返回base64流,
②然后用翔云平台进行对比识别,
③返回识别的结果

线程结束完成一次拍照识别

主要功能代码

(1)通过拍照指令提取当前人脸数据的base64流

上面介绍了树莓派的拍照指令,问题是拍照的时机怎么确定?

  • 原始手动的话,采用按钮方式人脸靠近手动拍照;
  • 自动的话一种方式是通过每隔一秒拍照一次,不断对比,很快就会将OCR识别次数用完;
  • 另一种方式我们可以识别人物动作,发现有人来再进行拍照识别,具体可参照这篇博文:树莓派摄像头使用Motion监测人物动作
char* getFace()
{
	printf("人脸数据采集中...\n");
	system("raspistill -q 5 -t 1 -o image.jpg");
	
	while(access("./image.jpg",F_OK) != 0); //判断是否拍照完毕
	
	printf("数据采集完毕\n");
	
	char* base64BufFaceRec = getBase64FromFile("./image.jpg");
	system("rm image.jpg");  //采集完成删除,防止占内存
	
	return base64BufFaceRec;   //返回刚才拍照的base64
}

(2)通过命令起摄像头线程

if(0 == strcmp(devName,"c1")){  //open-c1起摄像头线程
	pthread_t cameraThread;
	pthread_create(&cameraThread,NULL,cameraThread_func,NULL);
	return;  //执行拍照就不往下走了,返回
}

(3)线程函数

void *cameraThread_func(void* data)//起线程的函数有格式要求
{
	struct Devices *cameraTemp;

	cameraTemp = findDeviceByNum(pDeviceHead, "c1"); //摄像头的设备编号为c1

	if(cameraTemp == NULL){  //防止段错误的必需判断,当给指针赋值是,一定要考虑NULL的情况,否则后续操作都是空谈
		printf("find camera error\n");
		pthread_exit(NULL); //在线程中不用return
	}

	cameraTemp->justDoOnce(); //设备都要从工厂里面取出来.可不能camera.justDoOnce,谁认识你这个camera!
}

(4)摄像头的结构体

struct Devices camera = {

	.name = "camera",
	.serialNum = "c1",
	.justDoOnce = postUrl,
	.deviceInit = cameraInit,

};

(5)调库人脸识别函数

void postUrl()
{
        CURL *curl;
        CURLcode res;

        //分开定义,然后字符串拼接
        char* key    = "xxx";
        char* secret = "xxx";
        int   typeId = 21;
        char* format = "xml";

        char* base64BufPic1 = getFace();//摄像头拍照获取的照片

        char* base64BufPic2 = getBase64FromFile("./Your phtot.jpg");//你提前拍好的帅气照片

        int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;//分配空间不够会>导致栈溢出
        char* postString = (char* )malloc(len);
        memset(postString,'\0',len);//因为postString是一个指针,不能用sizeof来计算其指向的大小

        sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",base64BufPic1,base64BufPic2,key,secret,typeId,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);  //回调函数readDate读取返回值
                res = curl_easy_perform(curl);          //类似于状态码
                printf("OK:%d\n",res);

                if(strstr(ocrRetBuf,"否") != NULL){    //判断翔云后台返回的字符串中有没有“是”
                        printf("不是同一个人\n");
                }
                else{
                        printf("是同一个人\n");//这里识别成功,去开锁!
                }
                curl_easy_cleanup(curl);
        }

}

(6)回调函数

char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据

size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
//回调函数,把从后台的数据拷贝给ocrRetBuf
{
        strncpy(ocrRetBuf,ptr,1024);
}

功能验证

提前拍好自己的一张帅气照片放到树莓派里面,靠近树莓派摄像头识别成功,相应的继电器打开,锁开启。

在这里插入图片描述

后面我将摄像头识别线程完整的实现代码整合到智能家居里面展示,具体在下一篇博文介绍。

往期文章

智能家居 (1) ——智能家居整体功能框架
智能家居 (2) ——设计模式的引入
智能家居 (3) ——工厂模式继电器控制灯
智能家居 (4) ——工厂模式火焰报警
智能家居 (5) —— LD3320语音模块二次开发
智能家居 (6) ——语音识别线程控制
智能家居 (7) ——网络服务器线程控制
智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)
网络编程知识预备(1) ——了解OSI网络模型
网络编程知识预备(2) ——浅显易懂的三次握手与四次挥手
网络编程知识预备(3) ——SOCKET、TCP、HTTP之间的区别与联系
网络编程知识预备(4) ——了解HTTP协议与HTTPS协议
网络编程知识预备(5) ——libcurl库简介及其编程访问百度首页
智能家居 (9) ——人脸识别摄像头安装实现监控功能
智能家居 (10) ——人脸识别祥云平台编程使用
智能家居 (11) ——树莓派摄像头捕捉人脸并识别
智能家居 (12) ——人脸识别整合到智能家居系统
智能家居 (13) ——智能家居加入手机app端控制

  • 13
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
要在树莓派4B上运行人脸识别,可以使用OpenCV和Dlib这两个库来实现。这里提供一个基于Python的简单示例代码: 1. 安装OpenCV和Dlib 在终端中输入以下命令来安装OpenCV和Dlib: ``` sudo apt-get install python3-opencv sudo apt-get install libopencv-dev python3-opencv sudo pip3 install dlib ``` 2. 摄像头捕捉人脸 使用OpenCV的VideoCapture类来捕捉摄像头视频,并使用OpenCV的CascadeClassifier类来检测摄像头视频中的人脸。示例代码如下: ```python import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 加载人脸识别模型 cap = cv2.VideoCapture(0) # 打开摄像头 while True: ret, frame = cap.read() # 读取摄像头视频帧 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 将视频帧转换为灰度图像 faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5) # 检测人脸 for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) # 绘制人脸框 cv2.imshow('frame', frame) # 显示视频帧 if cv2.waitKey(1) & 0xFF == ord('q'): # 按‘q’键退出 break cap.release() # 释放摄像头 cv2.destroyAllWindows() # 关闭窗口 ``` 3. 人脸识别 在检测到人脸后,可以使用Dlib库中的人脸识别模型来识别人脸。示例代码如下: ```python import cv2 import dlib detector = dlib.get_frontal_face_detector() # 加载人脸检测器 predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 加载人脸关键点检测模型 cap = cv2.VideoCapture(0) # 打开摄像头 while True: ret, frame = cap.read() # 读取摄像头视频帧 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 将视频帧转换为灰度图像 faces = detector(gray) # 检测人脸 for face in faces: landmarks = predictor(gray, face) # 检测人脸关键点 for n in range(0, 68): x = landmarks.part(n).x y = landmarks.part(n).y cv2.circle(frame, (x, y), 2, (0, 255, 0), -1) # 绘制人脸关键点 cv2.imshow('frame', frame) # 显示视频帧 if cv2.waitKey(1) & 0xFF == ord('q'): # 按‘q’键退出 break cap.release() # 释放摄像头 cv2.destroyAllWindows() # 关闭窗口 ``` 以上代码只是一个简单的例子,如果要实现更复杂的人脸识别功能,需要对算法进行优化和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

行稳方能走远

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

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

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

打赏作者

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

抵扣说明:

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

余额充值