123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- #include "faceCompare.h"
- #include "ui_faceCompare.h"
- #include "CAppInfo.h"
- #include <QDesktopWidget>
- #include <QFile>
- #include <QFileInfo>
- #include "awMsgBox.h"
- #include "logproc.h"
- #include "CCommonTools.h"
- #include "CFaceRecProc.h"
- faceCompare::faceCompare(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::faceCompare)
- {
- ui->setupUi(this);
- setStyleSheet(g_appInfoPtr->m_sQssStr);
- initUI();
- m_bStartCompare = false;
- qRegisterMetaType<CBaseResponsePackage>("CBaseResponsePackage");
- qRegisterMetaType<CClientExamProcessUploadSign>("CClientExamProcessUploadSign");
- qRegisterMetaType<CUploadFileToAliyun>("CUploadFileToAliyun");
- connect(g_httpBllPtr.get(), &CHttpBll::sgnClientExamProcessUploadSign, this, &faceCompare::onClientExamProcessUploadSign);
- connect(g_httpBllPtr.get(), &CHttpBll::sgnSaveFaceCompareResult, this, &faceCompare::onSaveFaceCompareResult);
- connect(g_httpBllPtr.get(), &CHttpBll::sgnUploadFileToAliyun, this, &faceCompare::onUploadFileToAliyun);
- QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
- sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
- if(!QFile::exists(sFileName))
- {
- CHttpRequestPackage hrp;
- hrp.sUri = g_appInfoPtr->m_sStudentPhotoPath;
- hrp.sCommonStr = sFileName;
- hrp.sCommonStr1 = __FILE__;
- hrp.nRequestType = RequestType::rtDownLoadFile;
- hrp.nRetryCount = 3;
- g_httpBllPtr->downLoad(hrp);
- }
- m_pVideoTimer = std::make_shared<QTimer>();
- m_pVideoTimer->setInterval(200);
- connect(m_pVideoTimer.get(), &QTimer::timeout, this, [&](){
- std::scoped_lock lock(m_imageMutex);
- QImage img = CCommonTools::Mat2QImage(m_nCurImage);
- ui->widget_fc_camera->setAutoFillBackground(true);
- QPalette palette;
- palette.setBrush(QPalette::Window, QBrush(img.scaled(ui->widget_fc_camera->width(), ui->widget_fc_camera->height())));
- ui->widget_fc_camera->setPalette(palette);
- });
- g_clientVideoProcPtr->startTest(this);
- m_pVideoTimer->start();
- connect(this, &faceCompare::compareFailed, this, [&](QString sErrorMsg) {
- ShowMsg(sErrorMsg, this, MSG_ICON_TYPE::mit_error);
- ui->btn_fc_compare->setEnabled(true);
- if(!g_appInfoPtr->m_oExamInfo.bIsFaceCheck)
- {
- if(m_pSkipFaceCompare == nullptr)
- {
- m_pSkipFaceCompare = std::make_shared<skipFaceCompare>(this);
- connect(m_pSkipFaceCompare.get(), &skipFaceCompare::cancel, this, [&](){
- m_pSkipFaceCompare.reset();
- });
- connect(m_pSkipFaceCompare.get(), &skipFaceCompare::confirm, this, [&](){
- //比对成功
- QString sFileName = QString("temp/photo/%1.png").arg(CCommonTools::getUuid());
- QImage imgCompare = CCommonTools::Mat2QImage(m_nCurImage);
- imgCompare.save(sFileName, "PNG");
- CHttpRequestPackage hrp;
- hrp.sUri = "/api/ecs_oe_student/client/exam/process/upload/sign";
- hrp.nRequestType = RequestType::rtClientExamProcessUploadSign;
- hrp.sCommonStr = __FILE__;
- hrp.sCommonStr1 = sFileName;
- hrp.sParamList.push_back(QString("fileSuffix,%1").arg(".png"));
- hrp.sParamList.push_back(QString("fileMd5,%1").arg(CCommonTools::fileMd5(sFileName)));
- hrp.eParamType = HttpParamType::hptBody;
- g_httpBllPtr->post(hrp);
- });
- }
- m_pSkipFaceCompare->show();
- }
- });
-
- m_bIsRun = true;
- m_thread = std::thread(std::bind(&faceCompare::threadProc, this));
- }
- faceCompare::~faceCompare()
- {
- m_pVideoTimer->stop();
- g_clientVideoProcPtr->stopTest();
- m_bIsRun = false;
- m_thread.join();
- awMsgBox::clear(this);
- delete ui;
- }
- void faceCompare::onRenderVideoFrame(const char* userId, TRTCVideoStreamType streamType, TRTCVideoFrame* frame)
- {
- if(g_clientVideoProcPtr->isCameraTest())
- {
- __int64 nServerTime = g_appInfoPtr->serverMTime();
- if(nServerTime - m_lastFaceTime >= 100)
- {
- m_lastFaceTime = nServerTime;
- cv::Mat matImg;
- cv::cvtColor(cv::Mat(frame->height, frame->width, CV_8UC4, frame->data), matImg, CV_RGBA2RGB);
- std::scoped_lock lock(m_imageMutex);
- m_nCurImage = matImg.clone();
- }
- }
- }
- void faceCompare::onDownLoadFile(CDownLoadFileInfo downLoadFileInfo)
- {
- if(downLoadFileInfo.sModuleName == __FILE__)
- {
- if (downLoadFileInfo.nCode == 200)
- {
- QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
- sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
- ui->label_fc_basePhoto->setPixmap(QPixmap(sFileName).scaled(ui->label_fc_basePhoto->width(), ui->label_fc_basePhoto->height(),
- Qt::IgnoreAspectRatio));
- }
- else
- {
- if(downLoadFileInfo.sMessage.isEmpty())
- {
- ShowMsg(QString::fromLocal8Bit("下载失败"), this, MSG_ICON_TYPE::mit_error);
- }
- else
- {
- ShowMsg(downLoadFileInfo.sMessage, this, MSG_ICON_TYPE::mit_error);
- }
- }
- }
- }
- void faceCompare::initUI()
- {
- QDesktopWidget *dekwiget = QApplication::desktop();
- setGeometry(0, 0, dekwiget->width(), dekwiget->height());
- ui->widget_mask->setGeometry(0, 0, dekwiget->width(), dekwiget->height());
- ui->widget_fc_BG->setGeometry((width() - g_appInfoPtr->m_fRate*800)/2, (height() - g_appInfoPtr->m_fRate*536)/2,
- g_appInfoPtr->m_fRate*800, g_appInfoPtr->m_fRate*536);
- ui->label_fc_title->adjustSize();
- ui->label_fc_title->setGeometry(g_appInfoPtr->m_fRate*20, g_appInfoPtr->m_fRate*16,
- ui->label_fc_title->width(), ui->label_fc_title->height());
- ui->btn_fc_close->setGeometry(ui->widget_fc_BG->width() - g_appInfoPtr->m_fRate*(20 + 16),
- g_appInfoPtr->m_fRate*16, g_appInfoPtr->m_fRate*16, g_appInfoPtr->m_fRate*16);
- ui->label_HLine->setGeometry(0, ui->label_fc_title->y() + ui->label_fc_title->height() + g_appInfoPtr->m_fRate*16,
- ui->widget_fc_BG->width(), g_appInfoPtr->m_fRate*1 < 1 ? 1 : g_appInfoPtr->m_fRate*1);
- ui->label_fc_basePhoto->setGeometry(g_appInfoPtr->m_fRate*30, ui->label_HLine->y() + ui->label_HLine->height() + g_appInfoPtr->m_fRate*20,
- g_appInfoPtr->m_fRate*140, g_appInfoPtr->m_fRate*180);
- QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
- sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
- ui->label_fc_basePhoto->setPixmap(QPixmap(sFileName).scaled(ui->label_fc_basePhoto->width(), ui->label_fc_basePhoto->height(),
- Qt::IgnoreAspectRatio));
- ui->label_fc_basePhotoTips->setGeometry(ui->label_fc_basePhoto->x() + g_appInfoPtr->m_fRate*10,
- ui->label_fc_basePhoto->y() + ui->label_fc_basePhoto->height() - g_appInfoPtr->m_fRate*(10+20),
- ui->label_fc_basePhoto->width() - g_appInfoPtr->m_fRate*10*2, g_appInfoPtr->m_fRate*20);
- ui->widget_fc_camera->setGeometry(ui->label_fc_basePhoto->x() + ui->label_fc_basePhoto->width() + g_appInfoPtr->m_fRate*20,
- ui->label_fc_basePhoto->y(), g_appInfoPtr->m_fRate*580, g_appInfoPtr->m_fRate*300);
- ui->label_faceRect->setGeometry((ui->widget_fc_camera->width() - g_appInfoPtr->m_fRate*140)/2,
- (ui->widget_fc_camera->height() - g_appInfoPtr->m_fRate*140 - g_appInfoPtr->m_fRate*(20 + 40))/2,
- g_appInfoPtr->m_fRate*140, g_appInfoPtr->m_fRate*140);
- ui->btn_fc_compare->setGeometry((ui->widget_fc_camera->width() - g_appInfoPtr->m_fRate*120)/2,
- ui->widget_fc_camera->height() - g_appInfoPtr->m_fRate*(20 + 40),
- g_appInfoPtr->m_fRate*120, g_appInfoPtr->m_fRate*40);
- ui->label_fc_tips->adjustSize();
- ui->label_fc_tips->setGeometry(ui->widget_fc_camera->x(), ui->widget_fc_camera->y() + ui->widget_fc_camera->height() + g_appInfoPtr->m_fRate*20,
- ui->label_fc_tips->width(), ui->label_fc_tips->height());
- ui->label_fc_note->setGeometry(ui->widget_fc_camera->x(), ui->label_fc_tips->y() + ui->label_fc_tips->height() + g_appInfoPtr->m_fRate*5,
- g_appInfoPtr->m_fRate*580, g_appInfoPtr->m_fRate*100);
- }
- void faceCompare::on_btn_fc_compare_clicked()
- {
- if(g_faceRecProcPtr == nullptr)
- {
- g_faceRecProcPtr = std::make_shared<CFaceRecProc>();
- }
- if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
- {
- if(!setBaseImage())
- {
- return;
- }
- }
- else
- {
- ShowMsg(QString::fromLocal8Bit("本场考试需要进行人脸检测,但是您没有上传底照,请联系老师"), this, MSG_ICON_TYPE::mit_error);
- QTimer::singleShot(3000, this, [&]() { emit exitFaceCompare(); });
- return;
- }
- // if(!g_faceRecProcPtr->hasBaseImage())
- // {
- // if(!setBaseImage())
- // {
- // return;
- // }
- // }
- m_bStartCompare = true;
- ui->btn_fc_compare->setEnabled(false);
- }
- bool faceCompare::setBaseImage()
- {
- QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
- sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
- if(!QFile::exists(sFileName))
- {
- ShowMsg(QString::fromLocal8Bit("底照下载失败,请检查网络"), this, MSG_ICON_TYPE::mit_error);
- return false;
- }
- QFileInfo filePath(sFileName);
- if(!g_faceRecProcPtr->setBaseImage(filePath.absoluteFilePath()))
- {
- //g_faceRecProcPtr->errorMsg()
- ShowMsg(QString::fromLocal8Bit("底照不符合要求,请更换照片"), this, MSG_ICON_TYPE::mit_error);
- return false;
- }
- return true;
- }
- void faceCompare::on_btn_fc_close_clicked()
- {
- m_bIsRun = false;
- emit exitFaceCompare();
- }
- void faceCompare::threadProc()
- {
- while(m_bIsRun)
- {
- if(m_bStartCompare)
- {
- cv::Mat img = m_nCurImage;
- if(!img.empty())
- {
- //人脸比对
- int nFaceCount = 0;
- float fScore = 0;
- bool bRealness = false;
- int nTime = 0;
- if(!g_faceRecProcPtr->getMaxFaceScoreWithBase(img, nFaceCount, fScore, bRealness, nTime))
- {
- //比对失败
- QString sErrorMsg = g_faceRecProcPtr->errorMsg();
- emit compareFailed(sErrorMsg);
- }
- else
- {
- if(nFaceCount == 0)
- {
- //无人脸
- emit compareFailed(QString::fromLocal8Bit("请让我看到您的正脸"));
- }
- else if(nFaceCount > 1 && g_appInfoPtr->m_oExamInfo.bIsStrangerEnable)
- {
- //陌生人
- emit compareFailed(QString::fromLocal8Bit("检测到陌生人"));
- }
- else
- {
- #ifdef _DEBUG
- g_appInfoPtr->m_oExamInfo.nFaceThreshold = 1;
- #endif // _DEBUG
- if(fScore*100 > g_appInfoPtr->m_oExamInfo.nFaceThreshold || g_appInfoPtr->m_bSkipFaceCheck)
- {
- m_fScore = fScore;
- m_nFaceCount = nFaceCount;
- m_nTime = nTime;
- //比对成功
- QString sFileName = QString("temp/photo/%1.png").arg(CCommonTools::getUuid());
- QImage imgCompare = CCommonTools::Mat2QImage(img);
- imgCompare.save(sFileName, "PNG");
- CHttpRequestPackage hrp;
- hrp.sUri = "/api/ecs_oe_student/client/exam/process/upload/sign";
- hrp.nRequestType = RequestType::rtClientExamProcessUploadSign;
- hrp.sCommonStr = __FILE__;
- hrp.sCommonStr1 = sFileName;
- hrp.sParamList.push_back(QString("fileSuffix,%1").arg(".png"));
- hrp.sParamList.push_back(QString("fileMd5,%1").arg(CCommonTools::fileMd5(sFileName)));
- hrp.eParamType = HttpParamType::hptBody;
- g_httpBllPtr->post(hrp);
- }
- else
- {
- //低于阈值
- emit compareFailed(QString::fromLocal8Bit("检测失败"));
- }
- }
- }
- m_bStartCompare = false;
- }
- }
- else
- {
- Sleep(100);
- }
- }
- }
- //文件上传
- void faceCompare::onClientExamProcessUploadSign(CClientExamProcessUploadSign processUpload)
- {
- try
- {
- if(processUpload.sCommonStr == __FILE__)
- {
- if(processUpload.nCode == 200)
- {
- CHttpRequestPackage hrp;
- hrp.sUri = processUpload.sFormUrl;
- hrp.nRequestType = RequestType::rtUploadFileToAliyun;
- hrp.sCommonStr = __FILE__;
- hrp.sCommonStr1 = processUpload.sAccessUrl;
- hrp.sParamList.push_back(QString("OSSAccessKeyId,%1").arg(processUpload.sOssAcessKeyId));
- hrp.sParamList.push_back(QString("Signature,%1").arg(processUpload.sSignature));
- hrp.sParamList.push_back(QString("key,%1").arg(processUpload.sKey));
- hrp.sParamList.push_back(QString("policy,%1").arg(processUpload.sPolicy));
- hrp.sParamList.push_back(QString("success_action_status,%1").arg(200));
- hrp.sParamList.push_back(QString("formdataFileType,file,%1").arg(processUpload.sFilePath));
- hrp.bNoHostPrefix = true;
- hrp.eParamType = HttpParamType::hptFormdata;
- g_httpBllPtr->post(hrp);
- }
- else
- {
- if(processUpload.sMessage.isEmpty())
- {
- ShowMsg(QString::fromLocal8Bit("上传照片失败"), this, MSG_ICON_TYPE::mit_error);
- }
- else
- {
- ShowMsg(processUpload.sMessage, this, MSG_ICON_TYPE::mit_error);
- }
- }
- }
- }
- catch (const std::exception &e)
- {
- ShowMsg(QString::fromLocal8Bit("上传照片失败"), this, MSG_ICON_TYPE::mit_error);
- myServerLog()<<"onClientExamProcessUploadSign error"<<e.what();
- }
- }
- void faceCompare::onUploadFileToAliyun(CUploadFileToAliyun uploadFileToAliyun)
- {
- try
- {
- if(uploadFileToAliyun.sCommonStr == __FILE__)
- {
- if(uploadFileToAliyun.nCode == 200)
- {
- CHttpRequestPackage hrp;
- hrp.sUri = "/api/ecs_oe_student/client/exam/process/saveFaceCompareResult";
- hrp.nRequestType = RequestType::rtSaveFaceCompareResult;
- Json::Value jBody = Json::Value::null;
- jBody["faceCompareResult"] = QString::number(m_fScore).toStdString();
- jBody["fileUrl"] = uploadFileToAliyun.sFileUrl.toStdString();
- jBody["pass"] = true;
- jBody["processTime"] = m_nTime;
- jBody["stranger"] = m_nFaceCount > 1;
- hrp.sParamList.push_back(QString("CustomBody,%1").arg(jBody.toStyledString().c_str()));
- hrp.eParamType = HttpParamType::hptCustomBody;
- g_httpBllPtr->post(hrp);
- }
- else
- {
- if(uploadFileToAliyun.sMessage.isEmpty())
- {
- ShowMsg(QString::fromLocal8Bit("上传照片失败"), this, MSG_ICON_TYPE::mit_error);
- }
- else
- {
- ShowMsg(uploadFileToAliyun.sMessage, this, MSG_ICON_TYPE::mit_error);
- }
- }
- }
- }
- catch (const std::exception &e)
- {
- ShowMsg(QString::fromLocal8Bit("上传照片失败"), this, MSG_ICON_TYPE::mit_error);
- myServerLog()<<"onUploadFileToAliyun error"<<e.what();
- }
- }
- //保存人脸识别比对验证结果
- void faceCompare::onSaveFaceCompareResult(CBaseResponsePackage res)
- {
- try
- {
- if(res.nCode == 200)
- {
- if(g_appInfoPtr->m_bSkipFaceCheck)
- {
- emit faceComparePass();
- }
- else
- {
- if(m_pSkipFaceCompare && m_pSkipFaceCompare->isVisible())
- {
- m_pSkipFaceCompare.reset();
- emit faceComparePass();
- }
- else
- {
- ShowMsg(QString::fromLocal8Bit("人脸比对成功"), this, MSG_ICON_TYPE::mit_succeed);
- QTimer::singleShot(3000, this, [&](){
- emit faceComparePass();
- });
- }
- }
- }
- else
- {
- if(res.sMessage.isEmpty())
- {
- ShowMsg(QString::fromLocal8Bit("保存人脸识别信息失败"), this, MSG_ICON_TYPE::mit_error);
- }
- else
- {
- ShowMsg(res.sMessage, this, MSG_ICON_TYPE::mit_error);
- }
- }
- }
- catch (const std::exception &e)
- {
- ShowMsg(QString::fromLocal8Bit("保存人脸识别信息失败"), this, MSG_ICON_TYPE::mit_error);
- myServerLog()<<"onSaveFaceCompareResult error"<<e.what();
- }
- }
|