Newer
Older
AppendIrisCodeUtils / casic / iris / CasicIrisInterface.cpp
#ifdef _MSC_VER
#pragma execution_character_set("utf-8")    // Qt VS 中文兼容(UTF-8)
#endif

#include "CasicIrisInterface.h"

#include <QElapsedTimer>
#include <QDateTime>
#include <QDebug>

casic::iris::CasicIrisInterface::CasicIrisInterface()
{
    rec = iristrt::CasicIrisRec(gaborFilterFileName, applicationPointsFileName);

    cascade = new cv::CascadeClassifier();
    cascade->load(cascadeName);
}

casic::iris::CasicIrisInterface::~CasicIrisInterface()
{

}

void casic::iris::CasicIrisInterface::setCascadeFile(QString filename)
{
    this->cascadeName = filename.toStdString();
}
void casic::iris::CasicIrisInterface::setMinEyeSize(int minEyeSize)
{
    this->minEyeSize = minEyeSize;
}
void casic::iris::CasicIrisInterface::setMaxEyeSize(int maxEyeSize)
{
    this->maxEyeSize = maxEyeSize;
}

CasicIrisInfo casic::iris::CasicIrisInterface::findEye(CasicIrisInfo irisInfo)
{
    // 构建OpenCV自带的眼睛分类器
    if (this->cascade == nullptr) {
        this->cascade = new cv::CascadeClassifier();
        this->cascade->load(cascadeName);
    }

    QElapsedTimer timer;
    timer.start();

    std::vector<cv::Rect> rect;
    cv::Size minEyeRectSize(minEyeSize, minEyeSize);
    cv::Size maxEyeRectSize(maxEyeSize, maxEyeSize);

    // ★分类器对象调用
    cascade->detectMultiScale(irisInfo.matData, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minEyeRectSize, maxEyeRectSize);

    if (rect.size() == 0)
    {
        irisInfo.hasEye = false;
        return irisInfo;
    }

//    LOG(DEBUG) << QString("眼睛检测算法[tm: %1 ms][count: %2][rect: (%3, %4) %5 * %6]")
//                  .arg(timer.elapsed()).arg(rect.size())
//                  .arg(rect.at(0).x).arg(rect.at(0).y)
//                  .arg(rect.at(0).width).arg(rect.at(0).height).toStdString();
//    LOG_DEBUG(QString("眼睛检测算法[tm: %1 ms][count: %2][rect: (%3, %4) %5 * %6]")
//              .arg(timer.elapsed()).arg(rect.size())
//              .arg(rect.at(0).x).arg(rect.at(0).y)
//              .arg(rect.at(0).width).arg(rect.at(0).height).toStdString());
    qDebug() << QString("眼睛检测算法[tm: %1 ms][count: %2][rect: (%3, %4) %5 * %6]")
                              .arg(timer.elapsed()).arg(rect.size())
                              .arg(rect.at(0).x).arg(rect.at(0).y)
                              .arg(rect.at(0).width).arg(rect.at(0).height);

    irisInfo.hasEye = true;
//    irisInfo.eyeRect = rect.at(0);

//    irisInfo.data = ImageUtil::MatImageToQImage(irisInfo.matData);

    return irisInfo;
}

