mainwidget.cpp:
#include "mainwidget.h"
#include "ui_mainwidget.h"
#include <QDebug>
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MainWidget)
{
ui->setupUi(this);
// faceInfo.setIsable(false);
//显示所有摄像头信息
const QList<QCameraInfo> cameraInfoList = QCameraInfo::availableCameras();
for (const QCameraInfo &tmpCam : cameraInfoList) {
// qDebug() << tmpCam.deviceName() << "|||" << tmpCam.description();
ui->comboBox->addItem(tmpCam.description());
}
connect(ui->comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index){
qDebug() << cameraInfoList.at(index).description();
refreshTimer->stop();
camera->stop();
camera->deleteLater();
camera = new QCamera(cameraInfoList.at(index));
imageCapture->deleteLater();
// camera = new QCamera();
// finder = new QCameraViewfinder();
imageCapture = new QCameraImageCapture(camera);
camera->setViewfinder(finder);
camera->setCaptureMode(QCamera::CaptureStillImage);
imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
connect(imageCapture, &QCameraImageCapture::imageCaptured, this, [=](int id, const QImage &preview){
Q_UNUSED(id);
faceImg = preview;
ui->label->setPixmap(QPixmap::fromImage(preview));
});
//-->
// connect(imageCapture, &QCameraImageCapture::imageCaptured, this, &MainWidget::showPic);
camera->start();
refreshTimer->start(40);
});
//进行摄像头配置
camera = new QCamera();
finder = new QCameraViewfinder();
imageCapture = new QCameraImageCapture(camera);
camera->setViewfinder(finder);
camera->setCaptureMode(QCamera::CaptureStillImage);
imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
connect(imageCapture, &QCameraImageCapture::imageCaptured, this, &MainWidget::showPic);
camera->start();
//设置定时器帮刷新界面
refreshTimer = new QTimer(this);
connect(refreshTimer, &QTimer::timeout, this, &MainWidget::takePicture);
refreshTimer->start(40);
// detectTimer = new QTimer(this);
// connect(detectTimer, &QTimer::timeout, this, [&](){
// //进行人脸检测
// childThread = new QThread(this);
// Worker *worker = new Worker;
// worker->moveToThread(childThread);
// connect(this, &MainWidget::beginWork, worker, &Worker::doWork);
// connect(worker, &Worker::resultReady, this, &MainWidget::handlerResults);
// connect(childThread, &QThread::finished, worker, &QObject::deleteLater);
// childThread->start();
// emit beginWork(faceImg, childThread);
// });
// detectTimer->start(2000);
//设置布局
QVBoxLayout *vboxl = new QVBoxLayout;
vboxl->addWidget(ui->label);
vboxl->addWidget(ui->pushButton);
QVBoxLayout *vboxr = new QVBoxLayout;
vboxr->addWidget(ui->comboBox);
vboxr->addWidget(finder);
vboxr->addWidget(ui->textBrowser);
QBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vboxl);
hbox->addLayout(vboxr);
this->setLayout(hbox);
imgManager = new QNetworkAccessManager(this);
connect(imgManager, &QNetworkAccessManager::finished, this, [&](QNetworkReply *reply){
//处理应答
if (reply->error() != QNetworkReply::NoError) {
qDebug() << reply->errorString();
return ;
}
QByteArray replyData = reply->readAll();
// qDebug() << replyData;
QJsonParseError jsonErr;
QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonErr);
if (jsonErr.error != QJsonParseError::NoError) {
qDebug() << "Json Parse Error:" << jsonErr.errorString();
return;
}
QJsonObject obj = doc.object();
//for 人脸识别
if (!obj.contains("result")) return;
QJsonObject resultObj = obj.value("result").toObject();
//人脸数目必须>1
if (!resultObj.contains("face_num")) return ;
if (resultObj.value("face_num").toInt() < 1) return;
if (!resultObj.contains("face_list")) return;
QJsonArray faceList = resultObj.value("face_list").toArray();
QJsonObject faceInfoObj = faceList[0].toObject();
if (!faceInfoObj.contains("location")) return;
QJsonObject locationObj = faceInfoObj.value("location").toObject();
if (!locationObj.contains("left")) return;
this->faceInfo.setLeft(locationObj.value("left").toDouble());
if (!locationObj.contains("top")) return;
this->faceInfo.setTop(locationObj.value("top").toDouble());
if (!locationObj.contains("width")) return;
this->faceInfo.setWidth(locationObj.value("width").toDouble());
if (!locationObj.contains("height")) return;
this->faceInfo.setHeight(locationObj.value("height").toDouble());
qDebug() << faceInfo.getLeft();
qDebug() << faceInfo.getTop();
qDebug() << faceInfo.getWidth();
qDebug() << faceInfo.getHeight();
if (!faceInfoObj.contains("age")) return;
this->faceInfo.setAge(faceInfoObj.value("age").toInt());
QJsonObject tmpObj;
if (!faceInfoObj.contains("face_shape")) return ;
tmpObj = faceInfoObj.value("face_shape").toObject();
if (!tmpObj.contains("type")) return;
this->faceInfo.setFace_shape(tmpObj.value("type").toString());
if (!faceInfoObj.contains("gender")) return ;
tmpObj = faceInfoObj.value("gender").toObject();
if (!tmpObj.contains("type")) return;
this->faceInfo.setGender(tmpObj.value("type").toString());
if (!faceInfoObj.contains("glasses")) return ;
tmpObj = faceInfoObj.value("glasses").toObject();
if (!tmpObj.contains("type")) return;
this->faceInfo.setGlasses(tmpObj.value("type").toString());
if (!faceInfoObj.contains("emotion")) return ;
tmpObj = faceInfoObj.value("emotion").toObject();
if (!tmpObj.contains("type")) return;
this->faceInfo.setEmotion(tmpObj.value("type").toString());
if (!faceInfoObj.contains("face_type")) return ;
tmpObj = faceInfoObj.value("face_type").toObject();
if (!tmpObj.contains("type")) return;
this->faceInfo.setFace_type(tmpObj.value("type").toString());
if (!faceInfoObj.contains("mask")) return ;
tmpObj = faceInfoObj.value("mask").toObject();
if (!tmpObj.contains("type")) return;
this->faceInfo.setMask(tmpObj.value("type").toInt());
if (!faceInfoObj.contains("beauty")) return ;
this->faceInfo.setBeauty(faceInfoObj.value("beauty").toDouble());
faceInfo.setIsable(true);
QString faceStr;
faceStr.append("年龄:").append(QString::number(faceInfo.getAge())).append("\n");
faceStr.append("性别:").append(faceInfo.getGender()).append("\n");
faceStr.append("戴眼镜:").append(faceInfo.getGlasses()).append("\n");
faceStr.append("情绪:").append(faceInfo.getEmotion()).append("\n");
faceStr.append("脸型:").append(faceInfo.getFace_shape()).append("\n");
faceStr.append("戴口罩:").append(faceInfo.getMask()==0?"没戴" : "戴了").append("\n");
faceStr.append("颜值:").append(QString::number(faceInfo.getBeauty())).append("\n");
ui->textBrowser->setText(faceStr);
});
//设置按钮点击操作
// //connect(ui->pushButton, &QPushButton::clicked, this, &MainWidget::beginGame);
connect(ui->pushButton, &QPushButton::clicked, this, &MainWidget::detectFace);
// connect(ui->pushButton, &QPushButton::clicked, this, &MainWidget::takePicture);
// connect(ui->pushButton, &QPushButton::clicked, this, [&](){
// //进行人脸检测
qDebug() << 1;
childThread = new QThread(this);
Worker *worker = new Worker;
worker->moveToThread(childThread);
connect(this, &MainWidget::beginWork, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &MainWidget::handlerResults);
connect(childThread, &QThread::finished, worker, &QObject::deleteLater);
childThread->start();
emit beginWork(faceImg);
// //进行base64编码转换
// QByteArray ba;
// QBuffer buff(&ba);
// faceImg.save(&buff, "png");
// QString base64str = ba.toBase64();
qDebug() << base64str;
// //组装请求体
// QJsonObject postJson;
// postJson.insert("image", base64str);
// postJson.insert("image_type", "BASE64");
// postJson.insert("face_field", "age,expression,face_shape,gender,glasses,quality,emotion,face_type,mask,beauty");
// QJsonDocument doc;
// doc.setObject(postJson);
// QByteArray postData = doc.toJson(QJsonDocument::Compact);
// //组装请求包
// QUrl url("https://aip.baidubce.com/rest/2.0/face/v3/detect");
// QUrlQuery query;
// query.addQueryItem("access_token", accessToken);
// url.setQuery(query);
// QNetworkRequest req;
// req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
// req.setUrl(url);
// req.setSslConfiguration(sslConfig);
// imgManager->post(req, postData);
// });
//支持https协议
tokenManager = new QNetworkAccessManager(this);
qDebug() << tokenManager->supportedSchemes();
if (QSslSocket::supportsSsl()) {
qDebug() << "support ssl";
} else {
qDebug() << "not support ssl";
}
//发送token请求
QUrl url("https://aip.baidubce.com/oauth/2.0/token");
QUrlQuery query;
query.addQueryItem("grant_type", "client_credentials");
query.addQueryItem("client_id", "2jC1MWx7CuVdAfmfKQjLMoF8");
query.addQueryItem("client_secret", "U66s1gEthBNlFHRWKYLsGgQYH7L0iSaO");
url.setQuery(query);
qDebug() << url;
//配置SSL//
sslConfig = QSslConfiguration::defaultConfiguration();
sslConfig.setPeerVerifyMode(QSslSocket::QueryPeer);
sslConfig.setProtocol(QSsl::TlsV1_2);
//配置token请求
QNetworkRequest req;
req.setUrl(url);
req.setSslConfiguration(sslConfig);
tokenManager = new QNetworkAccessManager(this);
connect(tokenManager, &QNetworkAccessManager::finished, this,
[&](QNetworkReply *reply){
//处理应答
if (reply->error() != QNetworkReply::NoError) {
qDebug() << reply->errorString();
return;
}
QByteArray replyData = reply->readAll();
qDebug() << replyData;
QJsonParseError jsonErr;
QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonErr);
if (jsonErr.error != QJsonParseError::NoError) {
qDebug() << "Json Parse Error:" << jsonErr.errorString();
return ;
}
QJsonObject obj = doc.object();
if (!obj.contains("access_token")) {
qDebug() << "No key: access_token";
return;
}
accessToken = obj.value("access_token").toString();
ui->textBrowser->setText(accessToken);
});
tokenManager->get(req);
}
MainWidget::~MainWidget()
{
delete ui;
}
void MainWidget::takePicture()
{
imageCapture->capture();
}
void MainWidget::showPic(int id, const QImage &preview) {
Q_UNUSED(id);
faceImg = preview;
if (faceInfo.getIsable()) {
QPainter p(&faceImg);
p.setPen(Qt::red);
p.drawRect(faceInfo.getLeft(),
faceInfo.getTop(),
faceInfo.getWidth(),
faceInfo.getHeight());
//img 1654x1654->610X418
p.drawPixmap(faceInfo.getLeft() + faceInfo.getWidth() / 2 - 255,
faceInfo.getTop() - 368,
610, 418,
QPixmap(":/tuer.png"),
0, 0, 0, 0);
}
ui->label->setPixmap(QPixmap::fromImage(faceImg));
}
void MainWidget::handlerResults(QByteArray postData, QThread *thisThread) {
thisThread->quit();
thisThread->wait();
if (childThread->isFinished()) {
qDebug() << "子进程结束";
} else {
qDebug() << "子进程未结束";
}
detectFace();
//组装请求包
QUrl url("https://aip.baidubce.com/rest/2.0/face/v3/detect");
// QUrl url("https://aip.baidubce.com/rest/2.0/image-classify/v1/gesture");
QUrlQuery query;
query.addQueryItem("access_token", accessToken);
url.setQuery(query);
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
// req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
req.setUrl(url);
req.setSslConfiguration(sslConfig);
imgManager->post(req, postData);
}
void MainWidget::detectFace() {
//进行人脸检测
childThread = new QThread(this);
Worker *worker = new Worker;
worker->moveToThread(childThread);
connect(this, &MainWidget::beginWork, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &MainWidget::handlerResults);
connect(childThread, &QThread::finished, worker, &QObject::deleteLater);
childThread->start();
emit beginWork(faceImg, childThread);
}
多线程worker.cpp:
#include "Worker.h"
Worker::Worker(QObject *parent)
: QObject{parent}
{
}
void Worker::doWork(QImage faceImg, QThread *thisThread) {
//进行base64编码转换
QByteArray ba;
QBuffer buff(&ba);
faceImg.save(&buff, "png");
//for人脸识别
QString base64str = ba.toBase64();
//qDebug() << base64str;
//组装请求体
QJsonObject postJson;
postJson.insert("image", base64str);
postJson.insert("image_type", "BASE64");
postJson.insert("face_field", "age,expression,face_shape,gender,glasses,quality,emotion,face_type,mask,beauty");
QJsonDocument doc;
doc.setObject(postJson);
QByteArray postData = doc.toJson(QJsonDocument::Compact);
emit resultReady(postData, thisThread);
}
结果: