写点什么

AI 人脸识别测温一体机设计

作者:DS小龙哥
  • 2022 年 3 月 08 日
  • 本文字数:5397 字

    阅读完需:约 18 分钟

1. 前言

在 AI 人工智能发展应用的过程中,人脸识别技术得到了重用。目前在人脸识别相关的技术已经深入到生活方方面面。在公共安全、智能安防、手机认证等多个领域得到应用,比如: 通过人脸识别来解锁手机,通过人脸识别进入某些政务软件平台或是银行 APP, 还是各大门店,超市使用的"支付宝刷脸支付"等等,这些应用大大方便了人们生活。


目前,因为新冠疫情防控的需要,人人出门都需要戴口罩,查验健康码和测量体温,在办公大楼门口、地铁口、小区门口、商场门口人流量都比较大,传统的人工测量体温方式,费时费力、效率比较低,而且人工近距离核验温度,易产生交叉感染风险。


当前文章就利用华为云提供的 AI 人脸识别接口+红外测温传感器 MLX90614ESF(DCI)+瑞芯微 RK3399 完成 AI 人脸测温一体机设计,方便测量来往人员的体温,减轻防疫防控工作人员的负担。


实现的具体功能: 当检测到人脸时,就测量温度,并检测有没有带口罩;在显示屏上实时显示温度信息,如果温度超出设置值,会通过语音播报提示。如果人员没有戴口罩,会语音提示带口罩。


2. 软硬件设计

(1)核心板采用瑞芯微 RK3399,运行 ubuntu18.04 64 位系统,编译器采用 aarch64-linux-gcc。摄像头采用罗技的 720p 摄像头。



(2)软件界面采用 QT 设计,在 RK3399 的 ubuntu18.04 系统里可以直接安装 QT 开发环境完成开发,也可以在 PC 机上交叉编译后将程序和相关库拷贝过来。



(3)测温传感器采用 MLX90614ESF(DCI),这个是红外非接触式测温传感器,测量距离可达到 1 米左右,这个模块是 IIC 协议接口。


3. 华为云人脸识别服务

3.1 开通人脸识别服务

官网地址: https://www.huaweicloud.com/product/face.html



3.2 人脸识别接口功能

华为云提供的人脸检测可以对输入图片进行人脸检测和分析,输出人脸在图像中的位置、人脸关键点位置、人脸关键属性等信息。支持识别 JPG、PNG、JPEG、BMP 等格式的图片,上传图片时选择将图片转为 Base64 编码上传。


(1)接口请求方式: POST


(2)接口请求地址


格式:https://face.{endpoint}.myhuaweicloud.com/v2/{project_id}/face-detect
示例:https://face.cn-north-4.myhuaweicloud.com/v2/0e5957be8a00f53c2fa7c0045e4d8fbf/face-detect
复制代码


(3)请求头的参数


{ "X-Auth-Token": "******"   }
复制代码


X-Auth-Token 字段是访问华为云的任何 API 接口都需要填,获取方法看这里: https://bbs.huaweicloud.com/blogs/317759 翻到 2.3 小节。



(4)请求 Body 参数


image_base64字段   : 存放Base64编码后的图片数据,大小不超过8MB,建议小于1MB。
attributes字段 :这个参数可以选择不填,不填就只是返回人脸的在图片里的尺寸位置。如果希望获取更多的属性列表,可以填下面之这些属性:2:年龄4:装束(帽子、眼镜)6:口罩7:发型8:胡须11:图片类型12:质量13:表情21:人脸图片旋转角(顺时针偏转角度),支持0°、90°、180°和270°图片旋转。
多个属性间使用逗号(,)隔开。
复制代码


(5)响应参数


如果图像里没有人脸,返回的数据是这样的:{"faces":[]}
如果没有填额外的属性,返回的数据是这样的:{ "faces": [ { "bounding_box": { "top_left_x": 61, "top_left_y": 54, "width": 114, "height": 151 } } ]}
填了额外的属性,返回的数据是这样的:{ "faces": [ { "bounding_box": { "top_left_x": 61, "top_left_y": 54, "width": 114, "height": 151 }, "attributes": { "age": 30, "dress": { "glass": "none", "hat": "none" }, "mask": "none", "hair": "short", "beard": "none", "phototype": "internet photo", "quality": { "total_score": 0.62109375, "blur": 0.3359375, "pose": 0.266357421875, "occlusion": 0.330810546875, "illumination": 0.378662109375 }, "expression": { "type": "neutral", "probability": 0.9991200566291809 } } } ]}
复制代码

3.3 调试接口

地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=FRS&api=DetectFaceByFile


如果最开始想体验一下接口,了解参数的含义,可以先使用在线调试接口测试一下效果。


现在人脸检测的调试接口可以直接在网页上选择本地图片,不用再传 bash64 数据,测试更加方便。


4. 设计设备端程序

4.1 调用人脸检测接口

//人脸检测void Widget::FaceCheck(QImage image){    QString requestUrl;    QNetworkRequest request;
//存放图片BASE64编码 QString imgData;
//设置请求地址 QUrl url;
//人脸检测请求地址 requestUrl = QString("https://face.%1.myhuaweicloud.com/v2/%2/face-detect") .arg(SERVER_ID) .arg(PROJECT_ID);
//设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//将图片进行Base64编码 imgData = QString(toBase64(image)); //编码后的图片大小不超过2M //设置token request.setRawHeader("X-Auth-Token",Token);
//构造请求 url.setUrl(requestUrl); request.setUrl(url);
QString post_param=QString ("{" "\"image_base64\": \"%1\"," "\"attributes\":%2" "}").arg(imgData).arg("6");
//发送请求 manager->post(request, post_param.toUtf8());}
复制代码

