完善调试功能。

This commit is contained in:
luocai 2024-08-07 11:45:13 +08:00
parent c6554704ac
commit 2610c40189
6 changed files with 88 additions and 40 deletions

View File

@ -21,7 +21,7 @@
#include <fstream> #include <fstream>
#include <mbedtls/md5.h> #include <mbedtls/md5.h>
constexpr uint32_t ImageSliceSize = 2048; constexpr uint32_t ImageSliceSize = (4000 - 32);
Application::Application(int &argc, char **argv) : m_app(std::make_shared<QApplication>(argc, argv)) { Application::Application(int &argc, char **argv) : m_app(std::make_shared<QApplication>(argc, argv)) {
m_app->setApplicationName(APPLICATION_NAME); m_app->setApplicationName(APPLICATION_NAME);
@ -52,8 +52,16 @@ Application::Application(int &argc, char **argv) : m_app(std::make_shared<QAppli
} }
} }
void Application::onNewEnrollResult(uint16_t userid) {
m_palmId = userid;
QTimer::singleShot(0, this, [this, userid]() {
emit newStatusTip(Info, QString("%1,录入成功,ID:%2").arg(m_palmUsername).arg(userid));
});
}
void Application::onNewVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed) { void Application::onNewVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed) {
m_palmUsername = username; m_palmUsername = username;
m_palmId = userid;
QTimer::singleShot(0, this, [this, userid, username, elapsed]() { QTimer::singleShot(0, this, [this, userid, username, elapsed]() {
emit newStatusTip(Info, QString("%1,识别耗时: %2ms") emit newStatusTip(Info, QString("%1,识别耗时: %2ms")
.arg(userid == ModuleCommunication::InvalidUserId ? "未录入用户" : username) .arg(userid == ModuleCommunication::InvalidUserId ? "未录入用户" : username)
@ -106,6 +114,7 @@ bool Application::open(const QString &portName, int baudRate) {
m_communication = std::make_shared<ModuleCommunication>(); m_communication = std::make_shared<ModuleCommunication>();
connect(m_communication.get(), &ModuleCommunication::commandStarted, this, &Application::onCommandStarted); connect(m_communication.get(), &ModuleCommunication::commandStarted, this, &Application::onCommandStarted);
connect(m_communication.get(), &ModuleCommunication::commandFinished, this, &Application::onCommandFinished); connect(m_communication.get(), &ModuleCommunication::commandFinished, this, &Application::onCommandFinished);
connect(m_communication.get(), &ModuleCommunication::newEnrollResult, this, &Application::onNewEnrollResult);
connect(m_communication.get(), &ModuleCommunication::newVerifyResult, this, &Application::onNewVerifyResult); connect(m_communication.get(), &ModuleCommunication::newVerifyResult, this, &Application::onNewVerifyResult);
connect(m_communication.get(), &ModuleCommunication::newPalmFeature, this, &Application::onNewPalmFeature); connect(m_communication.get(), &ModuleCommunication::newPalmFeature, this, &Application::onNewPalmFeature);
connect(m_communication.get(), &ModuleCommunication::newImageInfo, this, &Application::onNewImageInfo); connect(m_communication.get(), &ModuleCommunication::newImageInfo, this, &Application::onNewImageInfo);
@ -203,18 +212,27 @@ void Application::enrollExtended(const QString &username, bool persistence, uint
m_palmUsername = username; m_palmUsername = username;
} }
void Application::uploadImage() { void Application::uploadImage(const QString &path, int operation) {
m_uploadImageSendedSize = 0; m_uploadImageSendedSize = 0;
// std::ifstream ifs("palm.yuv", std::ofstream::binary); if (path.endsWith(".jpg")) {
// m_uploadBuffer = std::vector<char>((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); auto image = ImageDecoder::extractJpegYComponent(path.toStdString());
auto image = ImageDecoder::extractJpegYComponent("E:/Downloads/7207002051849490432.jpg"); if (!image) {
if (!image) { LOG(error) << "decode failed.";
LOG(error) << "decode failed."; return;
}
m_uploadBuffer = image->data;
LOG(info) << "width: " << image->width << ", height: " << image->height;
} else if (path.endsWith(".yuv")) {
std::ifstream ifs(Amass::StringUtility::UTF8ToGBK(path.toStdString()), std::ofstream::binary);
m_uploadBuffer = std::vector<uint8_t>((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
if (m_uploadBuffer.empty()) {
LOG(error) << "file is empty.";
}
} else {
LOG(error) << "not supported format.";
return; return;
} }
m_uploadBuffer = image->data;
LOG(info) << "width: " << image->width << ", height: " << image->height;
ModuleCommunication::UploadImageInformation request; ModuleCommunication::UploadImageInformation request;
mbedtls_md5_context context; mbedtls_md5_context context;
@ -224,7 +242,7 @@ void Application::uploadImage() {
mbedtls_md5_finish(&context, request.md5); mbedtls_md5_finish(&context, request.md5);
mbedtls_md5_free(&context); mbedtls_md5_free(&context);
request.operation = 0; request.operation = operation;
request.width = 600; request.width = 600;
request.height = 800; request.height = 800;
request.size = m_uploadBuffer.size(); request.size = m_uploadBuffer.size();
@ -319,17 +337,17 @@ void Application::onNewImageSliceData(const std::vector<uint8_t> &data) {
if (m_palmImageId == ModuleCommunication::Note) { if (m_palmImageId == ModuleCommunication::Note) {
way = "no_alive"; way = "no_alive";
} }
LOG(info) << "request finished, username: " << username LOG(info) << "request image finished, username: " << username << ", userid: " << m_palmId
<< ", elapsed: " << duration_cast<milliseconds>(system_clock::now() - m_startUploadTime); << ", elapsed: " << duration_cast<milliseconds>(system_clock::now() - m_startUploadTime);
std::ostringstream oss; std::ostringstream oss;
oss << YuvPath << "/" << username << "_" << way << "_" oss << YuvPath << "/" << username << "_" << m_palmId << "_" << way << "_"
<< DateTime::toString(std::chrono::system_clock::now(), "%Y%m%d%H%M%S") << ".yuv"; << DateTime::toString(std::chrono::system_clock::now(), "%Y%m%d%H%M%S") << ".yuv";
std::ofstream ofs(Amass::StringUtility::UTF8ToGBK(oss.str()), std::ofstream::binary); std::ofstream ofs(Amass::StringUtility::UTF8ToGBK(oss.str()), std::ofstream::binary);
ofs.write(m_palmYImageBuffer.data(), m_palmYImageBuffer.size()); ofs.write(m_palmYImageBuffer.data(), m_palmYImageBuffer.size());
QImage image(reinterpret_cast<const uint8_t *>(m_palmYImageBuffer.data()), 600, 800, QImage::Format_Grayscale8); QImage image(reinterpret_cast<const uint8_t *>(m_palmYImageBuffer.data()), 600, 800, QImage::Format_Grayscale8);
oss.str(""); oss.str("");
oss << JpgPath << "/" << username << "_" << way << "_" oss << JpgPath << "/" << username << "_" << m_palmId << "_" << way << "_"
<< DateTime::toString(std::chrono::system_clock::now(), "%Y%m%d%H%M%S") << ".jpg"; << DateTime::toString(std::chrono::system_clock::now(), "%Y%m%d%H%M%S") << ".jpg";
image.save(QString::fromStdString(oss.str()), "jpg", 100); image.save(QString::fromStdString(oss.str()), "jpg", 100);
} }

View File

@ -51,7 +51,7 @@ public:
Q_INVOKABLE void enrollExtended(const QString &username, bool persistence, uint8_t timeout); Q_INVOKABLE void enrollExtended(const QString &username, bool persistence, uint8_t timeout);
Q_INVOKABLE void deleteUser(uint16_t userid); Q_INVOKABLE void deleteUser(uint16_t userid);
Q_INVOKABLE void deleteAll(); Q_INVOKABLE void deleteAll();
Q_INVOKABLE void uploadImage(); Q_INVOKABLE void uploadImage(const QString &path, int operation);
ModuleCommunication *module() const; ModuleCommunication *module() const;
bool connected() const; bool connected() const;
bool uvcOpened() const; bool uvcOpened() const;
@ -77,6 +77,7 @@ signals:
protected: protected:
Application(int &argc, char **argv); Application(int &argc, char **argv);
void onNewEnrollResult(uint16_t userid);
void onNewVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed); void onNewVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed);
void onNewPalmFeature(const PalmFeature &feature); void onNewPalmFeature(const PalmFeature &feature);
void onErrorOccurred(const QString &error); void onErrorOccurred(const QString &error);
@ -103,6 +104,7 @@ private:
ModuleCommunication::MessageId m_palmImageId; // 通过哪个指令获取的图片 ModuleCommunication::MessageId m_palmImageId; // 通过哪个指令获取的图片
uint32_t m_palmImageSize = 0; uint32_t m_palmImageSize = 0;
QString m_palmUsername; QString m_palmUsername;
uint16_t m_palmId = ModuleCommunication::InvalidUserId;
QByteArray m_palmYImageBuffer; QByteArray m_palmYImageBuffer;
std::chrono::system_clock::time_point m_startUploadTime; std::chrono::system_clock::time_point m_startUploadTime;

View File

@ -229,28 +229,26 @@ void ModuleCommunication::processPackage(const uint8_t *data, uint16_t size) {
LOG_CAT(info, GUI) << Separator; LOG_CAT(info, GUI) << Separator;
break; break;
} }
case EnrollSingle: { case EnrollSingle:
LOG_CAT(info, GUI) << "模组: " << protocolDataFormatString(data, size);
if (result == Success) {
auto info = reinterpret_cast<const EnrollDataReply *>(data + 7);
LOG_CAT(info, GUI) << "注册成功,用户ID: " << ntohs(info->userid);
} else if (result == Failed4Timeout) {
LOG_CAT(info, GUI) << "识别超时。";
} else {
LOG_CAT(info, GUI) << "未知错误(" << static_cast<int>(result) << ")。";
}
LOG_CAT(info, GUI) << Separator;
break;
}
case EnrollExtended: { case EnrollExtended: {
LOG_CAT(info, GUI) << "模组: " << protocolDataFormatString(data, size); LOG_CAT(info, GUI) << "模组: " << protocolDataFormatString(data, size);
if (result == Success) { if (result == Success) {
auto info = reinterpret_cast<const EnrollExtendedReply *>(data + 7); uint16_t userId = InvalidUserId;
uint16_t width = ntohs(info->image_width); if (replyId == EnrollExtended) {
uint16_t height = ntohs(info->image_height); auto info = reinterpret_cast<const EnrollExtendedReply *>(data + 7);
LOG_CAT(info, GUI) << "注册成功,用户ID: " << ntohs(info->userid) << ", 图片大小: " << width << "x" uint16_t width = ntohs(info->image_width);
<< height; uint16_t height = ntohs(info->image_height);
emit newImageInfo(static_cast<MessageId>(replyId), width * height, info->md5); userId = ntohs(info->userid);
LOG_CAT(info, GUI) << "注册成功,用户ID: " << userId << ", 图片大小: " << width << "x" << height;
emit newImageInfo(static_cast<MessageId>(replyId), width * height, info->md5);
} else {
auto info = reinterpret_cast<const EnrollDataReply *>(data + 7);
userId = ntohs(info->userid);
LOG_CAT(info, GUI) << "注册成功,用户ID: " << userId;
}
emit newEnrollResult(userId);
} else if (result == Failed4Timeout) {
LOG_CAT(info, GUI) << "识别超时。";
} else { } else {
LOG_CAT(info, GUI) << "未知错误(" << static_cast<int>(result) << ")。"; LOG_CAT(info, GUI) << "未知错误(" << static_cast<int>(result) << ")。";
} }

View File

@ -175,6 +175,7 @@ signals:
* @param elapsed ms毫秒 * @param elapsed ms毫秒
*/ */
void newVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed); void newVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed);
void newEnrollResult(uint16_t userid);
void newPalmFeature(const PalmFeature &feature); void newPalmFeature(const PalmFeature &feature);
void newImageInfo(MessageId id, uint32_t size, const uint8_t *md5); void newImageInfo(MessageId id, uint32_t size, const uint8_t *md5);
void newImageSliceData(const std::vector<uint8_t> &data); void newImageSliceData(const std::vector<uint8_t> &data);

View File

@ -1,5 +1,7 @@
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Dialogs
import QtQuick.Layouts import QtQuick.Layouts
import Analyser import Analyser
@ -141,10 +143,23 @@ ColumnLayout {
GroupBox { GroupBox {
title: "图片注册" title: "图片注册"
GridLayout { GridLayout {
columns: 1 columns: 2
TextField {
id: imagePath
Layout.columnSpan: 2
implicitWidth: 180
placeholderText: "请选择图片"
onPressed: {
fileDialog.open()
}
}
Button { Button {
text: "图片下发注册" text: "注册"
onClicked: App.uploadImage() onClicked: App.uploadImage(imagePath.text, 0)
}
Button {
text: "识别"
onClicked: App.uploadImage(imagePath.text, 1)
} }
} }
} }
@ -176,15 +191,28 @@ ColumnLayout {
} }
} }
FileDialog {
id: fileDialog
nameFilters: ["图片 (*.jpg *.yuv)"]
currentFolder: StandardPaths.standardLocations(
StandardPaths.DesktopLocation)[0]
onAccepted: {
var fileUrl = fileDialog.selectedFile.toString()
var localFilePath = fileUrl.startsWith(
"file:///") ? fileUrl.substring(8) : fileUrl
imagePath.text = localFilePath
}
}
Loader { Loader {
id: loader id: loader
source: "OtaPage.qml" source: "OtaPage.qml"
active: false active: false
onLoaded: { onLoaded: {
if (loader.item && loader.item.open) { if (loader.item && loader.item.open) {
loader.item.open(); loader.item.open()
loader.item.onClose = ()=>{ loader.item.onClose = () => {
loader.active= false loader.active = false
} }
} }
} }

View File

@ -88,7 +88,8 @@ void CdcUpdater::timerEvent(QTimerEvent *event) {
const auto serialPortInfos = QSerialPortInfo::availablePorts(); const auto serialPortInfos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &portInfo : serialPortInfos) { for (const QSerialPortInfo &portInfo : serialPortInfos) {
LOG(info) << "portName:" << portInfo.portName().toStdString() LOG(info) << "portName:" << portInfo.portName().toStdString()
<< ", vendorIdentifier: " << portInfo.vendorIdentifier(); << ", vendorIdentifier: " << portInfo.vendorIdentifier()
<< ", productIdentifier: " << portInfo.productIdentifier();
if (portInfo.vendorIdentifier() == 0xffff) { if (portInfo.vendorIdentifier() == 0xffff) {
LOG(info) << "founded device: " << portInfo.portName().toStdString(); LOG(info) << "founded device: " << portInfo.portName().toStdString();
emit deviceDiscovered(portInfo); emit deviceDiscovered(portInfo);