#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("127.0.0.1", 2015); // 调用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; } // LOG(TRACE) << QString("[IrisRecogProcess] 准备取出虹膜图像[%1]").arg(ProMemory::getInstance().isIrisQueueEmpty()).toStdString(); // LOG_TRACE(QString("[IrisRecogProcess] 准备取出虹膜图像[%1]").arg(ProMemory::getInstance().isIrisQueueEmpty()).toStdString()); // 取出虹膜图像栈中的一条数据 CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris(); // LOG(DEBUG) << QString("[IrisRecogProcess] 取出虹膜图像").toStdString(); // LOG_DEBUG(QString("[IrisRecogProcess] 取出虹膜图像").toStdString()); qDebug() << QString("[IrisRecogProcess] 取出虹膜图像"); // 调用找眼分类器算法 casic::iris::CasicIrisInterface::getInstance().setMinEyeSize(360); 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); QElapsedTimer timer; timer.start(); QByteArray data((char*)irisInfo.matData.data, SettingConfig::getInstance().IRIS_WIDTH * SettingConfig::getInstance().IRIS_HEIGHT); data.prepend("[-m]"); // 识别 // 发送TCP消息去匹配 emit sendDataToExract(data); // 状态修改为特征提取 CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_FEATURE_EXTRACT; QTimer toTimer; QEventLoop loop; toTimer.singleShot(3000, &loop, &QEventLoop::quit); // connect(clientUtil, &SocketClientUtil::responseReaded, &loop, &QEventLoop::quit); loop.exec(); // QByteArray matchResponse = clientUtil->getResponse(); 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"); } } }