1. 開發(fā)環(huán)境
Ubuntu18 + OpenCV3 + qt5
2.環(huán)境配置
1. 虛擬機安裝Ubuntu
2. 安裝qt5
下載完成后在下載目錄打開終端,賦予可執(zhí)行權(quán)限,再執(zhí)行即可安裝qt
sudo chmod +x qt-opensource-linux-x64-5.12.8.run
3. 安裝OpenCV庫
可參考文章
4. 在QT中引用OpenCV庫
若按照上述方法安裝好opencv,創(chuàng)建測試項目,在pro文件中加入:
INCLUDEPATH += /usr/local/include //opencv頭文件安裝路徑
LIBS += /usr/local/lib/libopencv_* //opencv庫文件路徑
測試:
#include <QWidget>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <QMessageBox>
#include <QDebug>
using namespace std;
using namespace cv;
//widget.cpp的析構(gòu)函數(shù)
{
VideoCapture cap(0);
if(!cap.isOpened())
QMessageBox::warning(this,"error","open camera faild!");
cout << "open camera success" << endl;
Mat frame;
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
cap.set(cv::CAP_PROP_FPS, 30);
for(;;){
cap >> frame;
if (frame.empty()) {
qDebug() << "錯誤:無法捕獲幀";
break; // 退出循環(huán)或根據(jù)需要處理錯誤
}
imshow("video", frame);
waitKey(27);
}
}
(若出現(xiàn)警告 “VIDEOIO(V4L2:/dev/video0): select() timeout”,在虛擬機->設(shè)置->USB控制器,更改一下兼容性,更改為3.1即可解決問題)
啟動程序若正常出現(xiàn)攝像頭畫面則表明安裝配置成功。
ps:一般配置完成后你會發(fā)現(xiàn)攝像頭是反鏡像的(實際使用一般是鏡像-前置攝像頭)這是可以用flip函數(shù)來調(diào)整畫面流frame:
flip(image, flippedImage, 1): 水平翻轉(zhuǎn)
flip(image, flippedImage, 0): 垂直翻轉(zhuǎn)
flip(image, flippedImage, -1): 水平和垂直同時翻轉(zhuǎn)
flip 函數(shù)有三個參數(shù),分別是:
**image:**輸入圖像,即需要進行翻轉(zhuǎn)的原始圖像。
**flippedImage:**輸出圖像,即翻轉(zhuǎn)后的圖像將存儲在這里。
這里使用 flip(frame, frame, 1);即可改變原圖形
3. 人臉檢測
1.圖像處理
- 將攝像頭畫面由rgb(彩色)轉(zhuǎn)換為gray(灰度圖)
#include <opencv2/imgproc.hpp> //所需頭文件
#include <opencv2/objdetect.hpp>
cvtColor(frame,Grayimage,CV_BGR2GRAY);//將彩色圖轉(zhuǎn)換從灰度圖 其中frame是初始Mat容器所存放的畫面流,
//Grayimage是轉(zhuǎn)換后的圖像 CV_BGR2GRAY是參數(shù)
- 圖形均衡化(調(diào)整亮度,對比度)
equalizeHist(InputArray src,OutputArray dst); //函數(shù)參數(shù)說明
equalizeHist(Grayimage,Grayimage); //進行均衡化處理,將處理后的圖形進行覆蓋(節(jié)約內(nèi)存)
2.人臉輪廓檢測
- 加載級聯(lián)分類器(CascadeClassifier)(關(guān)于級聯(lián)分類器相關(guān)可參考)
Ubuntu:/usr/share/opencv/haarcascades$ ls
haarcascade_eye_tree_eyeglasses.xml
haarcascade_eye.xml
haarcascade_frontalcatface_extended.xml
haarcascade_frontalcatface.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_licence_plate_rus_16stages.xml
haarcascade_lowerbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_russian_plate_number.xml
haarcascade_smile.xml
haarcascade_upperbody.xml
//這里我們使用OpenCV訓(xùn)練好的級聯(lián)分類器進行人臉輪廓檢測,可在構(gòu)造函數(shù)中聲明即可
classifier.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml");
if (classifier.empty()) {
qDebug() << "錯誤:無法加載級聯(lián)分類器文件";
}
/*
detectMultiScale(InputArray image,vector<Rect>& objects) 檢測函數(shù)說明
rectangle (InputOutputArray img,Point pt1,Point pt2,constScalar& color) 將檢測到的人臉矩形框繪制在圖形上的函數(shù)說明
*/
//具體使用:
vector<Rect> Allface; //矩形存放容器
//這里我們使用OpenCV庫中已經(jīng)訓(xùn)練好的級聯(lián)分類器進行人臉輪廓的識別
classifier.detectMultiScale(Grayimage,Allface); //檢測人臉矩形存放到vector容器中
if(Allface.size()){ //是否存在人臉
rectangle(Grayimage,Allface[0],Scalar(255,0,0)); //Allce中存放多個矩形(多張人臉,按照數(shù)組形式排列 Scalar改變顏色(rgb)
}
上述僅為關(guān)鍵代碼
- 將檢測的人臉矩形框保存
//先創(chuàng)建一個Mat容器用于存放截取到的矩形人臉框
Mat Matface; //存放檢測的人臉矩形框
vector<uchar> JpgFace; //存放jpg格式的圖形
if(Allface.size()){ //是否存在人臉
rectangle(Grayimage,Allface[0],Scalar(255,0,0)); //Allce中存放多個矩形(多張人臉,按照數(shù)組形式排列 Scalar改變顏色(rgb)
Matface = Grayimage(Allface[0]); //將截取的人臉存放到Matface中
imencode(".jpg",Matface,JpgFace); //將Matface中的圖片轉(zhuǎn)化成jpg格式
}
//imencode函數(shù)說明:
imencode(const String &ext,InputArray img,vector<uchar> &buf)
3.百度智能云平臺注冊
- 注冊百度智能云平臺
進入官網(wǎng)>產(chǎn)品>人臉識別>人臉搜索 官網(wǎng)鏈接
立即創(chuàng)建即可
即可在應(yīng)用列表查看到自己的接口信息
- 創(chuàng)建人臉庫
選擇查看人臉庫即可自定義添加組和人員,上傳清晰人臉照即可
4.SDK環(huán)境搭建
- 技術(shù)文檔 > SDK文檔 > C++文檔 > 按照流程下載人臉識別SDK到Ubuntu中(具體流程可參考文檔)
- 安裝依賴庫libcurl(需要支持https)openssl(加密) jsoncpp
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install openssl
sudo apt-get install libjsoncpp-dev
- 將下載好的SDK解壓,并將其base文件夾以及face.h(人臉檢測只需這兩個文件)文件復(fù)制到你的項目中參考文檔
這里編譯可能會出現(xiàn)報錯找不到j(luò)son和openssl路徑,點擊錯誤代碼行,將其改為
#include <jsoncpp/json/json.h>
,#include "jsoncpp/json/json.h"
(即改變路徑,在前面加上jsoncpp)
并安裝libssl庫
sudo apt-get install libssl-dev
LIBS += -lcurl -lcrypto -ljsoncpp //在pro文件中加入
并在程序中引入頭文件和命名空間
#include <face.h>
using namespace aip;
5.平臺接入
- 建立交互客戶端client
//頭文件中先聲明client指針類型對象,再在構(gòu)造函數(shù)中實例化賦值(使用完后需要用delete client進行銷毀)
//widget.h
Face *client; //創(chuàng)建客戶端對象
//widget.cpp
//建立百度交互客戶端client
// 設(shè)置APPID/AK/SK
string app_id = "你自己的";
string api_key = "你自己的";
string secret_key = "你自己的";
client = new Face(app_id,api_key,secret_key);
- 格式轉(zhuǎn)換
梳理一下我們的攝像頭捕捉流程
frame(初始的彩色視頻幀流) > Grayimage(灰度化)> Matface(存放截取的人臉矩形)> JpgFace(人臉矩形圖片轉(zhuǎn)化為JPG格式)> Base64Fce(轉(zhuǎn)化為base64格式-百度人臉識別要求的格式)>>>>
//widget.h
//先在頭文件的private中聲明一個容器存放base64格式的圖片
string Base64Face; //用于存放轉(zhuǎn)換成base64格式的照片
//widget.cpp
Base64Face = base64_encode((char *)JpgFace.data(),JpgFace.size()); //將jpg格式的圖片轉(zhuǎn)化為base64格式的
- 接收檢測結(jié)果
//widget.h
Json::Value result; //用于接受檢測結(jié)果的容器
// 帶參數(shù)調(diào)用人臉搜索函數(shù)說明
//result = client.face_search_v3(image, image_type, group_id_list, options);
result = client->face_search_v3(Base64Face,"BASE64","student",Json::nullValue);
cout << result <<endl; //打印測試結(jié)果
這里如果報錯multiple definition (多重定義):可以將出現(xiàn)多重定義的函數(shù)定義為static(靜態(tài)函數(shù))
6.驗證檢測結(jié)果
可以看到控制臺已經(jīng)輸出JSON格式的數(shù)據(jù),并且檢測成功文章來源:http://www.zghlxwxcb.cn/news/detail-813312.html
7.解析數(shù)據(jù)
- json解析
//result返回json數(shù)據(jù)格式
{
"cached" : 0,
"error_code" : 0,
"error_msg" : "SUCCESS",
"log_id" : 2660475389,
"result" :
{
"face_token" : "952d7830427201926483ab1f02f015b8",
"user_list" :
[
{
"group_id" : "student",
"score" : 80.822387695312003,
"user_id" : "yyqx",
"user_info" : ""
}
]
},
"timestamp" : 1705394660
}
if(!result["result"].isNull()) //發(fā)送來的數(shù)據(jù)中result不為空(檢測到人臉)
{
if(result["result"]["user_list"][0]["score"].asInt() >= 88) //提取數(shù)據(jù)中的score信息(匹配度高才算成功)
{
QString name = QString::fromStdString(result["result"]["user_list"][0]["user_id"].asString()); //將姓名轉(zhuǎn)化成Qstring類型以便提示
QMessageBox::information(this,"歡迎!",name+"打卡成功!");
}
else if(result["result"]["user_list"][0]["score"].asInt() < 88) { //未在人臉庫中
QMessageBox::information(this,"歡迎!","人員未注冊,請聯(lián)系管理員!");
}
}
jsoncpp的解析可參考
這里已經(jīng)實現(xiàn)了人臉檢測+識別+數(shù)據(jù)解析文章來源地址http://www.zghlxwxcb.cn/news/detail-813312.html
- 獲取系統(tǒng)時間
//widget.h
#include <QDateTime>
QDateTime currenttime; //獲取時間
//更新后
if(!result["result"].isNull()) //發(fā)送來的數(shù)據(jù)中result不為空(檢測到人臉)
{
if(result["result"]["user_list"][0]["score"].asInt() >= 88) //提取數(shù)據(jù)中的score信息(匹配度高才算成功)
{
currenttime = QDateTime::currentDateTime(); // 獲取當前時間
QString checktime = currenttime.toString("yyyy-MM-dd hh:mm:ss"); // 將時間轉(zhuǎn)換為字符串
QString name = QString::fromStdString(result["result"]["user_list"][0]["user_id"].asString()); // 將姓名轉(zhuǎn)化成QString類型以便提示
QMessageBox::information(this, "歡迎!", name + "打卡成功!" + checktime);
}
else if(result["result"]["user_list"][0]["score"].asInt() < 88) { //未在人臉庫中
QMessageBox::information(this,"歡迎!","人員未注冊,請聯(lián)系管理員!");
}
}
- 效果
到了這里,關(guān)于OpenCV+Ubuntu+QT實現(xiàn)人臉檢測/識別(考勤管理)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!