#include "faceCompare.h" #include "ui_faceCompare.h" #include "CAppInfo.h" #include #include #include #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"); qRegisterMetaType("CClientExamProcessUploadSign"); qRegisterMetaType("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(); 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(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(); } 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"< 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"<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"<