#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())); }