4.2 接口数据解析

    if(function_select==6)    {        //解析数据        QJsonParseError json_error;        QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error);        if(json_error.error == QJsonParseError::NoError)        {            //判断是否是对象,然后开始解析数据            if(document.isObject())            {                QJsonObject obj = document.object();                //解析错误代码                if(obj.contains("faces"))                {                    QJsonArray face_arr=obj.take("faces").toArray();
for(int i=0;i<face_arr.size();i++) { QJsonObject object=face_arr.at(i).toObject(); if(object.contains("bounding_box")) { QJsonObject obj1=object.take("bounding_box").toObject();
int top_left_x=0; int top_left_y=0; int width=0; int height=0;
if(obj1.contains("top_left_x")) { top_left_x=obj1.take("top_left_x").toInt(); } if(obj1.contains("top_left_y")) { top_left_y=obj1.take("top_left_y").toInt(); } if(obj1.contains("width")) { width=obj1.take("width").toInt(); } if(obj1.contains("height")) { height=obj1.take("height").toInt(); }
qDebug()<<"top_left_x:"<<top_left_x; qDebug()<<"top_left_y:"<<top_left_y; qDebug()<<"width:"<<width; qDebug()<<"height:"<<height; }
//属性 QString mask; if(object.contains("attributes")) { QJsonObject obj1=object.take("attributes").toObject(); mask=obj1.take("mask").toString(); qDebug()<<"带口罩的状态:"<<mask; } } } } } }
复制代码

4.3 token 获取

void Widget::GetToken(){    //表示获取token    function_select=3;
QString requestUrl; QNetworkRequest request;
//设置请求地址 QUrl url;
//获取token请求地址 requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens") .arg(SERVER_ID);
//自己创建的TCP服务器,测试用 //requestUrl="http://10.0.0.6:8080";
//设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
//构造请求 url.setUrl(requestUrl);
request.setUrl(url);
QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":" "{\"user\":{\"domain\": {" "\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}}," "\"scope\":{\"project\":{\"name\":\"%4\"}}}}") .arg(MAIN_USER) .arg(IAM_USER) .arg(IAM_PASSWORD) .arg(SERVER_ID);
//发送请求 manager->post(request, text.toUtf8());}
复制代码

4.4 摄像头初始化

//查找系统可用摄像头void Widget::Find_CameraNumber(){    //清空列表    ui->comboBox_camera_number->clear();
/*查找电脑当前可用摄像头*/ cameras = QCameraInfo::availableCameras(); if(cameras.count()) { for(int i=0;i<cameras.count();i++) { ui->comboBox_camera_number->addItem(tr("%1").arg(i)); } ui->pushButton_start_camera->setEnabled(true); } else { QMessageBox::warning(this,tr("提示"),"本机没有可用的摄像头!\n" "软件作者:DS小龙哥\n" "BUG反馈:1126626497@qq.com"); ui->pushButton_start_camera->setEnabled(false); }
/*摄像头没有启动时,按钮不可用*/ ui->pushButton_find->setEnabled(false); ui->pushButton_delete->setEnabled(false); ui->pushButton_update->setEnabled(false); ui->pushButton_register->setEnabled(false);}

//启动摄像头void Widget::on_pushButton_start_camera_clicked(){ //摄像头启动标志 if(camera_flag) //如果摄像头已经启动一次,再次启动需要将之前的空间释放掉 { camera->stop(); delete camera; ui->horizontalLayout_2->removeWidget(videoWidget); delete videoWidget; }
camera_flag=1; //标志摄像头已经启动一次
//摄像头启动之后,就无法在重复启动 ui->pushButton_start_camera->setEnabled(false);
/*创建摄像头对象,根据选择的摄像头打开*/ camera = new QCamera(cameras.at(ui->comboBox_camera_number->currentIndex()));
/*构造捕获的对象*/ camera_image_capture = new QCameraImageCapture(camera);
/*设置捕获的目的地*/ camera_image_capture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
//设置截图输出、缓冲区格式、分辨 camera_image_capture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer); camera_image_capture->setBufferFormat(QVideoFrame::PixelFormat::Format_Jpeg);
//设置截图的图片尺寸 iamge_setting.setResolution(320,240); camera_image_capture->setEncodingSettings(iamge_setting);
//关联捕获的信号,发出捕获截图信号时,发出信号 connect(camera_image_capture,&QCameraImageCapture::imageCaptured,this,&Widget::processCapturedImage);
/*配置摄像头捕获模式为帧捕获模式*/ camera->setCaptureMode(QCamera::CaptureViewfinder);
videoWidget = new QVideoWidget(); videoWidget->setMinimumSize(320,240);
//将摄像头显示窗口加入到布局中 ui->horizontalLayout_2->insertWidget(0,videoWidget);
/*设置取景器显示*/ camera->setViewfinder(videoWidget);
/*启动摄像头*/ camera->start();
/*摄像头启动时,按钮可用*/ ui->pushButton_find->setEnabled(true); ui->pushButton_delete->setEnabled(true); ui->pushButton_update->setEnabled(true); ui->pushButton_register->setEnabled(true);}
复制代码


发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
AI人脸识别测温一体机设计_3月月更_DS小龙哥_InfoQ写作平台