From 1731ea445f8ab5f556ff820a4d4ba8cfa2206053 Mon Sep 17 00:00:00 2001 From: luocai Date: Wed, 25 Sep 2024 17:09:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=BB=A3=E7=A0=81/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Analyser/CMakeLists.txt | 1 + Analyser/ModuleCommunication.cpp | 29 +++++++++++++++++++++++++++-- Analyser/ModuleCommunication.h | 16 ++++++++++++++++ Analyser/resources/palm-middle.png | Bin 0 -> 11150 bytes 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 Analyser/resources/palm-middle.png diff --git a/Analyser/CMakeLists.txt b/Analyser/CMakeLists.txt index 4aa1e6f..d33c4ea 100644 --- a/Analyser/CMakeLists.txt +++ b/Analyser/CMakeLists.txt @@ -30,6 +30,7 @@ qt_add_qml_module(Analyser RESOURCES resources/successfull.svg resources/warning.svg + resources/palm-middle.png ) target_compile_definitions(Analyser diff --git a/Analyser/ModuleCommunication.cpp b/Analyser/ModuleCommunication.cpp index 3776d78..655f267 100644 --- a/Analyser/ModuleCommunication.cpp +++ b/Analyser/ModuleCommunication.cpp @@ -1,6 +1,8 @@ #include "ModuleCommunication.h" #include "BoostLog.h" #include "StringUtility.h" +#include +#include #include #include #ifdef WIN32 @@ -257,9 +259,16 @@ void ModuleCommunication::processPackage(const uint8_t *data, uint16_t size) { uint16_t width = ntohs(info->imageWidth); uint16_t height = ntohs(info->imageHeight); userId = ntohs(info->userid); + uint16_t plamX = ntohs(info->palmVeinInformation.x1); + uint16_t plamY = ntohs(info->palmVeinInformation.y1); LOG_CAT(info, GUI) << "注册成功,用户ID: " << userId << ", 图片大小: " << width << "x" << height << ", 已有ID: " << ntohs(info->enrolledId) - << ", 姓名: " << (const char *)info->enrolledUsername; + << ", 姓名: " << (const char *)info->enrolledUsername << ". palm vein: (" + << plamX << "," << plamY << " " << (ntohs(info->palmVeinInformation.x2) - plamX) + << "x" << (ntohs(info->palmVeinInformation.y2) - plamY) + << "), detection probability: " + << ntohs(info->palmVeinInformation.detectionProbability) / 1000.f + << ", quality: " << ntohs(info->palmVeinInformation.quality) / 1000.f; emit newImageInfo(static_cast(replyId), width * height, info->md5); } else { @@ -388,11 +397,15 @@ void ModuleCommunication::processPackage(const uint8_t *data, uint16_t size) { } case NoteId::PalmState: { // 模组返回的数据为当前帧的手掌状态 auto state = reinterpret_cast(data + 6); - uint16_t palmState = ntohs(state->state); + PalmState palmState = static_cast(ntohs(state->state)); if (palmState == NeedMoveToCenter) { emit errorOccurred(NoteId::InteractWarning, "录入提示", "请将手掌置于画面中心"); } else if (palmState == TooFar) { emit errorOccurred(NoteId::InteractWarning, "录入提示", "请将手掌靠近一点"); + } else if (palmState == ManyPalm) { + emit errorOccurred(NoteId::InteractWarning, "录入提示", "检测到多个手掌"); + } else if (palmState == NoAlive) { + emit errorOccurred(NoteId::InteractWarning, "录入提示", "活体检测未通过"); } LOG(info) << "palm state: " << palmState; break; @@ -504,3 +517,15 @@ std::string ModuleCommunication::protocolDataFormatString(const uint8_t *data, i } return oss.str(); } + +BOOST_DESCRIBE_ENUM(ModuleCommunication::PalmState, NoPalm, TooFar, NeedMoveToCenter, ManyPalm, NoAlive) +namespace std { +std::ostream &operator<<(std::ostream &stream, const ModuleCommunication::PalmState &element) { + char const *r = "(unnamed)"; + boost::mp11::mp_for_each>([&](auto D) { + if (element == D.value) r = D.name; + }); + stream << r << "(" << static_cast(element) << ")"; + return stream; +} +} // namespace std diff --git a/Analyser/ModuleCommunication.h b/Analyser/ModuleCommunication.h index 9ec0602..22fd0f1 100644 --- a/Analyser/ModuleCommunication.h +++ b/Analyser/ModuleCommunication.h @@ -59,6 +59,7 @@ public: NoPalm = 1, TooFar = 6, NeedMoveToCenter = 15, + ManyPalm = 101, // 太多掌静脉 NoAlive = 122, }; @@ -112,6 +113,15 @@ public: uint8_t operation; }; + struct PalmVeinInformation { + uint16_t x1; + uint16_t y1; + uint16_t x2; + uint16_t y2; + uint16_t detectionProbability; + uint16_t quality; + }; + struct EnrollExtendedReply { uint16_t userid; uint16_t imageWidth; @@ -120,6 +130,7 @@ public: uint8_t md5[16]; uint8_t enrolledUsername[32]; uint16_t enrolledId; // 掌静脉库里已经存在的id + PalmVeinInformation palmVeinInformation; uint8_t reserved[4]; }; @@ -144,6 +155,7 @@ public: uint16_t image_height; uint8_t image_format; // 0: 只有Y分量,灰度图 uint8_t md5[16]; + PalmVeinInformation palmVeinInformation; }; struct UploadImageInformation { @@ -234,4 +246,8 @@ private: int m_otaVerison; }; +namespace std { +std::ostream &operator<<(std::ostream &stream, const ModuleCommunication::PalmState &element); +} // namespace std + #endif // MODULECOMMUNICATION_H diff --git a/Analyser/resources/palm-middle.png b/Analyser/resources/palm-middle.png new file mode 100644 index 0000000000000000000000000000000000000000..696eaf78e58dc4dbef547f9d4ce51269973b469b GIT binary patch literal 11150 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 IA}aiU0E?@X6951J literal 0 HcmV?d00001