#ifdef _MSC_VER #pragma execution_character_set("utf-8") // Qt VS 中文兼容(UTF-8) #endif #include "IrisRecogProcess.h" IrisRecogProcess::IrisRecogProcess(QObject *parent) : QThread(parent) { this->working = false; this->exit = false; // 连接算法服务 clientUtil = new SocketClientUtil(this); clientUtil->connect("192.168.83.223", 50007); // 调用socket发送消息 connect(this, &IrisRecogProcess::sendDataToExract, clientUtil, &SocketClientUtil::sendData); } IrisRecogProcess::~IrisRecogProcess() { this->setWorking(false); } void IrisRecogProcess::setWorking(bool working) { this->working = working; } void IrisRecogProcess::exitThread() { this->exit = true; } void IrisRecogProcess::run() { while (exit == false) { // 如果工作标志位为否, 则跳出 if (this->working == false) { this->msleep(200); // 200ms后再判断 continue; } // 图像栈中没有图像则直接返回 if (ProMemory::getInstance().isIrisQueueEmpty() == true) { // LOG(TRACE) << QString("[IrisRecogProcess] 虹膜图像栈空, 暂停200ms").toStdString(); // LOG_TRACE(QString("[IrisRecogProcess] 虹膜图像栈空, 暂停200ms").toStdString()); qDebug() << QString("[IrisRecogProcess] 虹膜图像栈空, 暂停200ms"); this->msleep(200); // 200ms后再判断 continue; } // 识别状态不等于未开始, 表示已经进入识别程序了, 后续不再执行, 等待本次识别过程结束 if (CasicIrisRecState::getInstance().state != CasicIrisRecState::IrisRecStateName::REC_NOT_START) { // LOG(DEBUG) << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state).toStdString(); qDebug() << QString("[IrisRecogProcess] 已在一次识别过程中, 暂停200ms。当前状态为: %1").arg(CasicIrisRecState::getInstance().state); this->msleep(200); // 200ms后再判断 continue; } // 取出虹膜图像栈中的一条数据 CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris(); // LOG(DEBUG) << QString("[IrisRecogProcess] 取出虹膜图像").toStdString(); // LOG_DEBUG(QString("[IrisRecogProcess] 取出虹膜图像").toStdString()); qDebug() << QString("[IrisRecogProcess] 取出虹膜图像"); // 调用找眼分类器算法 casic::iris::CasicIrisInterface::getInstance().setMinEyeSize(200); irisInfo = casic::iris::CasicIrisInterface::getInstance().findAndCutEye(irisInfo); // 没有找到眼睛则返回 if (irisInfo.hasEye == false) { // 表示本次识别结束, 可以开始下一次识别过程 // LOG(DEBUG) << QString("[IrisRecogProcess] 分类器没有找到眼睛,暂停200ms[%1]").arg(CasicIrisRecState::getInstance().noEyeCount).toStdString(); // LOG_DEBUG(QString("[IrisRecogProcess] 分类器没有找到眼睛,暂停200ms[%1]").arg(CasicIrisRecState::getInstance().noEyeCount).toStdString()); qDebug() << QString("[IrisRecogProcess] 分类器没有找到眼睛,暂停200ms[%1]").arg(CasicIrisRecState::getInstance().noEyeCount); addOneNoEyeCount(); this->msleep(200); // 200ms后再判断 continue; } // LOG(DEBUG) << QString("[IrisRecogProcess] 找到眼睛调用远程算法进行识别").toStdString(); // LOG_DEBUG(QString("[IrisRecogProcess] 找到眼睛调用远程算法进行识别").toStdString()); // 找到眼睛则开始质量评估和编码 // 调用远程算法进行编码 if (CasicIrisRecState::getInstance().recoginzeId == "0") { // 第一次找到眼则 虹膜识别状态初始化 CasicIrisRecState::getInstance().initRecognize(); } CasicIrisRecState::getInstance().noEyeCount = 0; // 持续未找到眼的次数清零 CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_FIND_EYE; // CasicIrisRecState::getInstance().irisInfo->hasEye = irisInfo.hasEye; // CasicIrisRecState::getInstance().irisInfo->eyeRect = irisInfo.eyeRect; // CasicIrisRecState::getInstance().irisInfo->matData = irisInfo.matData; // CasicIrisRecState::getInstance().irisInfo->data = ImageUtil::MatImageToQImage(irisInfo.matData); // irisInfo.matData = cv::imread("d:\\irisLogs\\photo\\left.bmp", 0); QElapsedTimer timer; timer.start(); // 进行预处理 如图像 irisInfo = casic::iris::CasicIrisInterface::getInstance().irisPreProcess(irisInfo); QByteArray data((char*)irisInfo.matData.data, SettingConfig::getInstance().IRIS_WIDTH * 0.5 * SettingConfig::getInstance().IRIS_HEIGHT * 0.5 * 3); // 发送TCP消息去匹配 emit sendDataToExract(data); // 等待接收算法返回的结果 QTimer toTimer; QEventLoop loop; toTimer.singleShot(3000, &loop, &QEventLoop::quit); // 等待3秒后退出等待 connect(clientUtil, &SocketClientUtil::responseReaded, &loop, &QEventLoop::quit); loop.exec(); char recvPupil[320 * 240 * 1]; char recvMask[320 * 240 * 1]; char recvIris[320 * 240 * 1]; memset(recvPupil, 0, sizeof(recvPupil)); memset(recvMask, 0, sizeof(recvMask)); memset(recvIris, 0, sizeof(recvIris)); for (int i = 0; i < clientUtil->getResponse().size(); i++) { if (i < 320 * 240) recvPupil[i] = clientUtil->getResponse().at(i); else if (i >= 320 * 240 && i < 2 * 320 * 240) recvMask[i - 320 * 240] = clientUtil->getResponse().at(i); else recvIris[i - 2 * 320 * 240] = clientUtil->getResponse().at(i); } cv::Mat pupil(240, 320, CV_8UC1, recvPupil); cv::Mat mask(240, 320, CV_8UC1, recvMask); cv::Mat iris(240, 320, CV_8UC1, recvIris); irisInfo.segResult.innerMask = pupil; irisInfo.segResult.irisMask = mask; irisInfo.segResult.outerCircle = iris; /* std::string pupilSeg = QString("%1\\%2\\%3-pupil-seg.bmp").arg("d:\\irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); std::string maskSeg = QString("%1\\%2\\%3-mask-seg.bmp").arg("d:\\irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); std::string irisSeg = QString("%1\\%2\\%3-iris-seg.bmp").arg("d:\\irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); cv::imwrite(pupilSeg, pupil); cv::imwrite(maskSeg, mask); cv::imwrite(irisSeg, iris); */ qDebug() << QString("算法分割图像成功[%1 ms]").arg(timer.elapsed()); // 分割后的后处理 if(cv::countNonZero(mask) == 0 || cv::countNonZero(pupil) == 0|| cv::countNonZero(iris) == 0) { qDebug() << "算法分割图像失败,暂停200ms"; addOneTryCount(); this->msleep(200); // 200ms后再判断 continue; } // 状态修改为特征提取 CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_FEATURE_EXTRACT; timer.restart(); qDebug() << "开始提取特征"; irisInfo = casic::iris::CasicIrisInterface::getInstance().irisEncode(irisInfo); /* std::string codeFilename = QString("%1\\%2\\%3-code.bmp").arg("d:\\irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); std::string maskFilename = QString("%1\\%2\\%3-mask.bmp").arg("d:\\irisLogs").arg(QDate::currentDate().toString("yyyyMMdd")).arg(QTime::currentTime().toString("HHmmss")).toStdString(); cv::imwrite(codeFilename, irisInfo.irisCode); cv::imwrite(maskFilename, irisInfo.maskNorm); */ qDebug() << QString("虹膜图像编码成功[%1 ms]").arg(timer.elapsed()); // 开始匹配 for (int i = 0; i < ProMemory::getInstance().getIrisFeatures().size(); i++) { CasicIrisFeature feature = ProMemory::getInstance().getIrisFeatures().at(i); float score = casic::iris::CasicIrisInterface::getInstance().calculateMatchScore(feature, irisInfo); qDebug() << score; if (score <= 0.32) { // 找到匹配结果 emit findMatchedIris(feature.personId); break; } } // 没有匹配上 addOneTryCount(); // QByteArray matchResponse; // LOG(INFO) << QString("算法匹配结果").toStdString() << matchResponse.toStdString(); // LOG_INFO("算法匹配结果 {}",matchResponse.toStdString()); /* // 算法调用返回成功 if (matchResponse.size() > 0) { QString response = matchResponse.mid(5, matchResponse.size() - 6); QStringList messList = response.split(";"); QString code = messList.at(0); if (code.toInt() == 0) { QString personId = messList.at(1); CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_SEARCH_SUCC; // LOG(INFO) << QString("匹配成功[tm: %1 ms][id: %2]").arg(timer.elapsed()).arg(personId).toStdString(); // LOG_INFO(QString("匹配成功[tm: %1 ms][id: %2]").arg(timer.elapsed()).arg(personId).toStdString()); // 保存图像文件 // cv::imwrite(QString("D:\\irisLogs\\%1-%2.bmp").arg(QDateTime::currentDateTime().toString("HHmmsszzz")).arg(irisInfo.leftOrRight).toStdString(), irisInfo.matData); CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; emit findMatchedIris(personId); this->afterRecogAction(); } else if (code.toInt() == -200) { // 匹配失败 // LOG(INFO) << QString("匹配失败: ").toStdString() << matchResponse.toStdString(); // LOG_INFO("匹配失败: {}", matchResponse.toStdString()); // 匹配失败则尝试次数+1 addOneTryCount(); } else if (code.toInt() == -100) { // 编码失败 // LOG(INFO) << QString("编码失败: ").toStdString() << matchResponse.toStdString(); // LOG_INFO("编码失败: {}", matchResponse.toStdString()); // 编码失败则尝试次数+1 addOneTryCount(); } } else { // 超时返回则尝试次数+1 addOneTryCount(); }*/ } } void IrisRecogProcess::afterRecogAction() { this->setWorking(false); ProMemory::getInstance().clearIrisQueue(); // 清理虹膜数据栈 } void IrisRecogProcess::addOneTryCount() { CasicIrisRecState::getInstance().tryCount++; // LOG(DEBUG) << QString("[CasicIrisRecogProcess]已尝试次数[%1]").arg(CasicIrisRecState::getInstance().tryCount).toStdString(); // LOG_DEBUG(QString("[CasicIrisRecogProcess]已尝试次数[%1]").arg(CasicIrisRecState::getInstance().tryCount).toStdString()); CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; if (CasicIrisRecState::getInstance().tryCount >= SettingConfig::getInstance().MAX_IRIS_TRY_COUNT) { CasicIrisRecState::getInstance().noEyeCount = 0; CasicIrisRecState::getInstance().tryCount = 0; this->setWorking(false); // ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); emit failedMatchedIris(); } } void IrisRecogProcess::addOneNoEyeCount() { CasicIrisRecState::getInstance().noEyeCount++; CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START; if (CasicIrisRecState::getInstance().noEyeCount >= SettingConfig::getInstance().MAX_EYE_NOT_FOUND_COUNT) { CasicIrisRecState::getInstance().noEyeCount = 0; this->setWorking(false); // ProMemory::getInstance().irisCam->stopCapture(); ProMemory::getInstance().clearIrisQueue(); // if (qrand() % 10 < 5) { emit failedMatchedIris(); // } // else { // emit findMatchedIris("1"); // } } }