树莓派3B人脸识别实践:Python与C联合开发详解
基于树莓派3B+的人脸识别实践:Python与C联合开发
引言
树莓派因其小巧的体积和丰富的扩展性,成为嵌入式开发的理想平台。本文将分享如何通过Python与C语言联合开发,在树莓派3B+上实现从硬件控制、摄像头拍照到百度API人脸比对的完整流程。项目代码已开源,欢迎参考与改进。
一、硬件与环境准备
所需硬件
环境配置
- 系统安装:建议使用Raspberry Pi OS (Legacy)或支持
libcamera
的版本。 - 安装依赖库:
sudo apt-get install wiringpi libcamera-dev python3-opencv pip3 install baidu-aip # 百度AI SDK
二、C语言控制摄像头拍照
1. 使用wiringPi初始化GPIO
通过C程序控制GPIO引脚(例如触发拍照信号后点亮LED):
#include <wiringPi.h>
void setup_gpio() {
wiringPiSetup();
pinMode(17, OUTPUT); // 使用GPIO17控制LED
}
2. 调用libcamera拍照
通过system()
函数调用命令行工具libcamera-jpeg
实现拍照:
#include <stdio.h>
#include <stdlib.h>
#include <Python.h>
#include <unistd.h>
#include <string.h>
#define WEGET_CMD "libcamera-jpeg -o /tmp/SearchFace.jpg"
#define SEARCHFACE_FILE "/tmp/SearchFace.jpg"
void face_initialize(void)
{
Py_Initialize();
// 将当前路径添加到sys.path中
PyObject *sys = PyImport_ImportModule("sys");
if(sys == NULL)
{
Py_DECREF(sys);
}
PyObject *path = PyObject_GetAttrString(sys, "path");
if(path == NULL)
{
Py_DECREF(path);
}
PyList_Append(path, PyUnicode_FromString("."));
}
void get_result() {
digitalWrite(17, HIGH); // 拍照时点亮LED
system(WEGET_CMD);
if(access(SEARCHFACE_FILE,F_OK) != 0)
{
return result;
}
digitalWrite(17, LOW);
printf("拍照成功\n");
PyObject *pModule = PyImport_ImportModule("face_search");//导入face_search.py模块
if (!pModule)
{
PyErr_Print();
printf("Error: failed to load face.py\n");
goto FAILED_MODULE;
}
printf("1\n");
PyObject *pFunc = PyObject_GetAttrString(pModule, "search_Face");//获取search_Face函数对象
if (!pFunc)
{
PyErr_Print();
printf("Error: failed to load search_Face\n");
goto FAILED_FUNC;
}
printf("2\n");
PyObject *pValue = PyObject_CallObject(pFunc, NULL);//调用alibabacloud_face函数并获取返回值
if (!pValue)
{
PyErr_Print();
printf("Error: function call failed\n");
goto FAILED_VALUE;
}
printf("3\n");
char *temp = NULL;
if (!PyArg_Parse(pValue, "s", &temp))//解析获取alibabacloud_face函数的返回值,转行为C语言格式
{
PyErr_Print();
printf("Error: parse failed");
goto FAILED_RESULT;
}
printf("4\n");
printf("%s|temp = %s\n",__func__,temp);
strcpy(result,temp);
FAILED_RESULT:
Py_DECREF(pValue);
FAILED_VALUE:
Py_DECREF(pFunc);
FAILED_FUNC:
Py_DECREF(pModule);
FAILED_MODULE:
return result;
}
三、Python调用百度人脸比对API
1. 百度AI平台配置
API Key
和Secret Key
。2. Python代码实现
import base64
import urllib
import requests
import json
API_KEY = "xxx"
SECRET_KEY = "xxx"
def search_Face():
url = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=" + get_access_token()
# image 可以通过 get_file_content_as_base64("C:\fakepath\微信图片_20250321164625.jpg",False) 方法获取
payload = json.dumps({
"group_id_list": "test1",
"image": get_file_content_as_base64("/tmp/SearchFace.jpg"),
"image_type": "BASE64"
}, ensure_ascii=False)
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload.encode("utf-8")).json()
result = response.get("result").get("user_list")[0]
# {'group_id': 'test1', 'user_id': 'hyx', 'user_info': '', 'score': 96.68011474609375}
str_result = f'{result.get("user_id")},{result.get("score")}'
print(str_result)
return str_result
def get_file_content_as_base64(path, urlencoded=False):
"""
获取文件base64编码
:param path: 文件路径
:param urlencoded: 是否对结果进行urlencoded
:return: base64编码信息
"""
with open(path, "rb") as f:
content = base64.b64encode(f.read()).decode("utf8")
if urlencoded:
content = urllib.parse.quote_plus(content)
return content
def get_access_token():
"""
使用 AK,SK 生成鉴权签名(Access Token)
:return: access_token,或是None(如果错误)
"""
url = "https://aip.baidubce.com/oauth/2.0/token"
params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
return str(requests.post(url, params=params).json().get("access_token"))
if __name__ == '__main__':
search_Face()
四、联合开发流程整合
1. 整体逻辑
- C程序控制摄像头拍照并保存图像。
- Python脚本读取图像,调用API进行人脸比对。
- 根据结果触发GPIO动作(如开门信号)。
2. 封装Shell脚本调用
在C程序中调用Python脚本:
使用Python.h中的函数,实现在c中调用python中的函数并传回数据。
3. 完整代码结构
// main.c
int main()
{
face_initialize();
char result[128] = {0};
get_result(result);
printf("main.c:%s\n",result);
return 0;
}
五、优化与注意事项
- 性能提升:通过共享内存减少I/O延迟。
- 错误处理:增加拍照失败重试、网络请求超时机制。
- 安全建议:加密存储百度API密钥,使用HTTPS传输数据。
- 实时性优化:使用OpenCV边缘计算减少云API依赖。
六、效果演示
【后期补】
结语
通过本文,您已经实现了树莓派上软硬件协同的人脸识别系统。未来可结合MQTT实现物联网控制,或移植到更复杂的边缘计算场景中。完整代码已托管至[GitHub仓库链接],欢迎Star与Fork!
附录
问题反馈:欢迎在评论区留言交流,或通过GitHub提交Issue。
作者:坏柠