inprogressFace.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #include "inprogressFace.h"
  2. #include "logproc.h"
  3. #include "CCommonTools.h"
  4. #include "CFaceRecProc.h"
  5. #include "CAppInfo.h"
  6. #include "json/json.h"
  7. std::shared_ptr<CInprogressFace> g_inProcessFace = nullptr;
  8. CInprogressFace::CInprogressFace()
  9. {
  10. qRegisterMetaType<CClientExamProcessUploadSign>("CClientExamProcessUploadSign");
  11. connect(g_httpBllPtr.get(), &CHttpBll::sgnClientExamProcessUploadSign, this, &CInprogressFace::onClientExamProcessUploadSign);
  12. qRegisterMetaType<CBaseResponsePackage>("CBaseResponsePackage");
  13. connect(g_httpBllPtr.get(), &CHttpBll::sgnSaveFaceCaptureResult, this, &CInprogressFace::onSaveFaceCaptureResult);
  14. qRegisterMetaType<CUploadFileToAliyun>("CUploadFileToAliyun");
  15. connect(g_httpBllPtr.get(), &CHttpBll::sgnUploadFileToAliyun, this, &CInprogressFace::onUploadFileToAliyun);
  16. genCameraInfo();
  17. m_bIsRun = true;
  18. m_thread = std::thread(std::bind(&CInprogressFace::threadProc, this));
  19. }
  20. void CInprogressFace::genCameraInfo()
  21. {
  22. std::vector<CameraInfo> list;
  23. if(CCommonTools::listCameraDevices(list) <= 0)
  24. {
  25. return;
  26. }
  27. Json::Value jCameraInfo;
  28. for(CameraInfo &ci : list)
  29. {
  30. if(ci.pid.empty() || ci.vid.empty())
  31. {
  32. m_bHasVirtualCamera = true;
  33. }
  34. Json::Value jCamera;
  35. jCamera["detail"] = QString::fromStdWString(ci.detail.c_str()).toStdString();
  36. jCamera["name"] = QString::fromStdWString(ci.name.c_str()).toStdString();
  37. jCamera["pid"] = QString::fromStdWString(ci.pid.c_str()).toStdString();
  38. jCamera["vid"] = QString::fromStdWString(ci.vid.c_str()).toStdString();
  39. jCameraInfo.append(jCamera);
  40. }
  41. m_sCameraInfo = Json::FastWriter().write(jCameraInfo).c_str();
  42. }
  43. CInprogressFace::~CInprogressFace()
  44. {
  45. m_bIsRun = false;
  46. m_thread.join();
  47. }
  48. void CInprogressFace::startFaceVerify(bool bVerify)
  49. {
  50. m_bStart = bVerify;
  51. }
  52. void CInprogressFace::addImage(cv::Mat matImage)
  53. {
  54. if(m_bStart)
  55. {
  56. std::scoped_lock lock(m_mImgList);
  57. m_vImgList.push_back(matImage);
  58. }
  59. }
  60. void CInprogressFace::addFaceCountImage(cv::Mat matImage)
  61. {
  62. myServerLog()<<"inprogress start"<<m_bStart;
  63. if(m_bStart)
  64. {
  65. std::scoped_lock lock(m_mImgFaceCountList);
  66. m_vImgFaceCountList.push_back(matImage);
  67. }
  68. }
  69. void CInprogressFace::threadProc()
  70. {
  71. if (g_faceRecProcPtr == nullptr)
  72. {
  73. g_faceRecProcPtr = std::make_shared<CFaceRecProc>();
  74. }
  75. if (!g_appInfoPtr->m_sStudentPhotoPath.isEmpty())
  76. {
  77. QString sFileName = g_appInfoPtr->m_sStudentPhotoPath.right(g_appInfoPtr->m_sStudentPhotoPath.length() - g_appInfoPtr->m_sStudentPhotoPath.lastIndexOf("/") - 1);
  78. sFileName = g_appInfoPtr->m_sCacheFileDir + sFileName;
  79. if (!QFile::exists(sFileName))
  80. {
  81. emit compareFailed(QString::fromLocal8Bit("底照下载失败,请检查网络"));
  82. return;
  83. }
  84. if(!g_faceRecProcPtr->setBaseImage(sFileName))
  85. {
  86. emit compareFailed(g_faceRecProcPtr->errorMsg());
  87. return;
  88. }
  89. }
  90. else
  91. {
  92. emit compareFailed(QString::fromLocal8Bit("当前考试未底照"));
  93. return;
  94. }
  95. while(m_bIsRun)
  96. {
  97. if(m_bStart)
  98. {
  99. if(m_vImgFaceCountList.begin() != m_vImgFaceCountList.end())
  100. {
  101. cv::Mat matImage;
  102. {
  103. std::scoped_lock lock(m_mImgFaceCountList);
  104. matImage = (*m_vImgFaceCountList.begin()).clone();
  105. m_vImgFaceCountList.erase(m_vImgFaceCountList.begin());
  106. }
  107. if(matImage.empty())
  108. {
  109. myServerLog()<<"Inprogress matImage.empty";
  110. continue;
  111. }
  112. int nFaceCount = 0;
  113. if(g_faceRecProcPtr->getFaceCount(matImage, nFaceCount))
  114. {
  115. if(nFaceCount == 0)
  116. {
  117. //无人脸
  118. emit compareFailed(QString::fromLocal8Bit("请调整坐姿,诚信考试"));
  119. }
  120. else if(nFaceCount > 1 && g_appInfoPtr->m_oExamInfo.bIsStrangerEnable)
  121. {
  122. //陌生人
  123. emit compareFailed(QString::fromLocal8Bit("请独立完成考试"));
  124. }
  125. }
  126. else
  127. {
  128. QString sErrorMsg = g_faceRecProcPtr->errorMsg();
  129. myDebug()<<QString::fromLocal8Bit("人脸检测失败:")<<sErrorMsg;
  130. }
  131. }
  132. if(m_vImgList.begin() != m_vImgList.end())
  133. {
  134. cv::Mat matImage;
  135. {
  136. std::scoped_lock lock(m_mImgList);
  137. matImage = (*m_vImgList.begin()).clone();
  138. m_vImgList.erase(m_vImgList.begin());
  139. }
  140. if(matImage.empty())
  141. {
  142. myDebug()<<"matImage.empty";
  143. continue;
  144. }
  145. int nFaceCount = 0;
  146. float fScore = 0;
  147. bool bRealness = false;
  148. int nTime = 0;
  149. if(!g_faceRecProcPtr->getMaxFaceScoreWithBase(matImage, nFaceCount, fScore, bRealness, nTime))
  150. {
  151. //比对失败
  152. QString sErrorMsg = g_faceRecProcPtr->errorMsg();
  153. myDebug()<<QString::fromLocal8Bit("人脸检测失败:")<<sErrorMsg;
  154. uploadFile(matImage, nFaceCount, fScore, bRealness);
  155. emit compareFailed(sErrorMsg);
  156. }
  157. else
  158. {
  159. if(nFaceCount == 0)
  160. {
  161. //无人脸
  162. uploadFile(matImage, nFaceCount, fScore, bRealness);
  163. emit compareFailed(QString::fromLocal8Bit("请让我看到您的正脸"));
  164. }
  165. else if(nFaceCount > 1 && g_appInfoPtr->m_oExamInfo.bIsStrangerEnable)
  166. {
  167. //陌生人
  168. uploadFile(matImage, nFaceCount, fScore, bRealness);
  169. emit compareFailed(QString::fromLocal8Bit("检测到陌生人"));
  170. }
  171. else
  172. {
  173. uploadFile(matImage, nFaceCount, fScore, bRealness);
  174. }
  175. }
  176. }
  177. }
  178. else
  179. {
  180. Sleep(100);
  181. }
  182. }
  183. }
  184. void CInprogressFace::uploadFile(cv::Mat faceMat, int nFaceCount, float fScore, int nRealness)
  185. {
  186. QString sFileName = QString("temp/photo/%1.png").arg(CCommonTools::getUuid());
  187. QImage imgCompare = CCommonTools::Mat2QImage(faceMat);
  188. imgCompare.save(sFileName, "PNG");
  189. CHttpRequestPackage hrp;
  190. hrp.sUri = "/api/ecs_oe_student/client/exam/process/upload/sign";
  191. hrp.nRequestType = RequestType::rtClientExamProcessUploadSign;
  192. hrp.sParamList.push_back(QString("fileSuffix,%1").arg(".png"));
  193. hrp.sParamList.push_back(QString("fileMd5,%1").arg(CCommonTools::fileMd5(sFileName)));
  194. hrp.sCommonStr = QString("%1,%2,%3,%4").arg(__FILE__).arg(nFaceCount).arg(fScore).arg(nRealness);
  195. hrp.sCommonStr1 = sFileName;
  196. hrp.eParamType = HttpParamType::hptBody;
  197. g_httpBllPtr->post(hrp);
  198. }
  199. //文件上传
  200. void CInprogressFace::onClientExamProcessUploadSign(CClientExamProcessUploadSign processUpload)
  201. {
  202. QStringList list = processUpload.sCommonStr.split(",");
  203. if(list.count() == 4)
  204. {
  205. QString sFile = list[0];
  206. int nFaceCount = list[1].toInt();
  207. float fScore = list[2].toFloat();
  208. int nRealness = list[3].toInt();
  209. if(__FILE__ == sFile)
  210. {
  211. if (processUpload.nCode == 200)
  212. {
  213. CHttpRequestPackage hrp;
  214. hrp.sUri = processUpload.sFormUrl;
  215. hrp.nRequestType = RequestType::rtUploadFileToAliyun;
  216. hrp.sCommonStr = QString("%1,%2,%3,%4").arg(__FILE__).arg(nFaceCount).arg(fScore).arg(nRealness);;
  217. hrp.sCommonStr1 = processUpload.sAccessUrl;
  218. hrp.sParamList.push_back(QString("OSSAccessKeyId,%1").arg(processUpload.sOssAcessKeyId));
  219. hrp.sParamList.push_back(QString("Signature,%1").arg(processUpload.sSignature));
  220. hrp.sParamList.push_back(QString("key,%1").arg(processUpload.sKey));
  221. hrp.sParamList.push_back(QString("policy,%1").arg(processUpload.sPolicy));
  222. hrp.sParamList.push_back(QString("success_action_status,%1").arg(200));
  223. hrp.sParamList.push_back(QString("formdataFileType,file,%1").arg(processUpload.sFilePath));
  224. hrp.bNoHostPrefix = true;
  225. hrp.eParamType = HttpParamType::hptFormdata;
  226. g_httpBllPtr->post(hrp);
  227. }
  228. else
  229. {
  230. }
  231. }
  232. }
  233. }
  234. void CInprogressFace::onUploadFileToAliyun(CUploadFileToAliyun uploadFileToAliyun)
  235. {
  236. QStringList list = uploadFileToAliyun.sCommonStr.split(",");
  237. if(list.count() == 4)
  238. {
  239. QString sFile = list[0];
  240. int nFaceCount = list[1].toInt();
  241. float fScore = list[2].toFloat();
  242. int nRealness = list[3].toInt();
  243. if(__FILE__ == sFile)
  244. {
  245. if (uploadFileToAliyun.nCode == 200)
  246. {
  247. CHttpRequestPackage hrp;
  248. hrp.sUri = "/api/ecs_oe_student/client/exam/process/saveFaceCaptureResult";
  249. hrp.nRequestType = RequestType::rtSaveFaceCaptureResult;
  250. Json::Value jBody = Json::Value::null;
  251. jBody["examRecordDataId"] = g_appInfoPtr->m_oExamInfo.nExamRecordDataId;
  252. jBody["faceCompareResult"] = fScore;
  253. jBody["facelivenessResult"] = nRealness;
  254. jBody["fileUrl"] = uploadFileToAliyun.sFileUrl.toStdString();
  255. jBody["pass"] = (fScore * 100 > g_appInfoPtr->m_oExamInfo.nFaceThreshold) ? true : false;
  256. jBody["stranger"] = nFaceCount > 1;
  257. jBody["hasVirtualCamera"] = m_bHasVirtualCamera;
  258. jBody["cameraInfos"] = m_sCameraInfo.toStdString();
  259. hrp.sParamList.push_back(QString("CustomBody,%1").arg(jBody.toStyledString().c_str()));
  260. hrp.eParamType = HttpParamType::hptCustomBody;
  261. myServerLog() << jBody.toStyledString().c_str();
  262. g_httpBllPtr->post(hrp);
  263. }
  264. else
  265. {
  266. }
  267. }
  268. }
  269. }
  270. //保存人脸抓拍比对验证结果
  271. void CInprogressFace::onSaveFaceCaptureResult(CBaseResponsePackage res)
  272. {
  273. if(res.nCode == 200)
  274. {
  275. }
  276. else
  277. {
  278. }
  279. }