CasicIrisInfo casic::iris::CasicIrisInterface::findAndCutEye(CasicIrisInfo irisInfo)
{
    // 构建OpenCV自带的眼睛分类器
    if (this->cascade == nullptr) {
        this->cascade = new cv::CascadeClassifier();
        this->cascade->load(cascadeName);
    }

    std::vector<cv::Rect> rect;
    cv::Size minEyeRectSize(minEyeSize, minEyeSize);
    cv::Size maxEyeRectSize(maxEyeSize, maxEyeSize);

    // ★分类器对象调用
    cascade->detectMultiScale(irisInfo.matData, rect, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT, minEyeRectSize, maxEyeRectSize);

    if (rect.size() == 0)
    {
        irisInfo.hasEye = false;
        return irisInfo;
    }

//    LOG(DEBUG) << QString("眼睛检测算法[tm: %1 ms][count: %2][rect: (%3, %4) %5 * %6]")
//                  .arg(timer.elapsed()).arg(rect.size())
//                  .arg(rect.at(0).x).arg(rect.at(0).y)
//                  .arg(rect.at(0).width).arg(rect.at(0).height).toStdString();
//    LOG_DEBUG(QString("眼睛检测算法[tm: %1 ms][count: %2][rect: (%3, %4) %5 * %6]")
//              .arg(timer.elapsed()).arg(rect.size())
//              .arg(rect.at(0).x).arg(rect.at(0).y)
//              .arg(rect.at(0).width).arg(rect.at(0).height).toStdString());
    qDebug() << QString("眼睛检测算法[count: %1][rect: (%2, %3) %4 * %5]")
                              .arg(rect.size())
                              .arg(rect.at(0).x).arg(rect.at(0).y)
                              .arg(rect.at(0).width).arg(rect.at(0).height);

    // 找到眼睛之后, 将眼部裁剪下来, 图像拉伸到640 * 480
    cv::Point center;
    center.x = cvFloor(rect.at(0).x + rect.at(0).width*0.5);
    center.y = cvFloor(rect.at(0).y + rect.at(0).height*0.5);

    // 限制中心点的范围
    if (center.x < SettingConfig::getInstance().IRIS_WIDTH * cutRatio * 0.5)
    {
        // x小于240则x=240
//        center.x = center.x - SettingConfig::getInstance().IRIS_WIDTH * cutRatio * 0.5;
        center.x = SettingConfig::getInstance().IRIS_WIDTH * cutRatio * 0.5;
    } else if (center.x > SettingConfig::getInstance().IRIS_FRAME_WIDTH - SettingConfig::getInstance().IRIS_WIDTH * cutRatio * 0.5) {
        // x大于1040则x=1040
        center.x = SettingConfig::getInstance().IRIS_FRAME_WIDTH - SettingConfig::getInstance().IRIS_WIDTH * cutRatio * 0.5;
    }

    if (center.y < SettingConfig::getInstance().IRIS_HEIGHT * cutRatio * 0.5)
    {
        // y小于180则y=180
        center.y = SettingConfig::getInstance().IRIS_HEIGHT * cutRatio * 0.5;
    } else if (center.y > SettingConfig::getInstance().IRIS_FRAME_HEIGHT - SettingConfig::getInstance().IRIS_HEIGHT * cutRatio * 0.5) {
        center.y = SettingConfig::getInstance().IRIS_FRAME_HEIGHT - SettingConfig::getInstance().IRIS_HEIGHT * cutRatio * 0.5;
    }

    // 裁剪眼部图像
    cv::Mat cutSize = irisInfo.matData.clone();
    cutSize = irisInfo.matData(cv::Rect(center.x - SettingConfig::getInstance().IRIS_WIDTH * cutRatio * 0.5,
                                         center.y - SettingConfig::getInstance().IRIS_HEIGHT * cutRatio * 0.5,
                                         SettingConfig::getInstance().IRIS_WIDTH * cutRatio,
                                         SettingConfig::getInstance().IRIS_HEIGHT * cutRatio));

    // 裁剪后放大到 640 * 480
    cv::resize(cutSize, cutSize, cv::Size(SettingConfig::getInstance().IRIS_WIDTH, SettingConfig::getInstance().IRIS_HEIGHT));
    cv::flip(cutSize, cutSize, 1); // 左右翻转

    irisInfo.hasEye = true;
    irisInfo.matData = cutSize;

    return irisInfo;
}

CasicIrisInfo casic::iris::CasicIrisInterface::irisQualityAssess(CasicIrisInfo irisInfo)
{

    return irisInfo;
}

