Newer
Older
CasicBioRecNew / device / iris / IrisRegistProcess.cpp
#include "IrisRegistProcess.h"

IrisRegistProcess::IrisRegistProcess(QObject *parent) : QThread(parent)
{
    this->working = false;
    this->exit = false;

    // 连接算法服务
    clientUtil = new SocketClientUtil(this);
    clientUtil->connect("127.0.0.1", 2015);

    // 调用socket发送消息
    connect(this, &IrisRegistProcess::sendDataToExract, clientUtil, &SocketClientUtil::sendData);
}

IrisRegistProcess::~IrisRegistProcess()
{
    this->setWorking(false);
}

void IrisRegistProcess::setWorking(bool working)
{
    this->working = working;
}
void IrisRegistProcess::exitThread()
{
    this->exit = true;
}

void IrisRegistProcess::addOneTryCount()
{
    CasicIrisRecState::getInstance().tryCount++;
//    LOG(DEBUG) << QString("[CasicIrisRegistProcess]已尝试次数[%1]").arg(CasicIrisRecState::getInstance().tryCount).toStdString();

    if (CasicIrisRecState::getInstance().tryCount >= SettingConfig::getInstance().MAX_IRIS_TRY_COUNT)
    {
        CasicIrisRecState::getInstance().noEyeCount = 0;
        CasicIrisRecState::getInstance().tryCount = 0;
        emit captureIrisFailure();
    } else {
        ProMemory::getInstance().irisRegistPro->setWorking(true); // 继续工作
    }
}
void IrisRegistProcess::addOneNoEyeCount()
{
    CasicIrisRecState::getInstance().noEyeCount++;
    if (CasicIrisRecState::getInstance().noEyeCount >= SettingConfig::getInstance().MAX_EYE_NOT_FOUND_COUNT)
    {
        CasicIrisRecState::getInstance().noEyeCount = 0;
        emit captureIrisFailure();
    }
}

void IrisRegistProcess::run()
{
    while (exit == false)
    {
        // 如果工作标志位为否, 则跳出
        if (this->working == false)
        {
            this->msleep(200); // 200ms后再判断
            continue;
        }

        // 图像栈中没有图像则直接返回
        if (ProMemory::getInstance().isIrisQueueEmpty() == true)
        {
//            LOG(DEBUG) << QString("[CasicIrisRegistThread]虹膜图像栈空 暂停200ms").toStdString();
            this->msleep(200); // 200ms后再判断
            continue;
        }

        // 取出一幅图像
        CasicIrisInfo irisInfo = ProMemory::getInstance().popCasicIris();
//        LOG(DEBUG) << QString("[CasicIrisRegistThread]取出一幅虹膜图").toStdString();

        if (CasicIrisRecState::getInstance().state == CasicIrisRecState::IrisRecStateName::REC_LEFT_FIND_EYE &&
                irisInfo.leftOrRight == "left")
        {
            // 左眼已经编码成功则不再判断左眼
//            LOG(DEBUG) << QString("[CasicIrisRegistThread]左眼已经编码成功则不再判断左眼[%1][%2]").arg(CasicIrisRecState::getInstance().state).arg(irisInfo.leftOrRight).toStdString();
            this->msleep(200); // 200ms后再判断
            continue;
        } else if (CasicIrisRecState::getInstance().state == CasicIrisRecState::IrisRecStateName::REC_RIGHT_FIND_EYE &&
                   irisInfo.leftOrRight == "right"){
            // 右眼已经编码成功则不再判断右眼
//            LOG(DEBUG) << QString("[CasicIrisRegistThread]右眼已经编码成功则不再判断右眼[%1][%2]").arg(CasicIrisRecState::getInstance().state).arg(irisInfo.leftOrRight).toStdString();
            this->msleep(200); // 200ms后再判断
            continue;
        }

        // 调用找眼分类器算法
        irisInfo = casic::iris::CasicIrisInterface::getInstance().findEye(irisInfo);

        // 没有找到眼睛则返回
        if (irisInfo.hasEye == false)
        {
            // 表示本次识别结束, 可以开始下一次识别过程
//            LOG(DEBUG) << QString("[CasicIrisRegistThread]分类器没有找到眼睛,暂停200ms[%1]").arg(CasicIrisRecState::getInstance().noEyeCount).toStdString();
            addOneNoEyeCount();

            // 双眼都要注册, 没找到眼不重置状态
            this->msleep(200); // 200ms后再判断
            continue;
        }

        // 找到眼睛则暂停线程工作
        ProMemory::getInstance().irisRegistPro->setWorking(false);
//        LOG(DEBUG) << QString("找到眼睛暂停线程工作").toStdString();

        // 找到眼睛则开始质量评估和编码
        // 调用远程算法进行编码
        if (CasicIrisRecState::getInstance().recoginzeId == "0")
        {
            // 第一次找到眼则 虹膜识别状态初始化
            CasicIrisRecState::getInstance().initRecognize();
        }

        CasicIrisRecState::getInstance().noEyeCount = 0; // 持续未找到眼的次数清零
        CasicIrisRecState::getInstance().irisInfo->hasEye = irisInfo.hasEye;
        CasicIrisRecState::getInstance().irisInfo->leftOrRight = irisInfo.leftOrRight;
        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("[-r]"); // 注册编码

        // 发送TCP消息去匹配
        emit sendDataToExract(data);

        QTimer toTimer;
        QEventLoop loop;
        toTimer.singleShot(3000, &loop, &QEventLoop::quit);
        connect(clientUtil, &SocketClientUtil::responseReaded, &loop, &QEventLoop::quit);
        loop.exec();

        QByteArray encodeResponse = clientUtil->getResponse();

        // 清除队列缓存
        ProMemory::getInstance().clearIrisQueue();

        // 编码成功
        if (encodeResponse.size() == 1024)
        {
//            LOG(DEBUG) << QString("虹膜特征值提取[耗时%1ms][%2]").arg(timer.elapsed()).arg(irisInfo.leftOrRight).toStdString();

            // 保存图像文件
//            cv::imwrite(QString("D:\\irisLogs\\%1-%2.bmp").arg(QDateTime::currentDateTime().toString("HHmmsszzz")).arg(irisInfo.leftOrRight).toStdString(), irisInfo.matData);

            CasicIrisRecState::getInstance().irisInfo->irisCode = encodeResponse;

            // 编码成功 到业务中判断
            emit findNoSimIris(CasicIrisRecState::getInstance().irisInfo);
        } else if (encodeResponse.contains("-100") == true)
        {
            // 编码失败
            addOneTryCount();
            CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START;
        } else if (encodeResponse.contains("-101") == true ||
                   encodeResponse.contains("-102") == true)
        {
            // 找到匹配的人
            QString message = encodeResponse.mid(5, encodeResponse.size() - 6);
            QStringList messList = message.split(";");
            QString personId = messList.at(1);

            // 到业务中进行判断
            emit findMatchedIris(personId);
        } else
        {
            CasicIrisRecState::getInstance().state = CasicIrisRecState::IrisRecStateName::REC_NOT_START;
            // 超时返回则尝试次数+1
            addOneTryCount();
        }
    }
}