diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 67cbe2f..83eb12a 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -21,6 +21,8 @@ void startCapture(); void stopCapture(); + void SetCameraFrameRate(float rate); + CAcquisitionThread * m_pobjAcqThread; GX_DEV_HANDLE m_hDevice; ///< Device Handle uint32_t m_ui32DeviceNum; ///< Device number enumerated diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 67cbe2f..83eb12a 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -21,6 +21,8 @@ void startCapture(); void stopCapture(); + void SetCameraFrameRate(float rate); + CAcquisitionThread * m_pobjAcqThread; GX_DEV_HANDLE m_hDevice; ///< Device Handle uint32_t m_ui32DeviceNum; ///< Device number enumerated diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index e4c8a02..54d38b5 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -73,7 +73,8 @@ int findEyeLast = timer.elapsed(); qDebug() << QString("[IrisRecogProcess] 找眼及裁剪[%1 ms]").arg(findEyeLast); -// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/145333.552.bmp", 0); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); // irisInfo.hasEye = true; // 4.1 没有找到眼睛则返回 @@ -117,10 +118,21 @@ // 缩放到320 * 240 cv::resize(segMat, segMat, cv::Size(SettingConfig::getInstance().IRIS_WIDTH * 0.5, SettingConfig::getInstance().IRIS_HEIGHT * 0.5)); -/* - std::string filename = QString("%1/%2/%3-seg.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); - cv::imwrite(filename, segMat); -*/ + + // save segMat for debug + std::string segFilename; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + segFilename = QString("%1/%2/%3-seg.bmp").arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH).arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); + cv::imwrite(segFilename, segMat); + } + +// QElapsedTimer timer; +// timer.start(); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); +// irisInfo.hasEye = true; +// cv::Mat segMat = cv::imread("/home/casic/code/CasicIrisIdentify/crash-test/113429-seg.bmp"); + int segMatSize = segMat.cols * segMat.rows; QByteArray data((char*)segMat.data, segMatSize * 3); // 三通道 @@ -182,7 +194,7 @@ // 7. 分割后的后处理 编码及提取特征值 timer.restart(); - if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0|| cv::countNonZero(iris) == 0) + if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0 || cv::countNonZero(iris) == 0) { qDebug() << "算法分割图像失败,暂停200ms"; @@ -222,13 +234,16 @@ // 开始匹配 timer.restart(); + float minScore = 1.0f; for (int i = 0; i < ProMemory::getInstance().getIrisFeatures().size(); i++) { CasicIrisFeature feature = ProMemory::getInstance().getIrisFeatures().at(i); float score = casic::iris::CasicIrisInterface::getInstance().calculatePairPoints(feature.irisFeatureCode, irisInfo.irisFeatureCode); // 计算压缩编码的比较值 + if (score < minScore) { + minScore = score; + } -// cv::imwrite(QString("%1/%2/%3-%4.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss.zzz")).arg(score).toStdString(), irisInfo.matData); if (score <= 0.32) { CasicIrisRecState::getInstance().state = CasicIrisRecState::REC_SEARCH_SUCC; CasicIrisRecState::getInstance().matchedId = feature.personId; @@ -245,6 +260,15 @@ CasicIrisRecState::getInstance().matchTmLast = matchLast; CasicIrisRecState::getInstance().recogTimeLast += matchLast; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + QFile::remove(QString::fromStdString(segFilename)); // delete segment file + cv::imwrite(QString("%1/%2/%3-%4.bmp") + .arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH) + .arg(QDate::currentDate().toString("yyyyMMdd")) + .arg(QTime::currentTime().toString("HHmmss.zzz")) + .arg(minScore).toStdString(), irisInfo.matData); + } + if (CasicIrisRecState::getInstance().state == CasicIrisRecState::REC_SEARCH_SUCC) { // 找到匹配结果 afterRecogAction(); diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 67cbe2f..83eb12a 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -21,6 +21,8 @@ void startCapture(); void stopCapture(); + void SetCameraFrameRate(float rate); + CAcquisitionThread * m_pobjAcqThread; GX_DEV_HANDLE m_hDevice; ///< Device Handle uint32_t m_ui32DeviceNum; ///< Device number enumerated diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index e4c8a02..54d38b5 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -73,7 +73,8 @@ int findEyeLast = timer.elapsed(); qDebug() << QString("[IrisRecogProcess] 找眼及裁剪[%1 ms]").arg(findEyeLast); -// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/145333.552.bmp", 0); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); // irisInfo.hasEye = true; // 4.1 没有找到眼睛则返回 @@ -117,10 +118,21 @@ // 缩放到320 * 240 cv::resize(segMat, segMat, cv::Size(SettingConfig::getInstance().IRIS_WIDTH * 0.5, SettingConfig::getInstance().IRIS_HEIGHT * 0.5)); -/* - std::string filename = QString("%1/%2/%3-seg.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); - cv::imwrite(filename, segMat); -*/ + + // save segMat for debug + std::string segFilename; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + segFilename = QString("%1/%2/%3-seg.bmp").arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH).arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); + cv::imwrite(segFilename, segMat); + } + +// QElapsedTimer timer; +// timer.start(); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); +// irisInfo.hasEye = true; +// cv::Mat segMat = cv::imread("/home/casic/code/CasicIrisIdentify/crash-test/113429-seg.bmp"); + int segMatSize = segMat.cols * segMat.rows; QByteArray data((char*)segMat.data, segMatSize * 3); // 三通道 @@ -182,7 +194,7 @@ // 7. 分割后的后处理 编码及提取特征值 timer.restart(); - if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0|| cv::countNonZero(iris) == 0) + if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0 || cv::countNonZero(iris) == 0) { qDebug() << "算法分割图像失败,暂停200ms"; @@ -222,13 +234,16 @@ // 开始匹配 timer.restart(); + float minScore = 1.0f; for (int i = 0; i < ProMemory::getInstance().getIrisFeatures().size(); i++) { CasicIrisFeature feature = ProMemory::getInstance().getIrisFeatures().at(i); float score = casic::iris::CasicIrisInterface::getInstance().calculatePairPoints(feature.irisFeatureCode, irisInfo.irisFeatureCode); // 计算压缩编码的比较值 + if (score < minScore) { + minScore = score; + } -// cv::imwrite(QString("%1/%2/%3-%4.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss.zzz")).arg(score).toStdString(), irisInfo.matData); if (score <= 0.32) { CasicIrisRecState::getInstance().state = CasicIrisRecState::REC_SEARCH_SUCC; CasicIrisRecState::getInstance().matchedId = feature.personId; @@ -245,6 +260,15 @@ CasicIrisRecState::getInstance().matchTmLast = matchLast; CasicIrisRecState::getInstance().recogTimeLast += matchLast; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + QFile::remove(QString::fromStdString(segFilename)); // delete segment file + cv::imwrite(QString("%1/%2/%3-%4.bmp") + .arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH) + .arg(QDate::currentDate().toString("yyyyMMdd")) + .arg(QTime::currentTime().toString("HHmmss.zzz")) + .arg(minScore).toStdString(), irisInfo.matData); + } + if (CasicIrisRecState::getInstance().state == CasicIrisRecState::REC_SEARCH_SUCC) { // 找到匹配结果 afterRecogAction(); diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp index 05c4c68..17abe3e 100644 --- a/utils/SettingConfig.cpp +++ b/utils/SettingConfig.cpp @@ -37,6 +37,8 @@ DEBUG_CAMERA_ROTATE = getProperty("debug", "cameraRotate").toString(); DEBUG_SEGMENT_IP = getProperty("debug", "segmentIp").toString(); + DEBUG_SAVE_IMAGE = getProperty("debug", "saveImage").toBool(); + DEBUG_IMAGE_BASE_PATH = getProperty("debug", "imageBasePath").toString(); } diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 67cbe2f..83eb12a 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -21,6 +21,8 @@ void startCapture(); void stopCapture(); + void SetCameraFrameRate(float rate); + CAcquisitionThread * m_pobjAcqThread; GX_DEV_HANDLE m_hDevice; ///< Device Handle uint32_t m_ui32DeviceNum; ///< Device number enumerated diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index e4c8a02..54d38b5 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -73,7 +73,8 @@ int findEyeLast = timer.elapsed(); qDebug() << QString("[IrisRecogProcess] 找眼及裁剪[%1 ms]").arg(findEyeLast); -// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/145333.552.bmp", 0); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); // irisInfo.hasEye = true; // 4.1 没有找到眼睛则返回 @@ -117,10 +118,21 @@ // 缩放到320 * 240 cv::resize(segMat, segMat, cv::Size(SettingConfig::getInstance().IRIS_WIDTH * 0.5, SettingConfig::getInstance().IRIS_HEIGHT * 0.5)); -/* - std::string filename = QString("%1/%2/%3-seg.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); - cv::imwrite(filename, segMat); -*/ + + // save segMat for debug + std::string segFilename; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + segFilename = QString("%1/%2/%3-seg.bmp").arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH).arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); + cv::imwrite(segFilename, segMat); + } + +// QElapsedTimer timer; +// timer.start(); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); +// irisInfo.hasEye = true; +// cv::Mat segMat = cv::imread("/home/casic/code/CasicIrisIdentify/crash-test/113429-seg.bmp"); + int segMatSize = segMat.cols * segMat.rows; QByteArray data((char*)segMat.data, segMatSize * 3); // 三通道 @@ -182,7 +194,7 @@ // 7. 分割后的后处理 编码及提取特征值 timer.restart(); - if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0|| cv::countNonZero(iris) == 0) + if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0 || cv::countNonZero(iris) == 0) { qDebug() << "算法分割图像失败,暂停200ms"; @@ -222,13 +234,16 @@ // 开始匹配 timer.restart(); + float minScore = 1.0f; for (int i = 0; i < ProMemory::getInstance().getIrisFeatures().size(); i++) { CasicIrisFeature feature = ProMemory::getInstance().getIrisFeatures().at(i); float score = casic::iris::CasicIrisInterface::getInstance().calculatePairPoints(feature.irisFeatureCode, irisInfo.irisFeatureCode); // 计算压缩编码的比较值 + if (score < minScore) { + minScore = score; + } -// cv::imwrite(QString("%1/%2/%3-%4.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss.zzz")).arg(score).toStdString(), irisInfo.matData); if (score <= 0.32) { CasicIrisRecState::getInstance().state = CasicIrisRecState::REC_SEARCH_SUCC; CasicIrisRecState::getInstance().matchedId = feature.personId; @@ -245,6 +260,15 @@ CasicIrisRecState::getInstance().matchTmLast = matchLast; CasicIrisRecState::getInstance().recogTimeLast += matchLast; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + QFile::remove(QString::fromStdString(segFilename)); // delete segment file + cv::imwrite(QString("%1/%2/%3-%4.bmp") + .arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH) + .arg(QDate::currentDate().toString("yyyyMMdd")) + .arg(QTime::currentTime().toString("HHmmss.zzz")) + .arg(minScore).toStdString(), irisInfo.matData); + } + if (CasicIrisRecState::getInstance().state == CasicIrisRecState::REC_SEARCH_SUCC) { // 找到匹配结果 afterRecogAction(); diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp index 05c4c68..17abe3e 100644 --- a/utils/SettingConfig.cpp +++ b/utils/SettingConfig.cpp @@ -37,6 +37,8 @@ DEBUG_CAMERA_ROTATE = getProperty("debug", "cameraRotate").toString(); DEBUG_SEGMENT_IP = getProperty("debug", "segmentIp").toString(); + DEBUG_SAVE_IMAGE = getProperty("debug", "saveImage").toBool(); + DEBUG_IMAGE_BASE_PATH = getProperty("debug", "imageBasePath").toString(); } diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h index c35d6ab..6909e84 100644 --- a/utils/SettingConfig.h +++ b/utils/SettingConfig.h @@ -57,6 +57,8 @@ QString DEBUG_CAMERA_ROTATE; QString DEBUG_SEGMENT_IP; + bool DEBUG_SAVE_IMAGE; + QString DEBUG_IMAGE_BASE_PATH; private: SettingConfig(); diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 67cbe2f..83eb12a 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -21,6 +21,8 @@ void startCapture(); void stopCapture(); + void SetCameraFrameRate(float rate); + CAcquisitionThread * m_pobjAcqThread; GX_DEV_HANDLE m_hDevice; ///< Device Handle uint32_t m_ui32DeviceNum; ///< Device number enumerated diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index e4c8a02..54d38b5 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -73,7 +73,8 @@ int findEyeLast = timer.elapsed(); qDebug() << QString("[IrisRecogProcess] 找眼及裁剪[%1 ms]").arg(findEyeLast); -// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/145333.552.bmp", 0); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); // irisInfo.hasEye = true; // 4.1 没有找到眼睛则返回 @@ -117,10 +118,21 @@ // 缩放到320 * 240 cv::resize(segMat, segMat, cv::Size(SettingConfig::getInstance().IRIS_WIDTH * 0.5, SettingConfig::getInstance().IRIS_HEIGHT * 0.5)); -/* - std::string filename = QString("%1/%2/%3-seg.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); - cv::imwrite(filename, segMat); -*/ + + // save segMat for debug + std::string segFilename; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + segFilename = QString("%1/%2/%3-seg.bmp").arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH).arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); + cv::imwrite(segFilename, segMat); + } + +// QElapsedTimer timer; +// timer.start(); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); +// irisInfo.hasEye = true; +// cv::Mat segMat = cv::imread("/home/casic/code/CasicIrisIdentify/crash-test/113429-seg.bmp"); + int segMatSize = segMat.cols * segMat.rows; QByteArray data((char*)segMat.data, segMatSize * 3); // 三通道 @@ -182,7 +194,7 @@ // 7. 分割后的后处理 编码及提取特征值 timer.restart(); - if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0|| cv::countNonZero(iris) == 0) + if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0 || cv::countNonZero(iris) == 0) { qDebug() << "算法分割图像失败,暂停200ms"; @@ -222,13 +234,16 @@ // 开始匹配 timer.restart(); + float minScore = 1.0f; for (int i = 0; i < ProMemory::getInstance().getIrisFeatures().size(); i++) { CasicIrisFeature feature = ProMemory::getInstance().getIrisFeatures().at(i); float score = casic::iris::CasicIrisInterface::getInstance().calculatePairPoints(feature.irisFeatureCode, irisInfo.irisFeatureCode); // 计算压缩编码的比较值 + if (score < minScore) { + minScore = score; + } -// cv::imwrite(QString("%1/%2/%3-%4.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss.zzz")).arg(score).toStdString(), irisInfo.matData); if (score <= 0.32) { CasicIrisRecState::getInstance().state = CasicIrisRecState::REC_SEARCH_SUCC; CasicIrisRecState::getInstance().matchedId = feature.personId; @@ -245,6 +260,15 @@ CasicIrisRecState::getInstance().matchTmLast = matchLast; CasicIrisRecState::getInstance().recogTimeLast += matchLast; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + QFile::remove(QString::fromStdString(segFilename)); // delete segment file + cv::imwrite(QString("%1/%2/%3-%4.bmp") + .arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH) + .arg(QDate::currentDate().toString("yyyyMMdd")) + .arg(QTime::currentTime().toString("HHmmss.zzz")) + .arg(minScore).toStdString(), irisInfo.matData); + } + if (CasicIrisRecState::getInstance().state == CasicIrisRecState::REC_SEARCH_SUCC) { // 找到匹配结果 afterRecogAction(); diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp index 05c4c68..17abe3e 100644 --- a/utils/SettingConfig.cpp +++ b/utils/SettingConfig.cpp @@ -37,6 +37,8 @@ DEBUG_CAMERA_ROTATE = getProperty("debug", "cameraRotate").toString(); DEBUG_SEGMENT_IP = getProperty("debug", "segmentIp").toString(); + DEBUG_SAVE_IMAGE = getProperty("debug", "saveImage").toBool(); + DEBUG_IMAGE_BASE_PATH = getProperty("debug", "imageBasePath").toString(); } diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h index c35d6ab..6909e84 100644 --- a/utils/SettingConfig.h +++ b/utils/SettingConfig.h @@ -57,6 +57,8 @@ QString DEBUG_CAMERA_ROTATE; QString DEBUG_SEGMENT_IP; + bool DEBUG_SAVE_IMAGE; + QString DEBUG_IMAGE_BASE_PATH; private: SettingConfig(); diff --git a/utils/SpeakerUtil.cpp b/utils/SpeakerUtil.cpp index 2cb9b20..933809c 100644 --- a/utils/SpeakerUtil.cpp +++ b/utils/SpeakerUtil.cpp @@ -7,6 +7,11 @@ tts->setRate(0.0); tts->setPitch(1.0); tts->setVolume(1.0); + + // 循环播放 + effect.setLoopCount(QSoundEffect::Null); + // 设置音量,0-1 + effect.setVolume(1.0f); } void SpeakerUtil::speak(QString content) @@ -16,3 +21,15 @@ tts->say(content); } } + +void SpeakerUtil::sayIdentifySuccessZhCn() +{ + effect.setSource(QUrl::fromLocalFile("wav/recSuccess.wav")); + effect.play(); +} + +void SpeakerUtil::sayIdentifyFailureZhCn() +{ + effect.setSource(QUrl::fromLocalFile("wav/recFailureRetry.wav")); + effect.play(); +} diff --git a/CasicIrisIdentify.pro b/CasicIrisIdentify.pro index c31991e..e5f8c61 100644 --- a/CasicIrisIdentify.pro +++ b/CasicIrisIdentify.pro @@ -1,4 +1,4 @@ -QT += core gui sql network texttospeech +QT += core gui sql network texttospeech multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets diff --git a/IdentifyForm.cpp b/IdentifyForm.cpp index 8548ecd..7abffa4 100644 --- a/IdentifyForm.cpp +++ b/IdentifyForm.cpp @@ -73,8 +73,8 @@ void IdentifyForm::showRecogFailure() { - SpeakerUtil::getInstance().speak("识别失败,请重试"); -// LOG_INFO("识别失败,请重试"); + SpeakerUtil::getInstance().sayIdentifyFailureZhCn(); + LOG_INFO("识别失败,请重试"); ui->wgtIdentifying->setCurrentIndex(2); @@ -100,7 +100,7 @@ QString deptName = matched.value("deptname").toString(); QString personName = matched.value("name").toString(); - SpeakerUtil::getInstance().speak(QString("识别成功,%1%2").arg(deptName).arg(personName)); + SpeakerUtil::getInstance().sayIdentifySuccessZhCn(); LOG_INFO(QString("识别成功,%1%2").arg(deptName).arg(personName).toStdString()); ui->wgtIdentifying->setCurrentIndex(1); diff --git a/MainWindowForm.cpp b/MainWindowForm.cpp index 31888a9..1a6e8fb 100644 --- a/MainWindowForm.cpp +++ b/MainWindowForm.cpp @@ -88,6 +88,7 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::LOCKSCREEN_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_WAIT; // App状态 = 待机 + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(2.5f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().LOCK_FRAME_INTERVAL); ui->labelMainTime->hide(); @@ -108,6 +109,8 @@ ProMemory::getInstance().widgeFrame = AppConstants::WidgeFrameName::IDENTIFY_FORM; ProMemory::getInstance().appState = AppConstants::ApplicationState::STATE_IDENTIFYING; // App状态 = 识别中 identifyForm->updateIdentifyTips("识 别 中"); + + ProMemory::getInstance().irisCamCtrl->SetCameraFrameRate(10.0f); TimeCounterUtil::getInstance().irisCapCounter->setInterval(SettingConfig::getInstance().IRIS_FRAME_INTERVAL); ui->labelMainTime->show(); diff --git a/casic/iris/CasicIrisInterface.cpp b/casic/iris/CasicIrisInterface.cpp index d33c7ea..5803f44 100644 --- a/casic/iris/CasicIrisInterface.cpp +++ b/casic/iris/CasicIrisInterface.cpp @@ -198,7 +198,16 @@ } cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (imageNorm.empty() == true) { + irisInfo.postProcSucc = false; + return irisInfo; + } irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]); + if (irisInfo.maskNorm.empty() == true) + { + irisInfo.postProcSucc = false; + return irisInfo; + } // std::cout << "finish normalize" << std::endl; // cv::imwrite("/home/nvidia/irisLogs/image-norm.bmp", imageNorm); diff --git a/casic/iris/CasicIrisRec.cpp b/casic/iris/CasicIrisRec.cpp index d9edb67..c8d3bbb 100644 --- a/casic/iris/CasicIrisRec.cpp +++ b/casic/iris/CasicIrisRec.cpp @@ -94,7 +94,11 @@ MatrixXi normMat = MatrixXi::Zero(xo_i.rows(), xo_i.cols()); for (int i = 0; i < xo_i.rows(); i++) { for (int j = 0; j < xo_i.cols(); j++) { - normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i,j)); + if (yo_i(i, j) < 0 || xo_i(i, j) < 0) { + cv::Mat empty; + return empty; + } + normMat(i, j) = eigenImage(yo_i(i, j), xo_i(i, j)); } } diff --git a/conf/config.ini b/conf/config.ini index 66e46ad..1697b34 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -1,3 +1,30 @@ +[window] +#界面窗口宽/高(px) +width=600 +height=1024 +#统一背景色 +backgroundColor="#FFFFFF" +#标题 版权所有 版本号 +title= +copyright=中国航天科工二院二〇三所 +version=1.0.0 +deviceCode=792023000001 + +[camera] +#虹膜相机取一幅画面的时间间隔(ms) +irisFrameInterval=100 +#待机时拍摄帧率(ms) +lockFrameInterval=400 +#虹膜相机拍摄宽度 / 高度 +irisFrameWidth=1080 +irisFrameHeight=1440 +#虹膜图像高度 / 高度 +irisWidth=640 +irisHeight=480 +#虹膜显示图像宽度 / 高度 +irisDisplayWidth=393 +irisDisplayHeight=512 + [recognize] #最大允许识别时间(ms) maxMatchTime=10000 @@ -5,63 +32,24 @@ successTipsLast=5000 #识别失败界面停留时间(ms) failureTipsLast=3000 -#人脸识别最大尝试次数 -maxFaceTryCount=20 -#持续没找到人脸的最大次数 -maxFaceNotFoundCount=500 -#注册时最小人脸 -minFaceRegist=240 -#识别时最小人脸 -minFaceRecog=100 - #虹膜识别最大尝试次数 -maxIrisTryCount=10 +maxIrisTryCount=5 #虹膜识别持续没有找到眼的最大次数 -maxEyeNotFoundCount=50 +maxEyeNotFoundCount=30 +#持续没找到目标而待机的最大次数 +maxFaceNotFoundCount=150 +#识别检测最小眼睛大小 +minEyeSize=320 -#识别方式[1=人脸;2=虹膜;3=双认证;4=任意] -recogType=4 - -[window] -#界面窗口宽(px) -width=600 -#界面窗口高(px) -height=1024 -#统一背景色 -backgroundColor="#FFFFFF" -#标题 -title="虹膜识别终端" - -[work] -#工作状态检测时最小人脸范围 -minFaceSize=160 -#人脸范围最小横坐标 -minFacePosX=320 -#人脸范围最大横坐标 -maxFacePosX=960 -#人脸范围最小纵坐标 -minFacePosY=180 -#人脸范围最大纵坐标 -maxFacePosY=540 -#人脸太近阈值 -faceCloseSize=360 -#人脸太远阈值 -faceFarSize=480 - -[camera] -#虹膜相机取一幅画面的时间间隔(ms) -irisFrameInterval=100 -#虹膜相机拍摄宽度 -irisFrameWidth=1440 -#虹膜相机拍摄高度 -irisFrameHeight=1080 -#虹膜图像高度 -irisWidth=640 -#虹膜图像高度 -irisHeight=480 [log] #日志文件位置 -logFile="d://irisLogs//casic_log.txt" +logFile="logs//casic_log.log" #日志级别 -logLevel="trace" +logLevel="debug" + +[debug] +cameraRotate=90 +segmentIp=192.168.83.107 +saveImage=true +imageBasePath="logs" diff --git a/device/IrisCameraController.cpp b/device/IrisCameraController.cpp index 4eea013..508379f 100644 --- a/device/IrisCameraController.cpp +++ b/device/IrisCameraController.cpp @@ -40,6 +40,12 @@ // isOpen flag set true m_bOpen = true; + // 使能采集帧率调节模式 + emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON); + + // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10 + emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0); + SetUpAcquisitionThread(); } } @@ -172,6 +178,11 @@ return; } +void IrisCameraController::SetCameraFrameRate(float rate) +{ + GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate); +} + bool IrisCameraController::SetAcquisitionBufferNum() { GX_STATUS emStatus = GX_STATUS_SUCCESS; diff --git a/device/IrisCameraController.h b/device/IrisCameraController.h index 67cbe2f..83eb12a 100644 --- a/device/IrisCameraController.h +++ b/device/IrisCameraController.h @@ -21,6 +21,8 @@ void startCapture(); void stopCapture(); + void SetCameraFrameRate(float rate); + CAcquisitionThread * m_pobjAcqThread; GX_DEV_HANDLE m_hDevice; ///< Device Handle uint32_t m_ui32DeviceNum; ///< Device number enumerated diff --git a/device/iris/IrisRecogProcess.cpp b/device/iris/IrisRecogProcess.cpp index e4c8a02..54d38b5 100644 --- a/device/iris/IrisRecogProcess.cpp +++ b/device/iris/IrisRecogProcess.cpp @@ -73,7 +73,8 @@ int findEyeLast = timer.elapsed(); qDebug() << QString("[IrisRecogProcess] 找眼及裁剪[%1 ms]").arg(findEyeLast); -// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/145333.552.bmp", 0); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); // irisInfo.hasEye = true; // 4.1 没有找到眼睛则返回 @@ -117,10 +118,21 @@ // 缩放到320 * 240 cv::resize(segMat, segMat, cv::Size(SettingConfig::getInstance().IRIS_WIDTH * 0.5, SettingConfig::getInstance().IRIS_HEIGHT * 0.5)); -/* - std::string filename = QString("%1/%2/%3-seg.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); - cv::imwrite(filename, segMat); -*/ + + // save segMat for debug + std::string segFilename; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + segFilename = QString("%1/%2/%3-seg.bmp").arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH).arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); + cv::imwrite(segFilename, segMat); + } + +// QElapsedTimer timer; +// timer.start(); +// CasicIrisInfo irisInfo; +// irisInfo.matData = cv::imread("/home/casic/code/irisLogs/20231125/200630.951-0.324786.bmp", 0); +// irisInfo.hasEye = true; +// cv::Mat segMat = cv::imread("/home/casic/code/CasicIrisIdentify/crash-test/113429-seg.bmp"); + int segMatSize = segMat.cols * segMat.rows; QByteArray data((char*)segMat.data, segMatSize * 3); // 三通道 @@ -182,7 +194,7 @@ // 7. 分割后的后处理 编码及提取特征值 timer.restart(); - if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0|| cv::countNonZero(iris) == 0) + if (cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0 || cv::countNonZero(iris) == 0) { qDebug() << "算法分割图像失败,暂停200ms"; @@ -222,13 +234,16 @@ // 开始匹配 timer.restart(); + float minScore = 1.0f; for (int i = 0; i < ProMemory::getInstance().getIrisFeatures().size(); i++) { CasicIrisFeature feature = ProMemory::getInstance().getIrisFeatures().at(i); float score = casic::iris::CasicIrisInterface::getInstance().calculatePairPoints(feature.irisFeatureCode, irisInfo.irisFeatureCode); // 计算压缩编码的比较值 + if (score < minScore) { + minScore = score; + } -// cv::imwrite(QString("%1/%2/%3-%4.bmp").arg("/home/casic/code/irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss.zzz")).arg(score).toStdString(), irisInfo.matData); if (score <= 0.32) { CasicIrisRecState::getInstance().state = CasicIrisRecState::REC_SEARCH_SUCC; CasicIrisRecState::getInstance().matchedId = feature.personId; @@ -245,6 +260,15 @@ CasicIrisRecState::getInstance().matchTmLast = matchLast; CasicIrisRecState::getInstance().recogTimeLast += matchLast; + if (SettingConfig::getInstance().DEBUG_SAVE_IMAGE == true) { + QFile::remove(QString::fromStdString(segFilename)); // delete segment file + cv::imwrite(QString("%1/%2/%3-%4.bmp") + .arg(SettingConfig::getInstance().DEBUG_IMAGE_BASE_PATH) + .arg(QDate::currentDate().toString("yyyyMMdd")) + .arg(QTime::currentTime().toString("HHmmss.zzz")) + .arg(minScore).toStdString(), irisInfo.matData); + } + if (CasicIrisRecState::getInstance().state == CasicIrisRecState::REC_SEARCH_SUCC) { // 找到匹配结果 afterRecogAction(); diff --git a/utils/SettingConfig.cpp b/utils/SettingConfig.cpp index 05c4c68..17abe3e 100644 --- a/utils/SettingConfig.cpp +++ b/utils/SettingConfig.cpp @@ -37,6 +37,8 @@ DEBUG_CAMERA_ROTATE = getProperty("debug", "cameraRotate").toString(); DEBUG_SEGMENT_IP = getProperty("debug", "segmentIp").toString(); + DEBUG_SAVE_IMAGE = getProperty("debug", "saveImage").toBool(); + DEBUG_IMAGE_BASE_PATH = getProperty("debug", "imageBasePath").toString(); } diff --git a/utils/SettingConfig.h b/utils/SettingConfig.h index c35d6ab..6909e84 100644 --- a/utils/SettingConfig.h +++ b/utils/SettingConfig.h @@ -57,6 +57,8 @@ QString DEBUG_CAMERA_ROTATE; QString DEBUG_SEGMENT_IP; + bool DEBUG_SAVE_IMAGE; + QString DEBUG_IMAGE_BASE_PATH; private: SettingConfig(); diff --git a/utils/SpeakerUtil.cpp b/utils/SpeakerUtil.cpp index 2cb9b20..933809c 100644 --- a/utils/SpeakerUtil.cpp +++ b/utils/SpeakerUtil.cpp @@ -7,6 +7,11 @@ tts->setRate(0.0); tts->setPitch(1.0); tts->setVolume(1.0); + + // 循环播放 + effect.setLoopCount(QSoundEffect::Null); + // 设置音量,0-1 + effect.setVolume(1.0f); } void SpeakerUtil::speak(QString content) @@ -16,3 +21,15 @@ tts->say(content); } } + +void SpeakerUtil::sayIdentifySuccessZhCn() +{ + effect.setSource(QUrl::fromLocalFile("wav/recSuccess.wav")); + effect.play(); +} + +void SpeakerUtil::sayIdentifyFailureZhCn() +{ + effect.setSource(QUrl::fromLocalFile("wav/recFailureRetry.wav")); + effect.play(); +} diff --git a/utils/SpeakerUtil.h b/utils/SpeakerUtil.h index d4c1074..02b221b 100644 --- a/utils/SpeakerUtil.h +++ b/utils/SpeakerUtil.h @@ -3,12 +3,13 @@ #include #include +#include class SpeakerUtil : public QObject { Q_OBJECT public: - ~SpeakerUtil() {}; + ~SpeakerUtil() {} SpeakerUtil(const SpeakerUtil&)=delete; SpeakerUtil& operator=(const SpeakerUtil&)=delete; @@ -18,11 +19,14 @@ } void speak(QString content); + void sayIdentifySuccessZhCn(); + void sayIdentifyFailureZhCn(); private: explicit SpeakerUtil(QObject *parent = nullptr); QTextToSpeech * tts; + QSoundEffect effect; signals: