#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("CProcessUpload"); connect(g_httpBllPtr.get(), &CHttpBll::sgnProcessUpload, this, &faceCompare::onProcessUpload); connect(g_httpBllPtr.get(), &CHttpBll::sgnSaveFaceCompareResult, this, &faceCompare::onSaveFaceCompareResult); 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); }); 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->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()) { 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; } QFileInfo filePath(sFileName); if(!g_faceRecProcPtr->setBaseImage(filePath.absoluteFilePath())) { ShowMsg(g_faceRecProcPtr->errorMsg(), this, MSG_ICON_TYPE::mit_error); return; } } else { ShowMsg(QString::fromLocal8Bit("本场考试需要进行人脸检测,但是您没有上传底照,请联系老师"), this, MSG_ICON_TYPE::mit_error); QTimer::singleShot(3000, this, [&]() { emit exitFaceCompare(); }); return; } } m_bStartCompare = true; ui->btn_fc_compare->setEnabled(false); } 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.nWarnThreshold = 1; #endif // _DEBUG if(fScore*100 > g_appInfoPtr->m_oExamInfo.nWarnThreshold) { 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"; hrp.nRequestType = RequestType::rtProcessUpload; hrp.sCommonStr = __FILE__; hrp.sParamList.push_back(QString("formdataFileType,file,%1").arg(sFileName)); hrp.sParamList.push_back(QString("md5,%1").arg(CCommonTools::fileMd5(sFileName))); hrp.eParamType = HttpParamType::hptFormdata; g_httpBllPtr->post(hrp); } else { //低于阈值 emit compareFailed(QString::fromLocal8Bit("检测失败")); } } } m_bStartCompare = false; } } else { Sleep(100); } } } //文件上传 void faceCompare::onProcessUpload(CProcessUpload processUpload) { if(processUpload.sCommonStr == __FILE__) { if(processUpload.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"] = processUpload.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(processUpload.sMessage.isEmpty()) { ShowMsg(QString::fromLocal8Bit("上传照片失败"), this, MSG_ICON_TYPE::mit_error); } else { ShowMsg(processUpload.sMessage, this, MSG_ICON_TYPE::mit_error); } } } } //保存人脸识别比对验证结果 void faceCompare::onSaveFaceCompareResult(CBaseResponsePackage res) { if(res.nCode == 200) { 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); } } }