#簡(jiǎn)介:這是在ubuntu22.04里面使用opencv打開(kāi)攝像頭,通過(guò)攝像頭獲取圖像并截取人臉圖像,再將人臉圖像轉(zhuǎn)換成百度智能云平臺(tái)所能接受的base64格式(當(dāng)然也有其他格式),將base64格式的人臉圖像發(fā)送給百度智能云,通過(guò)智能云平臺(tái)的計(jì)算得到圖像的匹配信息,本機(jī)接收到信息后對(duì)信息做處理。代碼用C++格式,即人臉打卡考勤機(jī)的軟件部分。
參考資料:
opencv官方在線文檔:OpenCV documentation index
百度智能云——人臉識(shí)別:人臉識(shí)別_人臉識(shí)別_準(zhǔn)確率99.99%_免費(fèi)試用-百度AI開(kāi)放平臺(tái)
零、Opencv及百度智能云平臺(tái)簡(jiǎn)介
1.Opencv簡(jiǎn)介
????????opencv是一個(gè)開(kāi)源的計(jì)算機(jī)視覺(jué)庫(kù),基于里面的代碼可以輕松的處理各種圖像,比如在本文中我們會(huì)用到opencv的代碼來(lái)打開(kāi)攝像頭、拍攝圖片、識(shí)別人臉、截取人臉區(qū)域、轉(zhuǎn)換圖像格式等。opencv兼容多個(gè)平臺(tái)多種語(yǔ)言,這里我們將會(huì)在ubuntu中配置opencv并使用它。
2.百度智能云平臺(tái)
????????人臉識(shí)別是一個(gè)牽扯到人工智能的功能,需要的計(jì)算量十分龐大,而一個(gè)人臉識(shí)別考勤機(jī)沒(méi)必要配置強(qiáng)大的硬件配置,于是可以借助云平臺(tái)來(lái)處理AI相關(guān)的計(jì)算,通過(guò)云平臺(tái),我們的考勤機(jī)只需聯(lián)網(wǎng)即可完成人臉識(shí)別的功能。
??????? AI相關(guān)計(jì)算既可以在云上進(jìn)行,也可以離線部署,兩種方式各有優(yōu)劣。云計(jì)算可節(jié)省硬件成本,但有信息泄露的風(fēng)險(xiǎn)。離線部署雖然安全,但搭建成本高。
一、ubuntu下安裝opencv
1.打開(kāi)終端,輸入指令。
sudo apt-get install libopencv-dev
?2.使用dpkg檢查opencv安裝狀態(tài)。
dpkg -s libopencv-dev
3.新建文件夾
我這里在home下創(chuàng)建了一個(gè)All_Project用來(lái)存放項(xiàng)目代碼。
4.安裝圖形化編輯器
有一個(gè)圖形化編輯器寫代碼會(huì)方便很多,這里我使用的是Gedit
sudo apt-get install gedit
二、使用opencv打開(kāi)攝像頭
1.讓攝像頭連接到ubuntu中,在VMware中可管理設(shè)備的連接。
確保有攝像頭連接到Ubuntu。
?在Ubuntu中可通過(guò)指令檢查攝像頭是否連接成功:
ls /dev
基于linux的萬(wàn)物皆文件的特性,dev這個(gè)文件夾存放的是設(shè)備文件,我們通過(guò)查看dev中是否有video文件來(lái)辨別攝像頭的連接情況。圖中的video0即是我的筆記本電腦的攝像頭
2.寫一個(gè).cpp文件來(lái)打開(kāi)攝像頭
先進(jìn)入項(xiàng)目文件夾
cd home/All_Project/Opencv_Project/Project1_testCamera
創(chuàng)建一個(gè).cpp文件
touch main.cpp
雙擊打開(kāi)main.cpp即可開(kāi)始編寫代碼。第一個(gè)main文件是編譯后生成的.exe文件。
最重要的代碼會(huì)用注釋“<<*>>”標(biāo)出
//這個(gè)代碼實(shí)現(xiàn)opencv打開(kāi)攝像頭并拍攝圖片使其連續(xù)播放變成視頻,加入了幀數(shù)的監(jiān)測(cè),會(huì)在終端里面打印出幀數(shù)
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
VideoCapture cap(0); //打開(kāi)攝像頭,即使用vedio0 <<*>>
if(!cap.isOpened())//檢查攝像頭打開(kāi)
{
cout << "Camera open failed " << endl;
return 0;
}
cout << "Camera open success" << endl;
double fps, total_fps = 0; //幀數(shù)相關(guān)的變量
int frame_count = 0; //幀數(shù)的計(jì)數(shù)變量
for( ; ; ) //讓圖片連續(xù)顯示就變成了視頻
{
// 獲取當(dāng)前時(shí)間戳
double start_time = static_cast<double>(cv::getTickCount());
Mat ColorImage; //實(shí)例化一個(gè)對(duì)象 <<*>>
cap >> ColorImage; //令攝像頭進(jìn)行拍照 <<*>>
if (ColorImage.empty()) //若圖像為空則退出循環(huán)
{
cerr << "Error: Couldn't capture a frame." << endl;
break; // 退出循環(huán)
}
// 在這里進(jìn)行幀處理
// 計(jì)算幀速率
double end_time = static_cast<double>(cv::getTickCount());
double elapsed_time = (end_time - start_time) / cv::getTickFrequency();
fps = 1.0 / elapsed_time;
// 累計(jì)幀速率和幀數(shù)
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鍵,退出循環(huán)
break;
}
}
return 0;
}
//g++ main.cpp -o main `pkg-config --cflags --libs opencv4`
?代碼編寫完成后還需要編譯才能在計(jì)算機(jī)上運(yùn)行,在當(dāng)前文件夾中右鍵打開(kāi)終端進(jìn)行編譯,這里使用g++編譯,編譯時(shí)容易出現(xiàn)報(bào)錯(cuò),除了代碼語(yǔ)法錯(cuò)誤外,大多是沒(méi)有連相關(guān)庫(kù)一起編譯
g++ main.cpp -o main `pkg-config --cflags --libs opencv4`
?編譯完后會(huì)發(fā)現(xiàn)生成了一個(gè).exe可執(zhí)行文件。通過(guò)指令或雙擊即可看見(jiàn)圖像
./main
?
三、使用opencv處理攝像頭拍攝的圖像
??????? 在計(jì)算機(jī)圖像處理中,攝像頭拍攝得到的原圖并不容易直接處理,我們需要將圖像進(jìn)行多種變換才方便計(jì)算機(jī)進(jìn)行計(jì)算。
????????拿到原圖后,先轉(zhuǎn)換為灰度圖,再轉(zhuǎn)換為均衡圖,原因是灰度圖不容易識(shí)別出人臉輪廓,將其均衡化后更容易檢測(cè)到人臉輪廓。再使用級(jí)連分類器調(diào)用opencv中自帶訓(xùn)練好的人臉模型對(duì)均衡圖進(jìn)行識(shí)別,識(shí)別到人臉后,會(huì)返回人臉列表,我們?cè)谌四樀奈恢卯嬕粋€(gè)矩形方框,這樣就實(shí)現(xiàn)了opencv識(shí)別人臉。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
///opencv.hpp
using namespace std;
using namespace cv;
int main()
{
VideoCapture cap(0); //打開(kāi)攝像頭 <<*>>
if(!cap.isOpened()) //檢測(cè)攝像頭是否打開(kāi)
{
cout << "Camera open failed" << endl;
return 0;
}
cout << "Camera open succed " << endl;
CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml"); //級(jí)聯(lián)分類器,輸入人臉的訓(xùn)練模型 <<*>>
Mat ColorImage;//原圖
Mat GrayImage;//灰度圖
Mat EqualImage;//均衡圖
vector<Rect> AllFace;//創(chuàng)建承載人臉列表的容器
for( ; ; )
{
cap >> ColorImage;
cvtColor(ColorImage,GrayImage,COLOR_BGR2GRAY); //將原圖轉(zhuǎn)換為灰度圖 <<*>>
equalizeHist(GrayImage,EqualImage);//將灰度圖均值化,均值化后的圖像更易檢測(cè)人臉輪廓 <<*>>
Classifier.detectMultiScale(EqualImage,AllFace);//檢測(cè)人臉,返回識(shí)別出人臉的矩形列表<<*>>
if(AllFace.size()) //當(dāng)檢測(cè)到人臉的時(shí)候才畫框
{
rectangle(GrayImage,AllFace[0],Scalar(255,255,0));//通過(guò)rectang將人臉的矩形畫在顯示圖像上 <<*>>
}
imshow("video",GrayImage);//顯示圖像 <<*>>
waitKey(40);
}
}
//g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4`
通過(guò)編譯后即可運(yùn)行得到結(jié)果
g++ main.cpp -o main -I/usr/include/opencv4 `pkg-config --cflags --libs opencv4`
?
????????現(xiàn)在我們就是使用了VideoCapture cap(0)來(lái)開(kāi)啟攝像頭,用cap >> ColorImage讓攝像頭拍照,并通過(guò)opencv訓(xùn)練好的人臉庫(kù)haarcascade_frontalface_alt2.xml和Classifier.detectMultiScale()獲取圖像中人臉的位置,然后我們用rectangle()在人臉位置畫了個(gè)框。
??????? 到目前為止,opencv的任務(wù)已經(jīng)完成了,我們已經(jīng)得到了人臉圖像,就差將人臉上傳到云進(jìn)行AI匹配計(jì)算了,將人臉圖像上傳到云后,云會(huì)把我們上傳的圖像與其人臉庫(kù)中的圖像進(jìn)行對(duì)比,并返回相似度最高的人臉信息。
四、配置百度智能云平臺(tái)
1.配置云
????????使用云平臺(tái)給我們進(jìn)行AI計(jì)算,需要在百度智能云平臺(tái)申請(qǐng)資源并輸入人臉庫(kù)的數(shù)據(jù),這樣云平臺(tái)在接收到我們拍攝到的人臉才能進(jìn)行比對(duì)。百度智能云平臺(tái)的業(yè)務(wù)很多,人臉識(shí)別考勤機(jī)只使用到了人臉識(shí)別業(yè)務(wù)。百度智能云現(xiàn)在有開(kāi)放免費(fèi)的計(jì)算資源,直接可以領(lǐng)取使用。
?根據(jù)操作指引的提示即可在網(wǎng)頁(yè)內(nèi)完成云的配置。
?
在創(chuàng)建完應(yīng)用后,需要錄入人臉庫(kù)。這里顯示了AppID、APIKey、Secret Key,我們正是通過(guò)這三個(gè)關(guān)鍵信息來(lái)讓ubuntu和云進(jìn)行匹配的。
?
?
2.配置ubuntu
???????? 配置好云后,在我們自己的ubuntu上也需要進(jìn)行配置,這樣才能兼容到智能云的API,即在ubuntu上搭建SDK,SDK是軟件開(kāi)發(fā)工具包,在ubuntu里面搭建后才能往代碼里寫上與云平臺(tái)有關(guān)的代碼。
下載即得到一個(gè)壓縮包,我們把壓縮包解壓后放入我們的項(xiàng)目文件夾,確保我們的main在這個(gè)文件夾里面。
??????? 百度云的SDK也依賴一些其他的庫(kù),我們也要把這些庫(kù)安裝上。
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install openssl
sudo apt-get install libjson-dev
sudo apt-get install libssl-dev
?文章來(lái)源地址http://www.zghlxwxcb.cn/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()) //檢測(cè)攝像頭是否打開(kāi)
{
cout << "Camera open failed" << endl;
return 0;
}
cout << "Camera open succed " << endl;
CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml"); //集聯(lián)分類器,輸入人臉的訓(xùn)練模型
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,通過(guò)這個(gè)建立Ubuntu和云的聯(lián)系 <<*>>
Mat ColorImage;//原圖
Mat GrayImage;//灰度圖
Mat EqualImage;//均衡圖
vector<Rect> AllFace;//創(chuàng)建承載人臉列表的容器
Mat MatFace;//人臉圖
vector<uchar> JpgFace;//用來(lái)存儲(chǔ).jpg形式的變量
string Base64Face;//用來(lái)存儲(chǔ)base64格式的變量
Json::Value result;//用來(lái)存儲(chǔ)百度智能云返回的結(jié)果
time_t sec;
for( ; ; )
{
cap >> ColorImage;
cvtColor(ColorImage,GrayImage,COLOR_BGR2GRAY); //將原圖轉(zhuǎn)換為灰度圖
equalizeHist(GrayImage,EqualImage);//將灰度圖均值化,均值化后的圖像更易檢測(cè)人臉輪廓
Classifier.detectMultiScale(EqualImage,AllFace);//檢測(cè)人臉,返回識(shí)別出人臉的矩形列表
if(AllFace.size()) //當(dāng)檢測(cè)到人臉的時(shí)候才畫框
{
//for(int i = 0;i < std::size(AllFace);i++) //size(AllFace)
//{
rectangle(GrayImage,AllFace[0],Scalar(255,255,0));//通過(guò)rectang將人臉的矩形畫在顯示圖像上
MatFace = GrayImage(AllFace[0]);//將人臉圖取出
imencode(".jpg",MatFace,JpgFace);//將Mat格式轉(zhuǎn)為.jpg
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size());//將.jpg格式的圖片轉(zhuǎn)換為base64格式 <<*>>
result = client.search(Base64Face,"BASE64","User",aip::null);//將本機(jī)截取的人臉發(fā)給百度智能云并獲取結(jié)果 <<*>>
cout << result << endl;//在本機(jī)上打印結(jié)果
//}
}
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,通過(guò)這個(gè)建立Ubuntu和云的聯(lián)系 <<*>>
string Base64Face;//用來(lái)存儲(chǔ)base64格式的變量
Json::Value result;//用來(lái)存儲(chǔ)百度智能云返回的結(jié)果
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size());//將.jpg格式的圖片轉(zhuǎn)換為base64格式 <<*>>
result = client.search(Base64Face,"BASE64","User",aip::null);//將本機(jī)截取的人臉發(fā)給百度智能云并獲取結(jié)果 <<*>>
根據(jù)智能云的文檔進(jìn)行編譯:
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出現(xiàn)報(bào)錯(cuò),按圖片進(jìn)行更改。
可以在終端里面看到云反饋回來(lái)的信息
六、信息處理
這是云返回給我們的信息
{
"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**
}
里面包含了很多內(nèi)容,如識(shí)別的人臉庫(kù)ID,人臉I(yè)D,相似度等,我們使用的時(shí)候不需要顯示那么多信息,于是可以用json庫(kù)來(lái)處理這些信息,當(dāng)識(shí)別的相似度大于80時(shí),我們才讓顯示人們和當(dāng)前時(shí)間。
if( !result["result"].isNull() ) //如果接受到的result不為空,則開(kāi)始判斷相似度
{
if(result["result"]["user_list"][0]["score"].asInt() > 80) //當(dāng)相似度大于80時(shí)才顯示信息
{
cout << result["result"]["user_list"][0]["user_id"] << endl; //顯示人臉名
sec = time(NULL);
cout << ctime(&sec) << endl; //獲取時(shí)間并顯示
}
}
這樣終端就會(huì)顯示人臉名和時(shí)間了
?同時(shí)這些信息也需要記錄備案,且我們想要將信息直接打印到圖像上,opencv庫(kù)有一個(gè)函數(shù)putText()可以直接將信息放在圖像上;而在啟動(dòng)程序的時(shí)候"./mian >> log.txt"這樣會(huì)使終端的輸出重定向到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()) //檢測(cè)攝像頭是否打開(kāi)
{
cout << "Camera open failed" << endl;
return 0;
}
cout << "Camera open succed " << endl;
CascadeClassifier Classifier("/usr/share/opencv4/haarcascades/haarcascade_frontalface_alt2.xml"); //集聯(lián)分類器,輸入人臉的訓(xùn)練模型
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;//創(chuàng)建承載人臉列表的容器
Mat MatFace;//人臉圖
vector<uchar> JpgFace;//用來(lái)存儲(chǔ).jpg形式的變量
string Base64Face;//用來(lái)存儲(chǔ)base64格式的變量
Json::Value result;//用來(lái)存儲(chǔ)百度智能云返回的結(jié)果
time_t sec;
for( ; ; )
{
cap >> ColorImage;
cvtColor(ColorImage,GrayImage,COLOR_BGR2GRAY); //將原圖轉(zhuǎn)換為灰度圖
equalizeHist(GrayImage,EqualImage);//將灰度圖均值化,均值化后的圖像更易檢測(cè)人臉輪廓
Classifier.detectMultiScale(EqualImage,AllFace);//檢測(cè)人臉,返回識(shí)別出人臉的矩形列表
if(AllFace.size()) //當(dāng)檢測(cè)到人臉的時(shí)候才畫框
{
//for(int i = 0;i < std::size(AllFace);i++) //size(AllFace)
//{
rectangle(GrayImage,AllFace[0],Scalar(255,255,0));//通過(guò)rectang將人臉的矩形畫在顯示圖像上
MatFace = GrayImage(AllFace[0]);//將人臉圖取出
imencode(".jpg",MatFace,JpgFace);//將Mat格式轉(zhuǎn)為.jpg
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size());//將.jpg格式的圖片轉(zhuǎn)換為base64格式
result = client.search(Base64Face,"BASE64","User",aip::null);//將本機(jī)截取的人臉發(fā)給百度智能云并獲取結(jié)果
//cout << result << endl;//在本機(jī)上打印結(jié)果
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
?效果:
?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-829984.html
?
到了這里,關(guān)于Ubuntu下的Opencv識(shí)別人臉#采用百度智能云平臺(tái)方案#人臉識(shí)別考勤機(jī)#C++的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!