diff --git a/openbr/core/evalutils.cpp b/openbr/core/evalutils.cpp index 7fe401e..90d18f9 100644 --- a/openbr/core/evalutils.cpp +++ b/openbr/core/evalutils.cpp @@ -263,7 +263,7 @@ QStringList EvalUtils::computeDetectionResults(const QList &d debug << QString("|") << QString::number(FAR, 'f', 4).leftJustified(10, ' '); debug << QString("|") << QString::number(TP / totalTrueDetections, 'f', 4).leftJustified(10, ' '); debug << QString("|") << QString::number(detection.confidence, 'f', 4).leftJustified(10, ' '); - debug << QString("|") << QString::number(poseMatch / TP, 'f', 4).leftJustified(10, ' '); + debug << QString("|") << QString::number(TP ? poseMatch / TP : 0., 'f', 4).leftJustified(10, ' '); debug << QString("|") << endl; break; } diff --git a/openbr/core/qtutils.cpp b/openbr/core/qtutils.cpp index 15bef1f..5941aae 100644 --- a/openbr/core/qtutils.cpp +++ b/openbr/core/qtutils.cpp @@ -172,12 +172,20 @@ QString find(const QString &file, const QString &alt) return ""; } -bool toBool(const QString &string) +bool toBool(const QString &string, bool *ok) { - bool ok; - bool result = (string.toFloat(&ok) != 0.f); - if (ok) return result; - else return (string != "FALSE") && (string != "false") && (string != "F") && (string != "f"); + bool floatOk; + bool result = (string.toFloat(&floatOk) != 0.f); + if (floatOk) { + if (ok) *ok = true; + return result; + } else { + if (ok) *ok = (string.compare("false", Qt::CaseInsensitive) == 0 || + string.compare("true", Qt::CaseInsensitive) == 0 || + string.compare("f", Qt::CaseInsensitive) == 0 || + string.compare("t", Qt::CaseInsensitive) == 0); + return (string.compare("false", Qt::CaseInsensitive) != 0 && string.compare("f", Qt::CaseInsensitive) != 0); + } } int toInt(const QString &string) @@ -245,10 +253,10 @@ QStringList parse(QString args, char split, bool *ok) QStack subexpressions; for (int i=0; i toFloats(const QStringList &strings); diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index bc263e3..7ccefdd 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -156,30 +156,12 @@ QVariant File::value(const QString &key) const QVariant File::parse(const QString &value) { - bool ok = false; - const QPointF point = QtUtils::toPoint(value, &ok); - if (ok) return point; - const QRectF rect = QtUtils::toRect(value, &ok); - if (ok) return rect; - const cv::RotatedRect rotatedRect = OpenCVUtils::rotateRectFromString(value, &ok); - if (ok) return QVariant::fromValue(rotatedRect); - const int i = value.toInt(&ok); - if (ok) return i; - const float f = value.toFloat(&ok); - if (ok) return f; - return value; + return QtUtils::fromString(value); } void File::set(const QString &key, const QString &value) { - if (value.startsWith('[') && value.endsWith(']')) { - QVariantList variants; - foreach (const QString &value, QtUtils::parse(value.mid(1, value.size()-2))) - variants.append(parse(value)); - set(key, variants); - } else { - set(key, QVariant(parse(value))); - } + set(key, QtUtils::fromString(value)); } bool File::getBool(const QString &key, bool defaultValue) const diff --git a/openbr/plugins/gallery/csv.cpp b/openbr/plugins/gallery/csv.cpp index eef367b..efdfcac 100644 --- a/openbr/plugins/gallery/csv.cpp +++ b/openbr/plugins/gallery/csv.cpp @@ -16,10 +16,101 @@ #include #include +#include namespace br { +struct CSVHeader +{ + QList indices; + + CSVHeader() + {} + + CSVHeader(const QString &key) + : key(key) + {} + + QString key; + QStringList subKeys; +}; + +class CSVHeaderList : public QList +{ +public: + CSVHeaderList() + {} + + CSVHeaderList(const QList &headers) + { + foreach (const CSVHeader &header, headers) + append(header); + } + + CSVHeaderList(const QStringList &keys) + { + foreach (const QString &key, keys) + append(CSVHeader(key)); + } + + void sort() + { + typedef QPair IndexPair; + QList sortedKeys = Common::Sort(keys()); + + CSVHeaderList sortedList; + foreach (const IndexPair sortedKey, sortedKeys) + sortedList.append((*this)[sortedKey.second]); + *this = sortedList; + } + + QStringList keys() const + { + QStringList keys; + for (int i=0; isize(); i++) + keys.append((*this)[i].key); + return keys; + } + + static CSVHeaderList fromHeaders(const QStringList &headers) + { + CSVHeaderList csvHeaders; + QStringList processedKeys; + + for (int i=0; i() || !value.toString().isEmpty()) + f.set(header.key, values[header.indices.first()]); + } + } else if (header.indices.size() == 2) { // QPointF + const QPointF point(values[header.indices[header.subKeys.indexOf("X")]].toFloat(), + values[header.indices[header.subKeys.indexOf("Y")]].toFloat()); + f.set(header.key, point); + f.appendPoint(point); + } else if (header.indices.size() == 4) { // QRectF + const QRectF rect(values[header.indices[header.subKeys.indexOf("X")]].toFloat(), + values[header.indices[header.subKeys.indexOf("Y")]].toFloat(), + values[header.indices[header.subKeys.indexOf("Width")]].toFloat(), + values[header.indices[header.subKeys.indexOf("Height")]].toFloat()); + f.set(header.key, rect); + f.appendRect(rect); + } + } + } + TemplateList readBlock(bool *done) { readOpen(); @@ -79,22 +203,41 @@ class csvGallery : public FileGallery QByteArray lineBytes = f.readLine(); QString line = QString::fromLocal8Bit(lineBytes).trimmed(); QRegExp regexp("\\s*,\\s*"); - headers = line.split(regexp); + headers = CSVHeaderList::fromHeaders(line.split(regexp).mid(1)); } - for (qint64 i = 0; i < this->readBlockSize && !f.atEnd(); i++) { - const QVariantList values = parseLine(f.readLine()); - if (values.size() != headers.size()) continue; + if (combineFiles) { + *done = true; + QMap combinedFiles; + + while (!f.atEnd()) { + QVariantList values; + foreach (const QString &value, QtUtils::parse(f.readLine(), ',')) + values.append(QtUtils::fromString(value)); - File in; - for (int j=0; jreadBlockSize && !f.atEnd(); i++) { + QVariantList values; + foreach (const QString &value, QtUtils::parse(f.readLine(), ',')) + values.append(QtUtils::fromString(value)); + + File in; + in.name = values.first().toString(); + setValuesFromHeaders(in, headers, values.mid(1)); + in.set("progress", f.pos()); + templates.append(in); + } + *done = f.atEnd(); } - *done = f.atEnd(); + return templates; } @@ -104,10 +247,10 @@ class csvGallery : public FileGallery writeOpen(); if (headers.isEmpty()) { foreach (const QString &key, t.file.localKeys()) - headers.append(key); + headers.append(CSVHeader(key)); headers.sort(); - const QString header = QString(QStringList(QStringList("File") + headers).join(",") + "\n"); + const QString header = QString(QStringList(QStringList("File") + headers.keys()).join(",") + "\n"); f.write(header.toLocal8Bit()); } f.write(QString(lineFromFile(t.file) + "\n").toLocal8Bit()); @@ -119,7 +262,7 @@ class csvGallery : public FileGallery { QStringList words; words.append(file.name); - foreach (const QString &key, headers) { + foreach (const QString &key, headers.keys()) { QString value = QtUtils::toString(file.value(key)); if (value.contains(",")) value = '"' + value + '"'; @@ -127,29 +270,6 @@ class csvGallery : public FileGallery } return words.join(","); } - - static QVariantList parseLine(const QByteArray bytes) - { - bool inQuote(false); - QVariantList values; - QString value = QString(); - const QString line = QString::fromLocal8Bit(bytes).trimmed(); - for (int i=0; i