修改结果显示和存储结果
This commit is contained in:
parent
d3e6b4d0f3
commit
4004807396
@ -17,6 +17,8 @@ struct CtrlDetectionBox
|
||||
int y{0};
|
||||
int width{0};
|
||||
int height{0};
|
||||
bool hasPhysicalHeight{false};
|
||||
float physicalHeightMm{0.0f};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -758,6 +758,8 @@ CtrlDetectionFrame DroneScrewCtrlPresenter::toCtrlFrame(const WDRemoteDetectionF
|
||||
cb.y = b.y;
|
||||
cb.width = b.width;
|
||||
cb.height = b.height;
|
||||
cb.hasPhysicalHeight = b.hasPhysicalHeight;
|
||||
cb.physicalHeightMm = b.physicalHeightMm;
|
||||
frame.boxes.push_back(cb);
|
||||
}
|
||||
frame.distances.reserve(f.distances.size());
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
|
||||
#define DRONESCREWCTRL_APP_NAME "无人机螺杆控制端"
|
||||
#define DRONESCREWCTRL_VERSION_STRING "1.0.0"
|
||||
#define DRONESCREWCTRL_BUILD_STRING "3"
|
||||
#define DRONESCREWCTRL_FULL_VERSION_STRING "V1.0.0_3"
|
||||
#define DRONESCREWCTRL_BUILD_STRING "4"
|
||||
#define DRONESCREWCTRL_FULL_VERSION_STRING "V1.0.0_4"
|
||||
|
||||
inline const char* GetDroneScrewCtrlFullVersion() { return DRONESCREWCTRL_FULL_VERSION_STRING; }
|
||||
|
||||
|
||||
@ -355,7 +355,7 @@ void MainWindow::OnDetectionResult(const CtrlDetectionFrame& result)
|
||||
upsertResultItem(row++, head, static_cast<int>(i), ResultItem::DisplayMode::Distance);
|
||||
}
|
||||
}
|
||||
else if (result.boxes.empty())
|
||||
else if (result.boxes.empty() && result.distances.empty())
|
||||
{
|
||||
const QString head = QStringLiteral("帧#%1 精准目标 0")
|
||||
.arg(result.frameId);
|
||||
@ -371,6 +371,14 @@ void MainWindow::OnDetectionResult(const CtrlDetectionFrame& result)
|
||||
.arg(static_cast<int>(result.boxes.size()));
|
||||
upsertResultItem(row++, head, static_cast<int>(i), ResultItem::DisplayMode::Precision);
|
||||
}
|
||||
for (size_t i = 0; i < result.distances.size(); ++i)
|
||||
{
|
||||
const QString head = QStringLiteral("帧#%1 杆间距 %2/%3")
|
||||
.arg(result.frameId)
|
||||
.arg(static_cast<int>(i + 1))
|
||||
.arg(static_cast<int>(result.distances.size()));
|
||||
upsertResultItem(row++, head, static_cast<int>(i), ResultItem::DisplayMode::PrecisionDistance);
|
||||
}
|
||||
}
|
||||
|
||||
trimResultItems(row);
|
||||
|
||||
@ -37,6 +37,11 @@ QString oneDistanceText(const CtrlDetectionDistance& d)
|
||||
return QStringLiteral("%1m").arg(meters, 0, 'f', 3);
|
||||
}
|
||||
|
||||
QString oneDistanceMmText(const CtrlDetectionDistance& d)
|
||||
{
|
||||
return QStringLiteral("%1 mm").arg(d.distanceMm, 0, 'f', 2);
|
||||
}
|
||||
|
||||
QString distanceText(const CtrlDetectionFrame& frame, int targetIndex)
|
||||
{
|
||||
if (targetIndex >= 0 && targetIndex < static_cast<int>(frame.distances.size()))
|
||||
@ -50,6 +55,19 @@ QString distanceText(const CtrlDetectionFrame& frame, int targetIndex)
|
||||
: distanceParts.join(" ");
|
||||
}
|
||||
|
||||
QString distanceMmText(const CtrlDetectionFrame& frame, int targetIndex)
|
||||
{
|
||||
if (targetIndex >= 0 && targetIndex < static_cast<int>(frame.distances.size()))
|
||||
return oneDistanceMmText(frame.distances[static_cast<size_t>(targetIndex)]);
|
||||
|
||||
QStringList distanceParts;
|
||||
for (size_t i = 0; i < frame.distances.size(); ++i)
|
||||
distanceParts << oneDistanceMmText(frame.distances[i]);
|
||||
return distanceParts.isEmpty()
|
||||
? QStringLiteral("未测到距离")
|
||||
: distanceParts.join(" ");
|
||||
}
|
||||
|
||||
QString distanceIndexText(const CtrlDetectionFrame& frame, int targetIndex)
|
||||
{
|
||||
const int total = static_cast<int>(frame.distances.size());
|
||||
@ -60,6 +78,22 @@ QString distanceIndexText(const CtrlDetectionFrame& frame, int targetIndex)
|
||||
}
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
|
||||
QString precisionDistanceIndexText(const CtrlDetectionFrame& frame, int targetIndex)
|
||||
{
|
||||
const int total = static_cast<int>(frame.distances.size());
|
||||
if (targetIndex >= 0 && targetIndex < total)
|
||||
{
|
||||
const CtrlDetectionDistance& d = frame.distances[static_cast<size_t>(targetIndex)];
|
||||
if (d.fromId >= 0 && d.toId >= 0)
|
||||
return QStringLiteral("%1-%2").arg(d.fromId + 1).arg(d.toId + 1);
|
||||
if (d.fromId >= 0)
|
||||
return QString::number(d.fromId + 1);
|
||||
if (d.toId >= 0)
|
||||
return QString::number(d.toId + 1);
|
||||
}
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
|
||||
ResultItem::ResultItem(QWidget* parent)
|
||||
@ -110,15 +144,23 @@ void ResultItem::setResultData(int targetIndex,
|
||||
DisplayMode mode)
|
||||
{
|
||||
const bool precisionMode = (mode == DisplayMode::Precision);
|
||||
const bool precisionDistanceMode = (mode == DisplayMode::PrecisionDistance);
|
||||
setResultTextStyle(ui);
|
||||
setMinimumHeight(precisionMode ? 104 : 108);
|
||||
setMinimumHeight((precisionMode || precisionDistanceMode) ? 104 : 108);
|
||||
|
||||
if (ui->lb_id_t)
|
||||
ui->lb_id_t->setText(QStringLiteral("ID"));
|
||||
if (ui->lb_status_t)
|
||||
ui->lb_status_t->setText(mode == DisplayMode::Distance
|
||||
? QStringLiteral("距离")
|
||||
: QStringLiteral("状态"));
|
||||
{
|
||||
if (mode == DisplayMode::Distance)
|
||||
ui->lb_status_t->setText(QStringLiteral("距离"));
|
||||
else if (precisionDistanceMode)
|
||||
ui->lb_status_t->setText(QStringLiteral("杆间距"));
|
||||
else if (precisionMode)
|
||||
ui->lb_status_t->setText(QStringLiteral("物理高度"));
|
||||
else
|
||||
ui->lb_status_t->setText(QStringLiteral("状态"));
|
||||
}
|
||||
|
||||
if (ui->label_id)
|
||||
{
|
||||
@ -126,6 +168,10 @@ void ResultItem::setResultData(int targetIndex,
|
||||
ui->label_id->setText(QString("%1/%2")
|
||||
.arg(targetIndex + 1)
|
||||
.arg(static_cast<int>(frame.boxes.size())));
|
||||
else if (precisionDistanceMode)
|
||||
{
|
||||
ui->label_id->setText(precisionDistanceIndexText(frame, targetIndex));
|
||||
}
|
||||
else if (mode == DisplayMode::Distance)
|
||||
{
|
||||
ui->label_id->setText(distanceIndexText(frame, targetIndex));
|
||||
@ -134,10 +180,16 @@ void ResultItem::setResultData(int targetIndex,
|
||||
ui->label_id->setText(QStringLiteral("0/0"));
|
||||
}
|
||||
|
||||
if (mode == DisplayMode::Distance)
|
||||
if (mode == DisplayMode::Distance || precisionDistanceMode)
|
||||
{
|
||||
if (ui->label_status)
|
||||
ui->label_status->setText(frame.success ? distanceText(frame, targetIndex) : failedText(frame));
|
||||
{
|
||||
ui->label_status->setText(frame.success
|
||||
? (precisionDistanceMode
|
||||
? distanceMmText(frame, targetIndex)
|
||||
: distanceText(frame, targetIndex))
|
||||
: failedText(frame));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,11 +198,19 @@ void ResultItem::setResultData(int targetIndex,
|
||||
if (targetIndex >= 0 && targetIndex < static_cast<int>(frame.boxes.size()))
|
||||
{
|
||||
const CtrlDetectionBox& b = frame.boxes[static_cast<size_t>(targetIndex)];
|
||||
const QString text = QStringLiteral("score=%1 w=%2 h=%3")
|
||||
.arg(b.score, 0, 'f', 3)
|
||||
.arg(b.width)
|
||||
.arg(b.height);
|
||||
ui->label_status->setText(text);
|
||||
if (b.hasPhysicalHeight)
|
||||
{
|
||||
ui->label_status->setText(QStringLiteral("%1 mm")
|
||||
.arg(b.physicalHeightMm, 0, 'f', 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString text = QStringLiteral("score=%1 w=%2 h=%3")
|
||||
.arg(b.score, 0, 'f', 3)
|
||||
.arg(b.width)
|
||||
.arg(b.height);
|
||||
ui->label_status->setText(text);
|
||||
}
|
||||
}
|
||||
else if (!frame.success)
|
||||
{
|
||||
|
||||
@ -14,7 +14,8 @@ public:
|
||||
enum class DisplayMode
|
||||
{
|
||||
Distance,
|
||||
Precision
|
||||
Precision,
|
||||
PrecisionDistance
|
||||
};
|
||||
|
||||
explicit ResultItem(QWidget* parent = nullptr);
|
||||
|
||||
@ -700,6 +700,18 @@ void DroneScrewAlgoStub::appendRoiBox(const StereoBoltModuleRoiC& roi,
|
||||
result.boxes.push_back(box);
|
||||
}
|
||||
|
||||
void DroneScrewAlgoStub::appendBoltBox(const StereoBoltModuleBoltC& bolt,
|
||||
DroneScrewResult& result) const
|
||||
{
|
||||
DroneScrewBox box;
|
||||
if (mapRectifiedLeftRoi(bolt.left_roi, result.imageWidth, result.imageHeight, box))
|
||||
{
|
||||
box.hasPhysicalHeight = true;
|
||||
box.physicalHeightMm = static_cast<float>(bolt.height_mm);
|
||||
result.boxes.push_back(box);
|
||||
}
|
||||
}
|
||||
|
||||
int DroneScrewAlgoStub::Init(const DroneScrewAlgoParams& params)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_mutex);
|
||||
@ -899,7 +911,7 @@ int DroneScrewAlgoStub::Detect(const DroneScrewInputImage& leftImage,
|
||||
if (out.data.n_bolts > 0 && out.data.bolts)
|
||||
{
|
||||
for (int i = 0; i < out.data.n_bolts; ++i)
|
||||
appendRoiBox(out.data.bolts[i].left_roi, result);
|
||||
appendBoltBox(out.data.bolts[i], result);
|
||||
}
|
||||
if (out.data.n_adjacent_distances > 0 && out.data.adjacent_distances)
|
||||
{
|
||||
|
||||
@ -47,6 +47,8 @@ private:
|
||||
DroneScrewBox& box) const;
|
||||
void appendRoiBox(const StereoBoltModuleRoiC& roi,
|
||||
DroneScrewResult& result) const;
|
||||
void appendBoltBox(const StereoBoltModuleBoltC& bolt,
|
||||
DroneScrewResult& result) const;
|
||||
#endif
|
||||
|
||||
DroneScrewAlgoParams m_params;
|
||||
|
||||
@ -16,6 +16,8 @@ struct DroneScrewBox
|
||||
int y{0};
|
||||
int width{0};
|
||||
int height{0};
|
||||
bool hasPhysicalHeight{false};
|
||||
float physicalHeightMm{0.0f};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -69,7 +69,6 @@ constexpr int kDetectPipelineDistance = 1;
|
||||
constexpr const char* kImageSaveRootDir = "/home/cat";
|
||||
constexpr size_t kMaxImageSaveQueueDepth = 100;
|
||||
constexpr size_t kImageSaveWorkerCount = 4;
|
||||
constexpr int kDistanceImageSaveStride = 3;
|
||||
|
||||
const char* mvsSdkErrorName(int code)
|
||||
{
|
||||
@ -253,6 +252,70 @@ void logDetectionResultFixed(const char* tag, int frameNo, const DroneScrewResul
|
||||
}
|
||||
}
|
||||
|
||||
QString savedImageFileName(unsigned long long index, const QString& prefix)
|
||||
{
|
||||
return QStringLiteral("%1_%2Image.png").arg(index).arg(prefix);
|
||||
}
|
||||
|
||||
bool saveDetectionResultText(const QString& dirPath,
|
||||
unsigned long long imageIndex,
|
||||
const DroneScrewResult& result)
|
||||
{
|
||||
const QString filePath = QDir(dirPath).filePath(
|
||||
QStringLiteral("%1_result.txt").arg(imageIndex));
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
|
||||
{
|
||||
LOG_WARN("[SAVE] result save open failed: %s\n",
|
||||
filePath.toStdString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
out << "index:" << static_cast<qulonglong>(imageIndex) << '\n';
|
||||
out << "leftImage:" << savedImageFileName(imageIndex, QStringLiteral("left")) << '\n';
|
||||
out << "rightImage:" << savedImageFileName(imageIndex, QStringLiteral("right")) << '\n';
|
||||
out << "frameId:" << static_cast<qulonglong>(result.frameId) << '\n';
|
||||
out << "timestampUs:" << static_cast<qlonglong>(result.timestampUs) << '\n';
|
||||
out << "success:" << (result.success ? 1 : 0) << '\n';
|
||||
out << "errorCode:" << result.errorCode << '\n';
|
||||
out << "message:" << QString::fromStdString(result.message) << '\n';
|
||||
|
||||
int physicalHeightCount = 0;
|
||||
for (const auto& b : result.boxes)
|
||||
{
|
||||
if (b.hasPhysicalHeight)
|
||||
++physicalHeightCount;
|
||||
}
|
||||
out << "physicalHeightCount:" << physicalHeightCount << '\n';
|
||||
int physicalHeightIndex = 1;
|
||||
for (const auto& b : result.boxes)
|
||||
{
|
||||
if (!b.hasPhysicalHeight)
|
||||
continue;
|
||||
out << "physicalHeight" << physicalHeightIndex << "Id:" << physicalHeightIndex << '\n';
|
||||
out << "physicalHeight" << physicalHeightIndex << "Mm:"
|
||||
<< QString::number(b.physicalHeightMm, 'f', 3) << '\n';
|
||||
++physicalHeightIndex;
|
||||
}
|
||||
|
||||
out << "rodSpacingCount:" << static_cast<int>(result.distances.size()) << '\n';
|
||||
for (size_t i = 0; i < result.distances.size(); ++i)
|
||||
{
|
||||
const auto& d = result.distances[i];
|
||||
const int index = static_cast<int>(i + 1);
|
||||
out << "rodSpacing" << index << "FromId:" << (d.fromId + 1) << '\n';
|
||||
out << "rodSpacing" << index << "ToId:" << (d.toId + 1) << '\n';
|
||||
out << "rodSpacing" << index << "Mm:"
|
||||
<< QString::number(d.distanceMm, 'f', 3) << '\n';
|
||||
}
|
||||
out.flush();
|
||||
if (out.status() != QTextStream::Ok)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double clampCameraFloatFeature(IMvsDevice* camera,
|
||||
const char* role,
|
||||
const char* featureName,
|
||||
@ -1814,9 +1877,9 @@ int DroneScrewServerPresenter::stopDetectionWork()
|
||||
|
||||
stopGpioTriggerLoop();
|
||||
m_bThreadExit = true;
|
||||
stopImageSaveThread();
|
||||
if (m_detectThread.joinable())
|
||||
m_detectThread.join();
|
||||
stopImageSaveThread();
|
||||
m_bIsDetecting = false;
|
||||
m_detectPipelineMode = kDetectPipelinePrecision;
|
||||
m_activeTriggerFps = static_cast<int>(kPrecisionFrameRate);
|
||||
@ -1909,7 +1972,6 @@ int DroneScrewServerPresenter::startLiveStream()
|
||||
m_bLiveStreaming = true;
|
||||
m_bThreadExit = false;
|
||||
m_bIsDetecting = true;
|
||||
startImageSaveThread(imageSaveModeName());
|
||||
startGpioTriggerLoop();
|
||||
m_detectThread = std::thread(&DroneScrewServerPresenter::detectThreadFunc, this);
|
||||
emit statusChanged(QStringLiteral("开始实时传图"));
|
||||
@ -1935,9 +1997,9 @@ int DroneScrewServerPresenter::stopLiveStream()
|
||||
m_bRtspStarted = false;
|
||||
stopGpioTriggerLoop();
|
||||
m_bThreadExit = true;
|
||||
stopImageSaveThread();
|
||||
if (m_detectThread.joinable())
|
||||
m_detectThread.join();
|
||||
stopImageSaveThread();
|
||||
m_bIsDetecting = false;
|
||||
m_detectPipelineMode = kDetectPipelinePrecision;
|
||||
m_activeTriggerFps = static_cast<int>(kPrecisionFrameRate);
|
||||
@ -2374,7 +2436,7 @@ void DroneScrewServerPresenter::startImageSaveThread(const QString& modeName)
|
||||
void DroneScrewServerPresenter::stopImageSaveThread()
|
||||
{
|
||||
const bool shouldJoin = !m_imageSaveThreads.empty();
|
||||
size_t droppedPending = 0;
|
||||
size_t pendingJobs = 0;
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_imageSaveMutex);
|
||||
if (!shouldJoin)
|
||||
@ -2384,16 +2446,14 @@ void DroneScrewServerPresenter::stopImageSaveThread()
|
||||
m_imageSaveThreadExit = false;
|
||||
return;
|
||||
}
|
||||
droppedPending = m_imageSaveQueue.size();
|
||||
if (droppedPending > 0)
|
||||
m_imageSaveQueue.clear();
|
||||
pendingJobs = m_imageSaveQueue.size();
|
||||
m_imageSaveThreadExit = true;
|
||||
}
|
||||
|
||||
if (droppedPending > 0)
|
||||
if (pendingJobs > 0)
|
||||
{
|
||||
LOG_WARN("[SAVE] stop requested, drop pending save jobs=%zu\n",
|
||||
droppedPending);
|
||||
LOG_INFO("[SAVE] stop requested, flush pending save jobs=%zu\n",
|
||||
pendingJobs);
|
||||
}
|
||||
|
||||
m_imageSaveCv.notify_all();
|
||||
@ -2414,6 +2474,7 @@ void DroneScrewServerPresenter::stopImageSaveThread()
|
||||
|
||||
void DroneScrewServerPresenter::enqueueImageSave(const MvsImageData& leftImg,
|
||||
const MvsImageData& rightImg,
|
||||
const DroneScrewResult& result,
|
||||
unsigned long long index)
|
||||
{
|
||||
auto dropIfQueueFull = [this, index]() -> bool {
|
||||
@ -2460,6 +2521,8 @@ void DroneScrewServerPresenter::enqueueImageSave(const MvsImageData& leftImg,
|
||||
|
||||
ImageSaveJob job;
|
||||
job.index = index;
|
||||
job.result = result;
|
||||
job.hasResult = true;
|
||||
if (!copyMono8(leftImg, job.left) || !copyMono8(rightImg, job.right))
|
||||
{
|
||||
LOG_WARN("[SAVE] skip image save: unsupported image pair index=%llu left=%ux%u pf=0x%x right=%ux%u pf=0x%x\n",
|
||||
@ -2494,14 +2557,10 @@ void DroneScrewServerPresenter::imageSaveThreadFunc(int workerIndex)
|
||||
return m_imageSaveThreadExit.load() || !m_imageSaveQueue.empty();
|
||||
});
|
||||
|
||||
if (m_imageSaveThreadExit.load())
|
||||
{
|
||||
m_imageSaveQueue.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_imageSaveQueue.empty())
|
||||
{
|
||||
if (m_imageSaveThreadExit.load())
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2523,7 +2582,7 @@ void DroneScrewServerPresenter::imageSaveThreadFunc(int workerIndex)
|
||||
static_cast<int>(img.width),
|
||||
QImage::Format_Grayscale8);
|
||||
const QString filePath = QDir(job.dirPath).filePath(
|
||||
QStringLiteral("%1_%2Image.png").arg(job.index).arg(prefix));
|
||||
savedImageFileName(job.index, prefix));
|
||||
if (!q.save(filePath, "PNG"))
|
||||
{
|
||||
LOG_WARN("[SAVE] image save failed: %s\n",
|
||||
@ -2532,9 +2591,9 @@ void DroneScrewServerPresenter::imageSaveThreadFunc(int workerIndex)
|
||||
};
|
||||
|
||||
saveMono8(job.left, QStringLiteral("left"));
|
||||
if (m_imageSaveThreadExit.load())
|
||||
break;
|
||||
saveMono8(job.right, QStringLiteral("right"));
|
||||
if (job.hasResult)
|
||||
saveDetectionResultText(job.dirPath, job.index, job.result);
|
||||
}
|
||||
LOG_DEBUG("[SAVE] worker #%d stopped\n", workerIndex);
|
||||
}
|
||||
@ -2908,12 +2967,6 @@ void DroneScrewServerPresenter::detectThreadFunc()
|
||||
haveProcessedFrame = true;
|
||||
lastProcessedLeftFrameId = leftImg.frameID;
|
||||
lastProcessedRightFrameId = rightImg.frameID;
|
||||
const bool distanceSaveMode =
|
||||
(m_detectPipelineMode.load() == kDetectPipelineDistance);
|
||||
const bool shouldSaveFrame =
|
||||
!distanceSaveMode || ((frameCnt % kDistanceImageSaveStride) == 0);
|
||||
if (shouldSaveFrame)
|
||||
enqueueImageSave(leftImg, rightImg, ++savedFrameCnt);
|
||||
|
||||
// Publish the display frame before detection work. detectMode only controls raw transport.
|
||||
if (m_bRawPubEnabled.load())
|
||||
@ -3138,6 +3191,9 @@ void DroneScrewServerPresenter::detectThreadFunc()
|
||||
result.success ? 1 : 0, result.errorCode,
|
||||
result.boxes.size(), result.distances.size());
|
||||
|
||||
if (!distanceMode)
|
||||
enqueueImageSave(leftImg, rightImg, result, ++savedFrameCnt);
|
||||
|
||||
emit detectionResult(result);
|
||||
|
||||
LOG_DEBUG("[DETECT] frame #%d after detectionResult emit\n", frameCnt + 1);
|
||||
|
||||
@ -239,6 +239,7 @@ private:
|
||||
void imageSaveThreadFunc(int workerIndex);
|
||||
void enqueueImageSave(const MvsImageData& leftImg,
|
||||
const MvsImageData& rightImg,
|
||||
const DroneScrewResult& result,
|
||||
unsigned long long index);
|
||||
QString imageSaveModeName() const;
|
||||
|
||||
@ -258,6 +259,8 @@ private:
|
||||
unsigned long long index{0};
|
||||
ImageSaveBuffer left;
|
||||
ImageSaveBuffer right;
|
||||
DroneScrewResult result;
|
||||
bool hasResult{false};
|
||||
};
|
||||
|
||||
// 双目相机设备
|
||||
|
||||
@ -163,6 +163,8 @@ void fillDetectionJson(const DroneScrewResult& result, QJsonObject& obj)
|
||||
jb["y"] = b.y;
|
||||
jb["w"] = b.width;
|
||||
jb["h"] = b.height;
|
||||
if (b.hasPhysicalHeight)
|
||||
jb["physicalHeightMm"] = static_cast<double>(b.physicalHeightMm);
|
||||
boxes.append(jb);
|
||||
}
|
||||
obj["boxes"] = boxes;
|
||||
|
||||
@ -8,6 +8,6 @@
|
||||
#define DRONESCREWSERVER_COMPANY_NAME "VisionTech"
|
||||
#define DRONESCREWSERVER_COPYRIGHT "Copyright (C) 2026"
|
||||
#define DRONESCREWSERVER_VERSION_STRING "1.0.0"
|
||||
#define DRONESCREWSERVER_VERSION_BUILD "3"
|
||||
#define DRONESCREWSERVER_VERSION_BUILD "4"
|
||||
|
||||
#endif // DRONESCREW_VERSION_H
|
||||
|
||||
@ -55,6 +55,8 @@ struct WDRemoteDetectionBox
|
||||
int y{0};
|
||||
int width{0};
|
||||
int height{0};
|
||||
bool hasPhysicalHeight{false};
|
||||
float physicalHeightMm{0.0f};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -1297,6 +1297,8 @@ bool WDRemoteReceiver::parseDetectionJson(const std::string& jsonStr,
|
||||
box.y = b.get("y", 0 ).asInt();
|
||||
box.width = b.get("w", 0 ).asInt();
|
||||
box.height = b.get("h", 0 ).asInt();
|
||||
box.hasPhysicalHeight = b.isMember("physicalHeightMm");
|
||||
box.physicalHeightMm = static_cast<float>(b.get("physicalHeightMm", 0.0).asDouble());
|
||||
outFrame.boxes.push_back(box);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user