Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions cloud_labeler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,3 +705,56 @@ void CloudAutoLabeler::fetchBatchResults(int idx, int retryCount)
fetchBatchResults(idx + 1);
});
}

// ── Landing AI response parser ───────────────────────────────────────────────

QStringList CloudAutoLabeler::parseLandingAIDetections(const QJsonArray &detections,
const QStringList &objList,
double imgW, double imgH,
QStringList *skipped)
{
QStringList outputLines;
for (const QJsonValue &v : detections) {
if (!v.isObject()) continue;
QJsonObject obj = v.toObject();
QString label = obj.value("label").toString();

int classId = objList.indexOf(label);
if (classId < 0) {
// Case-insensitive fallback
for (int i = 0; i < objList.size(); ++i) {
if (objList[i].compare(label, Qt::CaseInsensitive) == 0) {
classId = i; break;
}
}
}
if (classId < 0) {
if (skipped && !label.isEmpty() && !skipped->contains(label))
*skipped << label;
continue;
}

QJsonArray bb = obj.value("bounding_box").toArray();
if (bb.size() < 4) continue;
if (!bb[0].isDouble() || !bb[1].isDouble() ||
!bb[2].isDouble() || !bb[3].isDouble()) continue;
double x1 = bb[0].toDouble(), y1 = bb[1].toDouble();
double x2 = bb[2].toDouble(), y2 = bb[3].toDouble();

double cx = ((x1 + x2) / 2.0) / imgW;
double cy = ((y1 + y2) / 2.0) / imgH;
double nw = (x2 - x1) / imgW;
double nh = (y2 - y1) / imgH;

if (cx < 0.0 || cx > 1.0 || cy < 0.0 || cy > 1.0 ||
nw <= 0.0 || nw > 1.0 || nh <= 0.0 || nh > 1.0) continue;

outputLines << QString("%1 %2 %3 %4 %5")
.arg(classId)
.arg(QString::number(cx, 'f', 6))
.arg(QString::number(cy, 'f', 6))
.arg(QString::number(nw, 'f', 6))
.arg(QString::number(nh, 'f', 6));
}
return outputLines;
}
12 changes: 10 additions & 2 deletions cloud_labeler.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ class CloudAutoLabeler : public QObject
void labelImages(const QStringList &imagePaths); // batch (all images)
void cancel();

// Utilities used by MainWindow
static QString mimeForImage(const QString &path);
static void backupLabelFile(const QString &labelPath);
// Parse a Landing AI detections JSON array into YOLO annotation lines.
// Pure function — no network or file I/O; used by MainWindow and unit tests.
static QStringList parseLandingAIDetections(const QJsonArray &detections,
const QStringList &objList,
double imgW, double imgH,
QStringList *skipped = nullptr);

signals:
// Emitted when a label file has been written for one image.
void labelReady(const QString &imagePath, int nDetections, int computeMs);
Expand Down Expand Up @@ -69,8 +79,6 @@ class CloudAutoLabeler : public QObject
void processNextInQueue();
void handleFatalError(const QString &message);

static QString mimeForImage(const QString &path);
static void backupLabelFile(const QString &labelPath);
static QString labelPathFor(const QString &imagePath);
static QString filterValidDetections(const QString &yoloTxt, int numClasses);
static QString remapWithClassNames(const QString &yoloTxt,
Expand Down
Loading