#简介:这是在ubuntu22.04里面使用opencv打开摄像头,通过摄像头获取图像并截取人脸图像,再将人脸图像转换成百度智能云平台所能接受的base64格式(当然也有其他格式),将base64格式的人脸图像发送给百度智能云,通过智能云平台的计算得到图像的匹配信息,本机接收到信息后对信息做处理。代码用C++格式,即人脸打卡考勤机的软件部分。
参考资料:
opencv官方在线文档:OpenCV documentation index
百度智能云——人脸识别:人脸识别_人脸识别_准确率99.99%_免费试用-百度AI开放平台
零、Opencv及百度智能云平台简介
1.Opencv简介
opencv是一个开源的计算机视觉库,基于里面的代码可以轻松的处理各种图像,比如在本文中我们会用到opencv的代码来打开摄像头、拍摄图片、识别人脸、截取人脸区域、转换图像格式等。opencv兼容多个平台多种语言,这里我们将会在ubuntu中配置opencv并使用它。
2.百度智能云平台
人脸识别是一个牵扯到人工智能的功能,需要的计算量十分庞大,而一个人脸识别考勤机没必要配置强大的硬件配置,于是可以借助云平台来处理AI相关的计算,通过云平台,我们的考勤机只需联网即可完成人脸识别的功能。
AI相关计算既可以在云上进行,也可以离线部署,两种方式各有优劣。云计算可节省硬件成本,但有信息泄露的风险。离线部署虽然安全,但搭建成本高。
一、ubuntu下安装opencv
1.打开终端,输入指令。
sudo apt-get install libopencv-dev
2.使用dpkg检查opencv安装状态。
dpkg -s libopencv-dev
3.新建文件夹
我这里在home下创建了一个All_Project用来存放项目代码。
4.安装图形化编辑器
有一个图形化编辑器写代码会方便很多,这里我使用的是Gedit
sudo apt-get install gedit
二、使用opencv打开摄像头
1.让摄像头连接到ubuntu中,在VMware中可管理设备的连接。
确保有摄像头连接到Ubuntu。
在Ubuntu中可通过指令检查摄像头是否连接成功:
ls /dev
基于linux的万物皆文件的特性,dev这个文件夹存放的是设备文件,我们通过查看dev中是否有video文件来辨别摄像头的连接情况。图中的video0即是我的笔记本电脑的摄像头
2.写一个.cpp文件来打开摄像头
先进入项目文件夹
cd home/All_Project/Opencv_Project/Project1_testCamera
创建一个.cpp文件
touch main.cpp
双击打开main.cpp即可开始编写代码。第一个main文件是编译后生成的.exe文件。
最重要的代码会用注释“<<*>>”标出
//这个代码实现opencv打开摄像头并拍摄图片使其连续播放变成视频,加入了帧数的监测,会在终端里面打印出帧数
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
VideoCapture cap(0); //打开摄像头,即使用vedio0 <<*>>
if(!cap.isOpened())//检查摄像头打开
{
cout << "Camera open failed " << endl;
return 0;
}
cout << "Camera open success" << endl;
double fps, total_fps = 0; //帧数相关的变量
int frame_count = 0; //帧数的计数变量
for( ; ; ) //让图片连续显示就变成了视频
{
// 获取当前时间戳
double start_time = static_cast<double>(cv::getTickCount());
Mat ColorImage; //实例化一个对象 <<*>>
cap >> ColorImage; //令摄像头进行拍照 <<*>>
if (ColorImage.empty()) //若图像为空则退出循环
{
cerr << "Error: Couldn't capture a frame." << endl;
break; // 退出循环
}
// 在这里进行帧处理
// 计算帧速率
double end_time = static_cast<double>(cv::getTickCount());
double elapsed_time = (end_time - start_time) / cv::getTickFrequency();
fps = 1.0 / elapsed_time;
// 累计帧速率和帧数
total_fps += fps;
frame_count++;
// 输出平均帧速率
if (frame_count % 30 == 0) { // 每30帧输出一次
double avg_fps = total_fps / frame_count;
std::cout << "Average FPS: " << avg_fps << std::endl;
}
imshow("video",ColorImage); //显示最终的图像 <<*>>
//waitKey(0);
char key = waitKey(30); // 等待按键,每帧间隔30毫秒
if (key == 27) {
// 如果按下ESC键,退出循环
break;
}
}
return 0;
}
//g++ main.cpp -o main `pkg-config --cflags --libs opencv4`
代码编写完成后还需要编译才能在计算机上运行,在当前文件夹中右键打开终端进行编译,这里使用g++编译,编译时容易出现报错,除了代码语法错误外,大多是没有连相关库一起编译
g++ main.cpp -o main `pkg-config --cflags --libs opencv4`
编译完后会发现生成了一个.exe可执行文件。通过指令或双击即可看见图像
./main
三、使用opencv处理摄像头拍摄的图像
在计算机图像处理中,摄像头拍摄得到的原图并不容易直接处理,我们需要将图像进行多种变换才方便计算机进行计算。
拿到原图后,先转换为灰度图,再转换为均衡图,原因是灰度图不容易识别出人脸轮廓,将其均衡化后更容易检测到人脸轮廓。再使用级连分类器调用opencv中自带训练好的人脸模型对均衡图进行识别,识别到人脸后,会返回人脸列表,我们在人脸的位置画一个矩形方框,这样就实现了opencv识别人脸。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
///opencv.hpp
using namespace std;
using namespace cv;
int main()
{
VideoCapture cap(0); //打开摄像头 <<*>>
if(!cap.isOpened()) //检测摄像头是否打开
{
cout << "Camera open failed" << endl;
return 0;
}
cout << "Camera open succed " << endl;
CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml"); //级联分类器,输入人脸的训练模型 <<*>>
Mat ColorImage;//原图
Mat GrayImage;//灰度图
Mat EqualImage;//均衡图
vector<Rect> AllFace;//创建承载人脸列表的容器
for( ; ; )
{
cap >> ColorImage;
cvtColor(ColorImage,GrayImage,COLOR_BGR2GRAY); //将原图转换为灰度图 <<*>>
equalizeHist(GrayImage,EqualImage);//将灰度图均值化,均值化后的图像更易检测人脸轮廓 <<*>>
Classifier.detectMultiScale(EqualImage,AllFace);//检测人脸,返回识别出人脸的矩形列表<<*>>
if(AllFace.size()) //当检测到人脸的时候才画框
{
rectangle(GrayImage,AllFace[0],Scalar(255,255,0));//通过rectang将人脸的矩形画在显示图像上 <<*>>
}
imshow("video",GrayImage);//显示图像 <<*>>
waitKey(40);
}
}
//g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4`
通过编译后即可运行得到结果
g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4`
现在我们就是使用了VideoCapture cap(0)来开启摄像头,用cap >> ColorImage让摄像头拍照,并通过opencv训练好的人脸库haarcascade_frontalface_alt2.xml和Classifier.detectMultiScale()获取图像中人脸的位置,然后我们用rectangle()在人脸位置画了个框。
到目前为止,opencv的任务已经完成了,我们已经得到了人脸图像,就差将人脸上传到云进行AI匹配计算了,将人脸图像上传到云后,云会把我们上传的图像与其人脸库中的图像进行对比,并返回相似度最高的人脸信息。
四、配置百度智能云平台
1.配置云
使用云平台给我们进行AI计算,需要在百度智能云平台申请资源并输入人脸库的数据,这样云平台在接收到我们拍摄到的人脸才能进行比对。百度智能云平台的业务很多,人脸识别考勤机只使用到了人脸识别业务。百度智能云现在有开放免费的计算资源,直接可以领取使用。
根据操作指引的提示即可在网页内完成云的配置。
在创建完应用后,需要录入人脸库。这里显示了AppID、APIKey、Secret Key,我们正是通过这三个关键信息来让ubuntu和云进行匹配的。
2.配置ubuntu
配置好云后,在我们自己的ubuntu上也需要进行配置,这样才能兼容到智能云的API,即在ubuntu上搭建SDK,SDK是软件开发工具包,在ubuntu里面搭建后才能往代码里写上与云平台有关的代码。
下载即得到一个压缩包,我们把压缩包解压后放入我们的项目文件夹,确保我们的main在这个文件夹里面。
百度云的SDK也依赖一些其他的库,我们也要把这些库安装上。
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install openssl
sudo apt-get install libjson-dev
sudo apt-get install libssl-dev
文章来源地址https://www.toymoban.com/news/detail-829984.html
五、将百度智能云的API接入代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
#include <cstdlib>
#include <cstddef>
#include "face.h"
///opencv.hpp
using namespace std;
using namespace cv;
using namespace aip;
int main()
{
VideoCapture cap(0);
if(!cap.isOpened()) //检测摄像头是否打开
{
cout << "Camera open failed" << endl;
return 0;
}
cout << "Camera open succed " << endl;
CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml"); //集联分类器,输入人脸的训练模型
string app_id = "你的app_id ";
string api_key = "你的api_key ";
string secret_key = "你的secret_key ";
aip::Face client(app_id,api_key,secret_key);//智能云的API,通过这个建立Ubuntu和云的联系 <<*>>
Mat ColorImage;//原图
Mat GrayImage;//灰度图
Mat EqualImage;//均衡图
vector<Rect> AllFace;//创建承载人脸列表的容器
Mat MatFace;//人脸图
vector<uchar> JpgFace;//用来存储.jpg形式的变量
string Base64Face;//用来存储base64格式的变量
Json::Value result;//用来存储百度智能云返回的结果
time_t sec;
for( ; ; )
{
cap >> ColorImage;
cvtColor(ColorImage,GrayImage,COLOR_BGR2GRAY); //将原图转换为灰度图
equalizeHist(GrayImage,EqualImage);//将灰度图均值化,均值化后的图像更易检测人脸轮廓
Classifier.detectMultiScale(EqualImage,AllFace);//检测人脸,返回识别出人脸的矩形列表
if(AllFace.size()) //当检测到人脸的时候才画框
{
//for(int i = 0;i < std::size(AllFace);i++) //size(AllFace)
//{
rectangle(GrayImage,AllFace[0],Scalar(255,255,0));//通过rectang将人脸的矩形画在显示图像上
MatFace = GrayImage(AllFace[0]);//将人脸图取出
imencode(".jpg",MatFace,JpgFace);//将Mat格式转为.jpg
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size());//将.jpg格式的图片转换为base64格式 <<*>>
result = client.search(Base64Face,"BASE64","User",aip::null);//将本机截取的人脸发给百度智能云并获取结果 <<*>>
cout << result << endl;//在本机上打印结果
//}
}
imshow("video",GrayImage);//显示图像
waitKey(40);
}
}
//g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4` -I/home/newnew/All_Project/OpenCV_Project/project2_FaceDetection -I/home/newnew/All_Project/OpenCV_Project/project2_FaceDetection/base -std=c++11 -lcurl -lcrypto -ljsoncpp
使用智能云需要加的代码:
#include "face.h" //头文件包含
using namespace aip; //命名空间
string app_id = "你的app_id ";
string api_key = "你的api_key ";
string secret_key = "你的secret_key ";
aip::Face client(app_id,api_key,secret_key);//智能云的API,通过这个建立Ubuntu和云的联系 <<*>>
string Base64Face;//用来存储base64格式的变量
Json::Value result;//用来存储百度智能云返回的结果
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size());//将.jpg格式的图片转换为base64格式 <<*>>
result = client.search(Base64Face,"BASE64","User",aip::null);//将本机截取的人脸发给百度智能云并获取结果 <<*>>
根据智能云的文档进行编译:
g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4` -I/home/newnew/All_Project/OpenCV_Project/project2_FaceDetection -I/home/newnew/All_Project/OpenCV_Project/project2_FaceDetection/base -std=c++11 -lcurl -lcrypto -ljsoncpp
若http.h和json.h出现报错,按图片进行更改。
可以在终端里面看到云反馈回来的信息
六、信息处理
这是云返回给我们的信息
{
"cached" : 0,
"error_code" : 0,
"error_msg" : "SUCCESS",
"log_id" : 319**,
"result" :
{
"face_token" : "a177cce0d03e85ca3**",
"user_list" :
[
{
"group_id" : "User",
"score" : 79.587699890137003,
"user_id" : "ChenGuanXi",
"user_info" : ""
}
]
},
"timestamp" : 170**
}
里面包含了很多内容,如识别的人脸库ID,人脸ID,相似度等,我们使用的时候不需要显示那么多信息,于是可以用json库来处理这些信息,当识别的相似度大于80时,我们才让显示人们和当前时间。
if( !result["result"].isNull() ) //如果接受到的result不为空,则开始判断相似度
{
if(result["result"]["user_list"][0]["score"].asInt() > 80) //当相似度大于80时才显示信息
{
cout << result["result"]["user_list"][0]["user_id"] << endl; //显示人脸名
sec = time(NULL);
cout << ctime(&sec) << endl; //获取时间并显示
}
}
这样终端就会显示人脸名和时间了
同时这些信息也需要记录备案,且我们想要将信息直接打印到图像上,opencv库有一个函数putText()可以直接将信息放在图像上;而在启动程序的时候"./mian >> log.txt"这样会使终端的输出重定向到log.txt文件里面,便记录了这些信息。
全部代码:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
#include <cstdlib>
#include <cstddef>
#include "face.h"
///opencv.hpp
using namespace std;
using namespace cv;
using namespace aip;
int main()
{
VideoCapture cap(0);
if(!cap.isOpened()) //检测摄像头是否打开
{
cout << "Camera open failed" << endl;
return 0;
}
cout << "Camera open succed " << endl;
CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml"); //集联分类器,输入人脸的训练模型
string app_id = "47744549";
string api_key = "O1TaEInKKMgYLPutwExB3jhM";
string secret_key = "yoTdKymLxTTn5U1f2iZtwpZkIkLgpVwi";
aip::Face client(app_id,api_key,secret_key);
Mat ColorImage;//原图
Mat GrayImage;//灰度图
Mat EqualImage;//均衡图
vector<Rect> AllFace;//创建承载人脸列表的容器
Mat MatFace;//人脸图
vector<uchar> JpgFace;//用来存储.jpg形式的变量
string Base64Face;//用来存储base64格式的变量
Json::Value result;//用来存储百度智能云返回的结果
time_t sec;
for( ; ; )
{
cap >> ColorImage;
cvtColor(ColorImage,GrayImage,COLOR_BGR2GRAY); //将原图转换为灰度图
equalizeHist(GrayImage,EqualImage);//将灰度图均值化,均值化后的图像更易检测人脸轮廓
Classifier.detectMultiScale(EqualImage,AllFace);//检测人脸,返回识别出人脸的矩形列表
if(AllFace.size()) //当检测到人脸的时候才画框
{
//for(int i = 0;i < std::size(AllFace);i++) //size(AllFace)
//{
rectangle(GrayImage,AllFace[0],Scalar(255,255,0));//通过rectang将人脸的矩形画在显示图像上
MatFace = GrayImage(AllFace[0]);//将人脸图取出
imencode(".jpg",MatFace,JpgFace);//将Mat格式转为.jpg
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size());//将.jpg格式的图片转换为base64格式
result = client.search(Base64Face,"BASE64","User",aip::null);//将本机截取的人脸发给百度智能云并获取结果
//cout << result << endl;//在本机上打印结果
if( !result["result"].isNull() )
{
if(result["result"]["user_list"][0]["score"].asInt() > 80)
{
cout << result["result"]["user_list"][0]["user_id"] << endl;
sec = time(NULL);
cout << ctime(&sec) << endl;
putText(GrayImage,result["result"]["user_list"][0]["user_id"].asString(),Point(0,50),FONT_HERSHEY_SIMPLEX,1,Scalar(255,255,255));
putText(GrayImage,ctime(&sec),Point(0,100),FONT_HERSHEY_SIMPLEX,1,Scalar(255,255,255));
}
}
//}
}
imshow("video",GrayImage);//显示图像
waitKey(40);
}
}
//g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4` -I/home/newnew/All_Project/OpenCV_Project/project2_FaceDetection -I/home/newnew/All_Project/OpenCV_Project/project2_FaceDetection/base -std=c++11 -lcurl -lcrypto -ljsoncpp
效果:
文章来源:https://www.toymoban.com/news/detail-829984.html
到了这里,关于Ubuntu下的Opencv识别人脸#采用百度智能云平台方案#人脸识别考勤机#C++的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!