CasicIrisInfo casic::iris::CasicIrisInterface::irisCodeExtract(CasicIrisInfo irisInfo)
{

    QElapsedTimer timer;
    timer.start();

//    QSocketClientUtil * clientUtil = new QSocketClientUtil();

    QByteArray data((char*)irisInfo.matData.data, 640*480);

    std::cout << "extract iris code" << std::endl;

//    clientUtil->sendData(data);
//    if (response.size() == 1024)
//    {
//        QLog::getInstance()->logger()->debug(QString("特征值提取[耗时: %1ms][特征值: %2]\n")
//                                                     .arg(timer.elapsed())
//                                                     .arg(QByteUtil::binToHexString(response)));
//    } else
//    {
//         std::cout << response.toStdString() << std::endl;
//    }

    return irisInfo;
}


CasicIrisInfo casic::iris::CasicIrisInterface::irisEncode(CasicIrisInfo irisInfo)
{
    std::vector<int> irisCircle, pupilCircle; // x,y,r
    iristrt::CasicSegPostProcess segPost;

    cv::resize(irisInfo.segResult.irisMask, irisInfo.segResult.irisMask, cv::Size(irisInfo.matData.cols, irisInfo.matData.rows));
    cv::resize(irisInfo.segResult.innerMask, irisInfo.segResult.innerMask, cv::Size(irisInfo.matData.cols, irisInfo.matData.rows));
    cv::resize(irisInfo.segResult.outerCircle, irisInfo.segResult.outerCircle,cv::Size(irisInfo.matData.cols, irisInfo.matData.rows));

    bool flag = segPost.postProcess(irisInfo.segResult.irisMask, irisInfo.segResult.outerCircle, irisInfo.segResult.innerMask, irisCircle, pupilCircle);
    if(!flag || irisCircle.size() <= 0 || pupilCircle.size() <= 0)
    {
        return irisInfo;
    }
//    std::cout << "finish postProcess " << irisCircle[0] << " " << irisCircle[1] << " " << irisCircle[2] << " " << pupilCircle[0] << " " << pupilCircle[1] << "  " << pupilCircle[2] << std::endl;
    int iris_x = irisCircle[0];
    int iris_y = irisCircle[1];
    int iris_r = irisCircle[2];
    int pupil_x = pupilCircle[0];
    int pupil_y = pupilCircle[1];
    int pupil_r = pupilCircle[2];
    int dis = iristrt::point_distance(iris_x,iris_y,pupil_x,pupil_y);
    if(!(dis + pupil_r < iris_r))
    {
        // pupil circle doesn't contained in iris circle
        return irisInfo;
    }

    cv::Mat imageNorm = rec.normalize(irisInfo.matData, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]);
    irisInfo.maskNorm = rec.normalize(irisInfo.segResult.irisMask, irisCircle[0], irisCircle[1], irisCircle[2], pupilCircle[0], pupilCircle[1], pupilCircle[2]);
    //     std::cout << "finish normalize" << std::endl;

    irisInfo.irisCode = rec.encodeToImage(imageNorm);

    return irisInfo;
}

QByteArray casic::iris::CasicIrisInterface::extractFeature(CasicIrisInfo irisInfo)
{
    QByteArray irisFeatureCode = rec.extractFeature(irisInfo.irisCode, irisInfo.maskNorm);
    return irisFeatureCode;
}

float casic::iris::CasicIrisInterface::calculateMatchScore(CasicIrisFeature feature, CasicIrisInfo irisInfo)
{
    return rec.matchImage(feature.irisCode, irisInfo.irisCode, feature.maskNorm, irisInfo.maskNorm);
}

float casic::iris::CasicIrisInterface::calculatePairPoints(QByteArray feature, QByteArray other)
{
    return rec.matchFeatureCode(reinterpret_cast<uchar *>(feature.data()), reinterpret_cast<uchar *>(other.data()));
}