diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/device/face/FaceRecogProcess.cpp b/device/face/FaceRecogProcess.cpp index 0fcd9d9..d83cdeb 100644 --- a/device/face/FaceRecogProcess.cpp +++ b/device/face/FaceRecogProcess.cpp @@ -101,7 +101,7 @@ } // 找到人脸则开始一次识别 - if (CasicFaceRecState::getInstance().recoginzeId == "0") + if (CasicFaceRecState::getInstance().recoginzeId == "0" || CasicFaceRecState::getInstance().recoginzeId == "") { CasicFaceRecState::getInstance().initRecognize(); } @@ -172,8 +172,7 @@ // 发送信号, 在主界面上显示 emit matchSuccess(ffMap.value("person_id").toString(), 1); -// this->afterRecogAction(ffMap.value("person_id").toString()); - this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 + this->afterRecogAction(); return ; } } @@ -181,21 +180,9 @@ this->addOneTryCount(); } -void FaceRecogProcess::afterRecogAction(QString personId) +void FaceRecogProcess::afterRecogAction() { ProMemory::getInstance().clearFaceQueue(); // 清理人脸数据栈 - - LOG(DEBUG) << QString("[FaceDetectRecogProcess] 识别成功 [%1]").arg(CasicFaceRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "1"); - record.insert("debug_info", CasicFaceRecState::getInstance().toString()); - recDao.save(record); - - + this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 } diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/device/face/FaceRecogProcess.cpp b/device/face/FaceRecogProcess.cpp index 0fcd9d9..d83cdeb 100644 --- a/device/face/FaceRecogProcess.cpp +++ b/device/face/FaceRecogProcess.cpp @@ -101,7 +101,7 @@ } // 找到人脸则开始一次识别 - if (CasicFaceRecState::getInstance().recoginzeId == "0") + if (CasicFaceRecState::getInstance().recoginzeId == "0" || CasicFaceRecState::getInstance().recoginzeId == "") { CasicFaceRecState::getInstance().initRecognize(); } @@ -172,8 +172,7 @@ // 发送信号, 在主界面上显示 emit matchSuccess(ffMap.value("person_id").toString(), 1); -// this->afterRecogAction(ffMap.value("person_id").toString()); - this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 + this->afterRecogAction(); return ; } } @@ -181,21 +180,9 @@ this->addOneTryCount(); } -void FaceRecogProcess::afterRecogAction(QString personId) +void FaceRecogProcess::afterRecogAction() { ProMemory::getInstance().clearFaceQueue(); // 清理人脸数据栈 - - LOG(DEBUG) << QString("[FaceDetectRecogProcess] 识别成功 [%1]").arg(CasicFaceRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "1"); - record.insert("debug_info", CasicFaceRecState::getInstance().toString()); - recDao.save(record); - - + this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 } diff --git a/device/face/FaceRecogProcess.h b/device/face/FaceRecogProcess.h index c551e23..6ad8ced 100644 --- a/device/face/FaceRecogProcess.h +++ b/device/face/FaceRecogProcess.h @@ -32,7 +32,7 @@ //不能直接调用, 通过start()间接调用 void run(); void compareFaceInCollection(); - void afterRecogAction(QString personId); + void afterRecogAction(); volatile bool working; volatile bool exit; diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/device/face/FaceRecogProcess.cpp b/device/face/FaceRecogProcess.cpp index 0fcd9d9..d83cdeb 100644 --- a/device/face/FaceRecogProcess.cpp +++ b/device/face/FaceRecogProcess.cpp @@ -101,7 +101,7 @@ } // 找到人脸则开始一次识别 - if (CasicFaceRecState::getInstance().recoginzeId == "0") + if (CasicFaceRecState::getInstance().recoginzeId == "0" || CasicFaceRecState::getInstance().recoginzeId == "") { CasicFaceRecState::getInstance().initRecognize(); } @@ -172,8 +172,7 @@ // 发送信号, 在主界面上显示 emit matchSuccess(ffMap.value("person_id").toString(), 1); -// this->afterRecogAction(ffMap.value("person_id").toString()); - this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 + this->afterRecogAction(); return ; } } @@ -181,21 +180,9 @@ this->addOneTryCount(); } -void FaceRecogProcess::afterRecogAction(QString personId) +void FaceRecogProcess::afterRecogAction() { ProMemory::getInstance().clearFaceQueue(); // 清理人脸数据栈 - - LOG(DEBUG) << QString("[FaceDetectRecogProcess] 识别成功 [%1]").arg(CasicFaceRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "1"); - record.insert("debug_info", CasicFaceRecState::getInstance().toString()); - recDao.save(record); - - + this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 } diff --git a/device/face/FaceRecogProcess.h b/device/face/FaceRecogProcess.h index c551e23..6ad8ced 100644 --- a/device/face/FaceRecogProcess.h +++ b/device/face/FaceRecogProcess.h @@ -32,7 +32,7 @@ //不能直接调用, 通过start()间接调用 void run(); void compareFaceInCollection(); - void afterRecogAction(QString personId); + void afterRecogAction(); volatile bool working; volatile bool exit; diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index 52c3826..a25eb87 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -39,8 +39,6 @@ continue; } - LOG(DEBUG) << QString("[IrisRecogProcess]虹膜识别线程").toStdString(); - // 图像栈中没有图像则直接返回 if (ProMemory::getInstance().isIrisQueueEmpty() == true) { @@ -50,13 +48,14 @@ } // 识别状态不等于未开始, 表示已经进入识别程序了, 后续不再执行, 等待本次识别过程结束 - if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) - { - LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); +// if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) +// { +// LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); - this->msleep(200); // 200ms后再判断 - continue; - } +// this->msleep(200); // 200ms后再判断 +// continue; +// } + LOG(DEBUG) << QString("[IrisRecogProcess]准备取出虹膜图像[%1]").arg(ProMemory::getInstance().isIrisQueueEmpty()).toStdString(); // 取出虹膜图像栈中的一条数据 CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris(); @@ -78,6 +77,8 @@ continue; } + LOG(DEBUG) << QString("[IrisRecogProcess]找到眼睛调用远程算法进行识别").toStdString(); + // 找到眼睛则开始质量评估和编码 // 调用远程算法进行编码 if (CasicIrisRecState::getInstance().recoginzeId == "0") @@ -134,7 +135,7 @@ CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; emit findMatchedIris(personId, 2); -// this->afterRecogAction(personId); + this->afterRecogAction(); } else if (code.toInt() == -200) { // 匹配失败 @@ -158,28 +159,11 @@ } } -void IrisRecogProcess::afterRecogAction(QString personId) +void IrisRecogProcess::afterRecogAction() { - ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 - this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - LOG(DEBUG) << QString("[IrisRecogProcess] 识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "2"); - record.insert("debug_info", CasicIrisRecState::getInstance().toString()); - recDao.save(record); - - CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; - - // 发送信号, 在主界面上显示 - emit findMatchedIris(personId, 2); + ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 } void IrisRecogProcess::addOneTryCount() @@ -194,7 +178,7 @@ CasicIrisRecState::getInstance().tryCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } @@ -208,7 +192,7 @@ CasicIrisRecState::getInstance().noEyeCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/device/face/FaceRecogProcess.cpp b/device/face/FaceRecogProcess.cpp index 0fcd9d9..d83cdeb 100644 --- a/device/face/FaceRecogProcess.cpp +++ b/device/face/FaceRecogProcess.cpp @@ -101,7 +101,7 @@ } // 找到人脸则开始一次识别 - if (CasicFaceRecState::getInstance().recoginzeId == "0") + if (CasicFaceRecState::getInstance().recoginzeId == "0" || CasicFaceRecState::getInstance().recoginzeId == "") { CasicFaceRecState::getInstance().initRecognize(); } @@ -172,8 +172,7 @@ // 发送信号, 在主界面上显示 emit matchSuccess(ffMap.value("person_id").toString(), 1); -// this->afterRecogAction(ffMap.value("person_id").toString()); - this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 + this->afterRecogAction(); return ; } } @@ -181,21 +180,9 @@ this->addOneTryCount(); } -void FaceRecogProcess::afterRecogAction(QString personId) +void FaceRecogProcess::afterRecogAction() { ProMemory::getInstance().clearFaceQueue(); // 清理人脸数据栈 - - LOG(DEBUG) << QString("[FaceDetectRecogProcess] 识别成功 [%1]").arg(CasicFaceRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "1"); - record.insert("debug_info", CasicFaceRecState::getInstance().toString()); - recDao.save(record); - - + this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 } diff --git a/device/face/FaceRecogProcess.h b/device/face/FaceRecogProcess.h index c551e23..6ad8ced 100644 --- a/device/face/FaceRecogProcess.h +++ b/device/face/FaceRecogProcess.h @@ -32,7 +32,7 @@ //不能直接调用, 通过start()间接调用 void run(); void compareFaceInCollection(); - void afterRecogAction(QString personId); + void afterRecogAction(); volatile bool working; volatile bool exit; diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index 52c3826..a25eb87 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -39,8 +39,6 @@ continue; } - LOG(DEBUG) << QString("[IrisRecogProcess]虹膜识别线程").toStdString(); - // 图像栈中没有图像则直接返回 if (ProMemory::getInstance().isIrisQueueEmpty() == true) { @@ -50,13 +48,14 @@ } // 识别状态不等于未开始, 表示已经进入识别程序了, 后续不再执行, 等待本次识别过程结束 - if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) - { - LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); +// if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) +// { +// LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); - this->msleep(200); // 200ms后再判断 - continue; - } +// this->msleep(200); // 200ms后再判断 +// continue; +// } + LOG(DEBUG) << QString("[IrisRecogProcess]准备取出虹膜图像[%1]").arg(ProMemory::getInstance().isIrisQueueEmpty()).toStdString(); // 取出虹膜图像栈中的一条数据 CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris(); @@ -78,6 +77,8 @@ continue; } + LOG(DEBUG) << QString("[IrisRecogProcess]找到眼睛调用远程算法进行识别").toStdString(); + // 找到眼睛则开始质量评估和编码 // 调用远程算法进行编码 if (CasicIrisRecState::getInstance().recoginzeId == "0") @@ -134,7 +135,7 @@ CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; emit findMatchedIris(personId, 2); -// this->afterRecogAction(personId); + this->afterRecogAction(); } else if (code.toInt() == -200) { // 匹配失败 @@ -158,28 +159,11 @@ } } -void IrisRecogProcess::afterRecogAction(QString personId) +void IrisRecogProcess::afterRecogAction() { - ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 - this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - LOG(DEBUG) << QString("[IrisRecogProcess] 识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "2"); - record.insert("debug_info", CasicIrisRecState::getInstance().toString()); - recDao.save(record); - - CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; - - // 发送信号, 在主界面上显示 - emit findMatchedIris(personId, 2); + ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 } void IrisRecogProcess::addOneTryCount() @@ -194,7 +178,7 @@ CasicIrisRecState::getInstance().tryCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } @@ -208,7 +192,7 @@ CasicIrisRecState::getInstance().noEyeCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } diff --git a/device/iris/IrisRecogProcess.h b/device/iris/IrisRecogProcess.h index e256614..b50cdd5 100644 --- a/device/iris/IrisRecogProcess.h +++ b/device/iris/IrisRecogProcess.h @@ -34,7 +34,7 @@ private: SocketClientUtil * clientUtil; - void afterRecogAction(QString personId); + void afterRecogAction(); signals: void sendDataToExract(QByteArray data); diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/device/face/FaceRecogProcess.cpp b/device/face/FaceRecogProcess.cpp index 0fcd9d9..d83cdeb 100644 --- a/device/face/FaceRecogProcess.cpp +++ b/device/face/FaceRecogProcess.cpp @@ -101,7 +101,7 @@ } // 找到人脸则开始一次识别 - if (CasicFaceRecState::getInstance().recoginzeId == "0") + if (CasicFaceRecState::getInstance().recoginzeId == "0" || CasicFaceRecState::getInstance().recoginzeId == "") { CasicFaceRecState::getInstance().initRecognize(); } @@ -172,8 +172,7 @@ // 发送信号, 在主界面上显示 emit matchSuccess(ffMap.value("person_id").toString(), 1); -// this->afterRecogAction(ffMap.value("person_id").toString()); - this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 + this->afterRecogAction(); return ; } } @@ -181,21 +180,9 @@ this->addOneTryCount(); } -void FaceRecogProcess::afterRecogAction(QString personId) +void FaceRecogProcess::afterRecogAction() { ProMemory::getInstance().clearFaceQueue(); // 清理人脸数据栈 - - LOG(DEBUG) << QString("[FaceDetectRecogProcess] 识别成功 [%1]").arg(CasicFaceRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "1"); - record.insert("debug_info", CasicFaceRecState::getInstance().toString()); - recDao.save(record); - - + this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 } diff --git a/device/face/FaceRecogProcess.h b/device/face/FaceRecogProcess.h index c551e23..6ad8ced 100644 --- a/device/face/FaceRecogProcess.h +++ b/device/face/FaceRecogProcess.h @@ -32,7 +32,7 @@ //不能直接调用, 通过start()间接调用 void run(); void compareFaceInCollection(); - void afterRecogAction(QString personId); + void afterRecogAction(); volatile bool working; volatile bool exit; diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index 52c3826..a25eb87 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -39,8 +39,6 @@ continue; } - LOG(DEBUG) << QString("[IrisRecogProcess]虹膜识别线程").toStdString(); - // 图像栈中没有图像则直接返回 if (ProMemory::getInstance().isIrisQueueEmpty() == true) { @@ -50,13 +48,14 @@ } // 识别状态不等于未开始, 表示已经进入识别程序了, 后续不再执行, 等待本次识别过程结束 - if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) - { - LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); +// if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) +// { +// LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); - this->msleep(200); // 200ms后再判断 - continue; - } +// this->msleep(200); // 200ms后再判断 +// continue; +// } + LOG(DEBUG) << QString("[IrisRecogProcess]准备取出虹膜图像[%1]").arg(ProMemory::getInstance().isIrisQueueEmpty()).toStdString(); // 取出虹膜图像栈中的一条数据 CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris(); @@ -78,6 +77,8 @@ continue; } + LOG(DEBUG) << QString("[IrisRecogProcess]找到眼睛调用远程算法进行识别").toStdString(); + // 找到眼睛则开始质量评估和编码 // 调用远程算法进行编码 if (CasicIrisRecState::getInstance().recoginzeId == "0") @@ -134,7 +135,7 @@ CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; emit findMatchedIris(personId, 2); -// this->afterRecogAction(personId); + this->afterRecogAction(); } else if (code.toInt() == -200) { // 匹配失败 @@ -158,28 +159,11 @@ } } -void IrisRecogProcess::afterRecogAction(QString personId) +void IrisRecogProcess::afterRecogAction() { - ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 - this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - LOG(DEBUG) << QString("[IrisRecogProcess] 识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "2"); - record.insert("debug_info", CasicIrisRecState::getInstance().toString()); - recDao.save(record); - - CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; - - // 发送信号, 在主界面上显示 - emit findMatchedIris(personId, 2); + ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 } void IrisRecogProcess::addOneTryCount() @@ -194,7 +178,7 @@ CasicIrisRecState::getInstance().tryCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } @@ -208,7 +192,7 @@ CasicIrisRecState::getInstance().noEyeCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } diff --git a/device/iris/IrisRecogProcess.h b/device/iris/IrisRecogProcess.h index e256614..b50cdd5 100644 --- a/device/iris/IrisRecogProcess.h +++ b/device/iris/IrisRecogProcess.h @@ -34,7 +34,7 @@ private: SocketClientUtil * clientUtil; - void afterRecogAction(QString personId); + void afterRecogAction(); signals: void sendDataToExract(QByteArray data); diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp index ce43d9f..f10b016 100644 --- a/utils/SettingConfig.cpp +++ b/utils/SettingConfig.cpp @@ -37,6 +37,8 @@ MAX_WORK_FACE_POSX = getProperty("work", "maxFacePosX").toInt(); MIN_WORK_FACE_POSY = getProperty("work", "minFacePosY").toInt(); MAX_WORK_FACE_POSY = getProperty("work", "maxFacePosY").toInt(); + FACE_TOO_CLOSE_SIZE = getProperty("work", "faceCloseSize").toInt(); + FACE_TOO_FAR_SIZE = getProperty("work", "faceFarSize").toInt(); PORT_NAME = getProperty("com", "motoPortName").toString(); diff --git a/RecognizeResultForm.cpp b/RecognizeResultForm.cpp index b340be9..cb61cc8 100644 --- a/RecognizeResultForm.cpp +++ b/RecognizeResultForm.cpp @@ -35,13 +35,13 @@ case 2: // 虹膜识别 ProMemory::getInstance().clearIrisQueue(); -// ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().camPosCtrl->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); break; case 3: // 双认证 先打开人脸识别 成功后再进行虹膜识别 ProMemory::getInstance().clearFaceQueue(); + ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); break; case 4: @@ -50,7 +50,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(true); ProMemory::getInstance().irisRecogPro->setWorking(true); - ProMemory::getInstance().irisCam->startCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(true); break; } @@ -91,7 +91,7 @@ ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearFaceQueue(); @@ -170,17 +170,15 @@ recDao.save(record); showRecognizeResult(personId); + break; } case 2: { // 仅虹膜识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - ProMemory::getInstance().clearIrisQueue(); - - // 停止控制电机和提示 ProMemory::getInstance().camPosCtrl->setWorking(false); + ProMemory::getInstance().clearIrisQueue(); LOG(DEBUG) << QString("[RecognizeResultForm] 虹膜识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); @@ -200,7 +198,8 @@ { // 任意识别 ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().faceRecogPro->setWorking(false); @@ -242,12 +241,13 @@ // 2. 虹膜识别开始 ProMemory::getInstance().clearIrisQueue(); ProMemory::getInstance().camPosCtrl->setWorking(true); + ProMemory::getInstance().irisRecogPro->setWorking(true); } else if (faceOrIris == 2) { this->personIdByIris = personId; + ProMemory::getInstance().camPosCtrl->setWorking(false); ProMemory::getInstance().irisRecogPro->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); if (personIdByFace.isEmpty() || personIdByIris.isEmpty()) @@ -276,6 +276,10 @@ } } } + + // 识别结束 + CasicFaceRecState::getInstance().recoginzeId = "0"; + CasicIrisRecState::getInstance().recoginzeId = "0"; } void RecognizeResultForm::updateRecogTips(QString tipsText) diff --git a/casic/face/CasicFaceInterface.cpp b/casic/face/CasicFaceInterface.cpp index 3cb2118..33423ee 100644 --- a/casic/face/CasicFaceInterface.cpp +++ b/casic/face/CasicFaceInterface.cpp @@ -427,6 +427,36 @@ return rect.at(0); } +cv::Rect casic::face::CasicFaceInterface::eyeGlassesDetectByCVCascade(cv::Mat frame) +{ + // 构建openCV自带的眼睛分类器 + if (this->eyeGlassesCascade == nullptr) + { + this->eyeGlassesCascade = new cv::CascadeClassifier(); + this->eyeGlassesCascade->load(cvEyeGlassesCascadeName); + } + + QElapsedTimer timer; + timer.start(); + + std::vector rect; + cv::Size minRectSize(minEyeSize, minEyeSize); + cv::Size maxRectSize(maxEyeSize, maxEyeSize); + + // ★分类器对象调用 + eyeGlassesCascade->detectMultiScale(frame, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minRectSize, maxRectSize); + + if (rect.size() == 0) + { + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][0]").arg(timer.elapsed()).toStdString(); + return cv::Rect(0, 0, 0, 0); + } + + LOG(DEBUG) << QString("眼睛分类检测算法[戴眼镜][tm: %1 ms][%2, %3]").arg(timer.elapsed()).arg(rect.at(0).width).arg(rect.at(0).height).toStdString(); + + return rect.at(0); +} + std::vector casic::face::CasicFaceInterface::eyeDetectByCVCascade(cv::Mat frame, int minEyeSize) { // 构建openCV自带的眼睛分类器 diff --git a/casic/face/CasicFaceInterface.h b/casic/face/CasicFaceInterface.h index 1753bd1..5a2f32f 100644 --- a/casic/face/CasicFaceInterface.h +++ b/casic/face/CasicFaceInterface.h @@ -52,6 +52,7 @@ cv::Rect faceDetectByCVCascade(cv::Mat frame, int minFaceSize); cv::Rect eyeDetectByCVCascade(cv::Mat frame); + cv::Rect eyeGlassesDetectByCVCascade(cv::Mat frame); std::vector eyeDetectByCVCascade(cv::Mat frame, int minEyeSize); void setMinFaceSize(int minFaceSize); void setMinEyeSize(int minEyeSize); @@ -66,10 +67,11 @@ std::string cvFaceCascadeName = "./model/haarcascade_frontalface_default.xml"; std::string cvEyeCascadeName = "./model/haarcascade_eye.xml"; + std::string cvEyeGlassesCascadeName = "./model/haarcascade_eye_tree_eyeglasses.xml"; int minFaceSize = 320; int maxFaceSize = 720; - int minEyeSize = 100; - int maxEyeSize = 300; + int minEyeSize = 50; + int maxEyeSize = 400; std::string detectorModelPath = "./model/face_detector.csta"; std::string markPts5ModelPath = "./model/face_landmarker_pts5.csta"; @@ -86,6 +88,7 @@ cv::CascadeClassifier * cascade; cv::CascadeClassifier * eyeCascade; + cv::CascadeClassifier * eyeGlassesCascade; }; } } diff --git a/conf/config.ini b/conf/config.ini index 79045a6..9423149 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -49,6 +49,10 @@ minFacePosY=180 #人脸范围最大纵坐标 maxFacePosY=540 +#人脸太近阈值 +faceCloseSize=360 +#人脸太远阈值 +faceFarSize=480 [camera] #人脸摄像头的编号 diff --git a/device/CameraPositionController.cpp b/device/CameraPositionController.cpp index 577c9ad..1b15c13 100644 --- a/device/CameraPositionController.cpp +++ b/device/CameraPositionController.cpp @@ -33,59 +33,42 @@ // 取一幅图像 cv::Mat rawFrame = ProMemory::getInstance().faceCam->takeOneRawFrame(); -/* - // 分类器找眼睛 - cv::Rect eyeRect = casic::face::CasicFaceInterface::getInstance().eyeDetectByCVCascade(rawFrame); - if (eyeRect.width != 0) - { - // 眼睛的位置 - int eyeCenter = eyeRect.y + eyeRect.height / 2; - LOG(DEBUG) << eyeCenter << " " << abs(eyeCenter - 300) << " " << 100 * abs(eyeCenter - 300) / 20 + 200; - - if (eyeCenter < 250 || eyeCenter > 350) - { -// ProMemory::getInstance().moto->autoPosition(eyeCenter); - emit motoControl(eyeCenter); - -// this->msleep(100 * abs(eyeCenter - 300) / 20 + 200); // 200ms后再判断 - } - } - */ // 分类器找脸 cv::Rect faceRect = casic::face::CasicFaceInterface::getInstance().faceDetectByCVCascade(rawFrame, SettingConfig::getInstance().MIN_WORK_FACE_SIZE); - QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) - .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); if (faceRect.width != 0) { - // 通过人脸的大小判断距离,提示靠近或者远离 - if (faceRect.width < 360) - { - emit updateTips(QString("距离太远,请靠近 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#9F1919"); - } else if (faceRect.width >= 360 && faceRect.width <= 480) - { - emit updateTips(QString("正在识别,请保持 %1").arg(faceRect.width)); - emit updateTipsBackgroundColor("#248A53"); +// QString facePos = QString("%1 * %2, (%3, %4), (%5, %6)").arg(faceRect.width).arg(faceRect.height) +// .arg(faceRect.x).arg(faceRect.y).arg(faceRect.x + faceRect.width).arg(faceRect.y + faceRect.height); - // 位置合适 开始识别 -// ProMemory::getInstance().irisRecogPro->setWorking(true); -// ProMemory::getInstance().irisCam->startCapture(); -// this->setWorking(false); - } else if (faceRect.width > 480) + // 通过人脸的大小判断距离,提示靠近或者远离 + if (faceRect.width < SettingConfig::getInstance().FACE_TOO_CLOSE_SIZE) { - emit updateTips(QString("距离太近,请远离 %1").arg(faceRect.width)); + emit updateTips(QString("距离太远,请靠近")); emit updateTipsBackgroundColor("#9F1919"); } - } + else if (faceRect.width > SettingConfig::getInstance().FACE_TOO_FAR_SIZE) + { + emit updateTips(QString("距离太近,请远离")); + emit updateTipsBackgroundColor("#9F1919"); + } + else + { + emit updateTips(QString("正在识别,请看向镜头")); + emit updateTipsBackgroundColor("#248A53"); - this->msleep(500); + int eyeTop = faceRect.y + faceRect.height * 0.35; + int eyeBottom = faceRect.y + faceRect.height * 0.45; + if (eyeTop < 250 || eyeBottom > 350) { + emit motoControl(faceRect.y + faceRect.height * 0.4); + } + + // 位置合适 拍两张虹膜图像进行识别 + ProMemory::getInstance().irisCam->getOneFaceFrm(); + } + } + this->msleep(200); } } - -void CameraPositionController::checkFacePosition() -{ - -} diff --git a/device/CameraPositionController.h b/device/CameraPositionController.h index 9520b14..0b89ce2 100644 --- a/device/CameraPositionController.h +++ b/device/CameraPositionController.h @@ -27,9 +27,6 @@ volatile bool working; volatile bool exit; -public slots: - void checkFacePosition(); - signals: void updateTips(QString tipsText); void updateTipsBackgroundColor(QString bgColor); diff --git a/device/IrisCameraCapEventHandler.cpp b/device/IrisCameraCapEventHandler.cpp index 151de09..d33ade9 100644 --- a/device/IrisCameraCapEventHandler.cpp +++ b/device/IrisCameraCapEventHandler.cpp @@ -44,6 +44,8 @@ irisInfo.matData = irisMat; ProMemory::getInstance().pushCasicIris(irisInfo); + + cv::imwrite(QString("D:\\irisLogs\\iristest-%1.bmp").arg(irisInfo.leftOrRight).toStdString(), irisMat); } else if (ProMemory::getInstance().widgeFrame == CasicBioRecConst::ADD_PERSON_CAPTURE_IRIS) { // 相机拍摄下的图像1280*960, 直接用于算法判断 diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index ed9f890..0b81012 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -79,6 +79,13 @@ IRIS_CAMERA_SWITCHER++; } +void IrisCameraController::getLeftAndRightEyeFrame() +{ + leftFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); + QThread::msleep(100); + rightFeaturePtr->GetCommandFeature("TriggerSoftware")->Execute(); +} + void IrisCameraController::OpenDevice() { for(size_t i = 0; i < this->irisCamList.size(); i++) diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 744a68d..e7c838e 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -22,6 +22,8 @@ void startCapture(); void stopCapture(); + void getLeftAndRightEyeFrame(); + IrisCameraCapEventHandler * leftHandler; IrisCameraCapEventHandler * rightHandler; diff --git a/device/MotoController.cpp b/device/MotoController.cpp index 15cb5f0..ca61c02 100644 --- a/device/MotoController.cpp +++ b/device/MotoController.cpp @@ -118,7 +118,7 @@ int center = 300; int dir = eyeCenter > center ? -1 : 1; int step = abs(eyeCenter - center) / 20; - for (int i = 0; i < step; i++) + for (int i = 0; i <= step; i++) { QByteArray data = this->encodeProtocol(QString::number(20 * dir)); this->sendDataAutoEnding(data); diff --git a/device/device.pri b/device/device.pri index 2a1b90b..1bace7a 100644 --- a/device/device.pri +++ b/device/device.pri @@ -1,12 +1,10 @@ -HEADERS += $$PWD/FaceCameraController.h \ - $$PWD/CameraPositionController.h +HEADERS += $$PWD/FaceCameraController.h HEADERS += $$PWD/face/FaceRecogProcess.h HEADERS += $$PWD/face/FaceRegistProcess.h HEADERS += $$PWD/face/CasicFaceRecState.h -SOURCES += $$PWD/FaceCameraController.cpp \ - $$PWD/CameraPositionController.cpp +SOURCES += $$PWD/FaceCameraController.cpp SOURCES += $$PWD/face/FaceRecogProcess.cpp SOURCES += $$PWD/face/FaceRegistProcess.cpp SOURCES += $$PWD/face/CasicFaceRecState.cpp @@ -25,5 +23,5 @@ HEADERS += $$PWD/MotoController.h SOURCES += $$PWD/MotoController.cpp -HEADERS += -SOURCES += +HEADERS += $$PWD/CameraPositionController.h +SOURCES += $$PWD/CameraPositionController.cpp diff --git a/device/face/FaceRecogProcess.cpp b/device/face/FaceRecogProcess.cpp index 0fcd9d9..d83cdeb 100644 --- a/device/face/FaceRecogProcess.cpp +++ b/device/face/FaceRecogProcess.cpp @@ -101,7 +101,7 @@ } // 找到人脸则开始一次识别 - if (CasicFaceRecState::getInstance().recoginzeId == "0") + if (CasicFaceRecState::getInstance().recoginzeId == "0" || CasicFaceRecState::getInstance().recoginzeId == "") { CasicFaceRecState::getInstance().initRecognize(); } @@ -172,8 +172,7 @@ // 发送信号, 在主界面上显示 emit matchSuccess(ffMap.value("person_id").toString(), 1); -// this->afterRecogAction(ffMap.value("person_id").toString()); - this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 + this->afterRecogAction(); return ; } } @@ -181,21 +180,9 @@ this->addOneTryCount(); } -void FaceRecogProcess::afterRecogAction(QString personId) +void FaceRecogProcess::afterRecogAction() { ProMemory::getInstance().clearFaceQueue(); // 清理人脸数据栈 - - LOG(DEBUG) << QString("[FaceDetectRecogProcess] 识别成功 [%1]").arg(CasicFaceRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "1"); - record.insert("debug_info", CasicFaceRecState::getInstance().toString()); - recDao.save(record); - - + this->setWorking(false); // 找到匹配的人脸之后停止识别线程工作 } diff --git a/device/face/FaceRecogProcess.h b/device/face/FaceRecogProcess.h index c551e23..6ad8ced 100644 --- a/device/face/FaceRecogProcess.h +++ b/device/face/FaceRecogProcess.h @@ -32,7 +32,7 @@ //不能直接调用, 通过start()间接调用 void run(); void compareFaceInCollection(); - void afterRecogAction(QString personId); + void afterRecogAction(); volatile bool working; volatile bool exit; diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index 52c3826..a25eb87 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -39,8 +39,6 @@ continue; } - LOG(DEBUG) << QString("[IrisRecogProcess]虹膜识别线程").toStdString(); - // 图像栈中没有图像则直接返回 if (ProMemory::getInstance().isIrisQueueEmpty() == true) { @@ -50,13 +48,14 @@ } // 识别状态不等于未开始, 表示已经进入识别程序了, 后续不再执行, 等待本次识别过程结束 - if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) - { - LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); +// if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) +// { +// LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); - this->msleep(200); // 200ms后再判断 - continue; - } +// this->msleep(200); // 200ms后再判断 +// continue; +// } + LOG(DEBUG) << QString("[IrisRecogProcess]准备取出虹膜图像[%1]").arg(ProMemory::getInstance().isIrisQueueEmpty()).toStdString(); // 取出虹膜图像栈中的一条数据 CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris(); @@ -78,6 +77,8 @@ continue; } + LOG(DEBUG) << QString("[IrisRecogProcess]找到眼睛调用远程算法进行识别").toStdString(); + // 找到眼睛则开始质量评估和编码 // 调用远程算法进行编码 if (CasicIrisRecState::getInstance().recoginzeId == "0") @@ -134,7 +135,7 @@ CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; emit findMatchedIris(personId, 2); -// this->afterRecogAction(personId); + this->afterRecogAction(); } else if (code.toInt() == -200) { // 匹配失败 @@ -158,28 +159,11 @@ } } -void IrisRecogProcess::afterRecogAction(QString personId) +void IrisRecogProcess::afterRecogAction() { - ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 - this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); - LOG(DEBUG) << QString("[IrisRecogProcess] 识别成功 [%1]").arg(CasicIrisRecState::getInstance().toString()).toStdString(); - - // 识别记录存入数据库 - RecognitionRecordDao recDao; - QVariantMap record; - record.insert("person_id", personId); - record.insert("date_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")); - record.insert("type", "2"); - record.insert("debug_info", CasicIrisRecState::getInstance().toString()); - recDao.save(record); - - CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; - - // 发送信号, 在主界面上显示 - emit findMatchedIris(personId, 2); + ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 } void IrisRecogProcess::addOneTryCount() @@ -194,7 +178,7 @@ CasicIrisRecState::getInstance().tryCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } @@ -208,7 +192,7 @@ CasicIrisRecState::getInstance().noEyeCount = 0; this->setWorking(false); - ProMemory::getInstance().irisCam->stopCapture(); +// ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } diff --git a/device/iris/IrisRecogProcess.h b/device/iris/IrisRecogProcess.h index e256614..b50cdd5 100644 --- a/device/iris/IrisRecogProcess.h +++ b/device/iris/IrisRecogProcess.h @@ -34,7 +34,7 @@ private: SocketClientUtil * clientUtil; - void afterRecogAction(QString personId); + void afterRecogAction(); signals: void sendDataToExract(QByteArray data); diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp index ce43d9f..f10b016 100644 --- a/utils/SettingConfig.cpp +++ b/utils/SettingConfig.cpp @@ -37,6 +37,8 @@ MAX_WORK_FACE_POSX = getProperty("work", "maxFacePosX").toInt(); MIN_WORK_FACE_POSY = getProperty("work", "minFacePosY").toInt(); MAX_WORK_FACE_POSY = getProperty("work", "maxFacePosY").toInt(); + FACE_TOO_CLOSE_SIZE = getProperty("work", "faceCloseSize").toInt(); + FACE_TOO_FAR_SIZE = getProperty("work", "faceFarSize").toInt(); PORT_NAME = getProperty("com", "motoPortName").toString(); diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h index c05b2ec..89541ca 100644 --- a/utils/SettingConfig.h +++ b/utils/SettingConfig.h @@ -57,6 +57,8 @@ int MAX_WORK_FACE_POSX; int MIN_WORK_FACE_POSY; int MAX_WORK_FACE_POSY; + int FACE_TOO_CLOSE_SIZE; + int FACE_TOO_FAR_SIZE; QString PORT_NAME;