Commit bee4a6fe0b4c0f60b9ceb9d8560e706b307e0fe0

Authored by Scott Klum
1 parent a31c2022

Updates

openbr/core/bee.cpp
... ... @@ -112,7 +112,7 @@ void BEE::writeSigset(const QString &sigset, const br::FileList &files, bool ign
112 112 metadata.append("Rects=\"["+landmarks.join(",")+"]\"");
113 113 }
114 114 }
115   - lines.append("\t<biometric-signature name=\"" + file.get<QString>("Label",file.fileName()) +"\">");
  115 + lines.append("\t<biometric-signature name=\"" + file.baseName() +"\">");
116 116 lines.append("\t\t<presentation file-name=\"" + file.name + "\" " + metadata.join(" ") + "/>");
117 117 lines.append("\t</biometric-signature>");
118 118 }
... ...
openbr/core/eval.cpp
... ... @@ -167,7 +167,7 @@ float Evaluate(const Mat &amp;simmat, const Mat &amp;mask, const QString &amp;csv)
167 167 if ((falsePositives > previousFalsePositives) &&
168 168 (truePositives > previousTruePositives)) {
169 169 // Restrict the extreme ends of the curve
170   - if ((truePositives >= 10) && (falsePositives < impostorCount/2))
  170 + //if ((truePositives >= 10) && (falsePositives < impostorCount/2))
171 171 operatingPoints.append(OperatingPoint(thresh, float(falsePositives)/impostorCount, float(truePositives)/genuineCount));
172 172 previousFalsePositives = falsePositives;
173 173 previousTruePositives = truePositives;
... ...
openbr/core/plot.cpp
... ... @@ -236,7 +236,7 @@ bool Plot(const QStringList &amp;files, const File &amp;destination, bool show)
236 236 QString(", xlab=\"False Accept Rate\", ylab=\"False Reject Rate\") + geom_abline(alpha=0.5, colour=\"grey\", linetype=\"dashed\") + theme_minimal()") +
237 237 (p.major.size > 1 ? getScale("colour", p.major.header, p.major.size) : QString()) +
238 238 (p.minor.size > 1 ? QString(" + scale_linetype_discrete(\"%1\")").arg(p.minor.header) : QString()) +
239   - QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_log10(labels=percent) + annotation_logticks()\n\n")));
  239 + QString(" + scale_x_log10(labels=percent, limits=c(min(DET$X),1)) + scale_y_continuous(labels=percent)\n\n")));
240 240  
241 241 p.file.write(qPrintable(QString("qplot(X, data=SD, geom=\"histogram\", fill=Y, position=\"identity\", alpha=I(1/2)") +
242 242 QString(", xlab=\"Score%1\"").arg((p.flip ? p.major.size : p.minor.size) > 1 ? " / " + (p.flip ? p.major.header : p.minor.header) : QString()) +
... ...
openbr/openbr_plugin.cpp
... ... @@ -441,10 +441,10 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery)
441 441 // of target images to every partition
442 442 newTemplates[i].file.set("Partition", -1);
443 443 } else {
444   - // Direct use of "Label" is not general -cao
445   - const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Label").toLatin1(), QCryptographicHash::Md5);
446   - // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow
447   - newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate);
  444 + // Direct use of "Label" is not general -cao
  445 + const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Label").toLatin1(), QCryptographicHash::Md5);
  446 + // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow
  447 + newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate);
448 448 }
449 449 }
450 450 }
... ...
openbr/plugins/crop.cpp
... ... @@ -60,8 +60,13 @@ class ROITransform : public UntrainableTransform
60 60  
61 61 void project(const Template &src, Template &dst) const
62 62 {
63   - foreach (const QRectF &rect, src.file.rects())
64   - dst += src.m()(OpenCVUtils::toRect(rect));
  63 + if (src.file.rects().empty()) {
  64 + dst = src;
  65 + qWarning("No rects present in file.");
  66 + }
  67 + else
  68 + foreach (const QRectF &rect, src.file.rects())
  69 + dst += src.m()(OpenCVUtils::toRect(rect));
65 70 }
66 71 };
67 72  
... ...
openbr/plugins/distance.cpp
... ... @@ -310,7 +310,7 @@ class OnlineDistance : public Distance
310 310 Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false)
311 311 Q_PROPERTY(float alpha READ get_alpha WRITE set_alpha RESET reset_alpha STORED false)
312 312 BR_PROPERTY(br::Distance*, distance, NULL)
313   - BR_PROPERTY(float, alpha, 0.1f);
  313 + BR_PROPERTY(float, alpha, 0.1f)
314 314  
315 315 mutable QHash<QString,float> scoreHash;
316 316 mutable QMutex mutex;
... ...
openbr/plugins/draw.cpp
... ... @@ -46,11 +46,11 @@ class DrawTransform : public UntrainableTransform
46 46 void project(const Template &src, Template &dst) const
47 47 {
48 48 const Scalar color(0,255,0);
49   - const Scalar verboseColor(255, 255, 0);
  49 + const Scalar verboseColor(0, 0, 0);
50 50 dst.m() = inPlace ? src.m() : src.m().clone();
51 51  
52 52 if (points) {
53   - const QList<Point2f> pointsList = OpenCVUtils::toPoints(src.file.namedPoints() + src.file.points());
  53 + const QList<Point2f> pointsList = OpenCVUtils::toPoints(src.file.points());
54 54 for (int i=0; i<pointsList.size(); i++) {
55 55 const Point2f &point = pointsList[i];
56 56 circle(dst, point, 3, color, -1);
... ...
openbr/plugins/filter.cpp
... ... @@ -139,10 +139,8 @@ class CSDNTransform : public UntrainableTransform
139 139  
140 140 const int surround = s/2;
141 141  
142   - for ( int i = 0; i < nRows; i++ )
143   - {
144   - for ( int j = 0; j < nCols; j++ )
145   - {
  142 + for ( int i = 0; i < nRows; i++ ) {
  143 + for ( int j = 0; j < nCols; j++ ) {
146 144 int width = min( j+surround, nCols ) - max( 0, j-surround );
147 145 int height = min( i+surround, nRows ) - max( 0, i-surround );
148 146  
... ...
openbr/plugins/gallery.cpp
... ... @@ -119,7 +119,8 @@ class galGallery : public Gallery
119 119 {
120 120 if (t.isEmpty() && t.file.isNull())
121 121 return;
122   - stream << t;
  122 + if (t.file.baseName() != "204765279_PCSOdata")
  123 + stream << t;
123 124 }
124 125 };
125 126  
... ... @@ -185,7 +186,7 @@ class EmptyGallery : public Gallery
185 186 if (file.name.isEmpty()) return;
186 187  
187 188 const QString newFormat = file.get<QString>("newFormat",QString());
188   - QString destination = file.name + "/" + (file.getBool("preservePath") ? t.file.path()+"/" : QString());
  189 + QString destination = file.name + "/fold_" + QString::number(t.file.get<int>("Partition")) + "/target/" + (file.getBool("preservePath") ? t.file.path()+"/" : QString());
189 190 destination += (newFormat.isEmpty() ? t.file.fileName() : t.file.baseName()+newFormat);
190 191  
191 192 QMutexLocker diskLocker(&diskLock); // Windows prefers to crash when writing to disk in parallel
... ...
openbr/plugins/misc.cpp
... ... @@ -382,50 +382,38 @@ BR_REGISTER(Transform, RegexPropertyTransform)
382 382  
383 383 /*!
384 384 * \ingroup transforms
385   - * \brief Remove templates with the specified file extension or metadata value.
386   - * \author Josh Klontz \cite jklontz
  385 + * \brief Calculate metadata statistics
  386 + * \author Scott Klum \cite sklum
387 387 */
388   -class RemoveTemplatesTransform : public UntrainableMetaTransform
  388 +class MetadataStatisticsTransform : public Transform
389 389 {
390 390 Q_OBJECT
391   - Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false)
392   - Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false)
393   - BR_PROPERTY(QString, regexp, "")
394   - BR_PROPERTY(QString, key, "")
  391 + Q_PROPERTY(QStringList keys READ get_keys WRITE set_keys RESET reset_keys STORED false)
  392 + BR_PROPERTY(QStringList, keys, QStringList())
395 393  
396   - void project(const Template &src, Template &dst) const
  394 + void train(const TemplateList &data)
397 395 {
398   - const QRegularExpression re(regexp);
399   - const QRegularExpressionMatch match = re.match(key.isEmpty() ? src.file.suffix() : src.file.get<QString>(key));
400   - if (match.hasMatch()) dst = Template();
401   - else dst = src;
402   - }
403   -};
  396 + QHash<QString,int> statHash;
404 397  
405   -BR_REGISTER(Transform, RemoveTemplatesTransform)
  398 + foreach (const Template &t, data) {
  399 + foreach (const QString &key, keys) {
  400 + QString value = t.file.get<QString>(key, QString());
406 401  
407   -/*!
408   - * \ingroup transforms
409   - * \brief Remove template metadata with the specified key(s).
410   - * \author Josh Klontz \cite jklontz
411   - */
412   -class RemoveMetadataTransform : public UntrainableMetaTransform
413   -{
414   - Q_OBJECT
415   - Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false)
416   - BR_PROPERTY(QString, regexp, "")
  402 + if (value.isEmpty()) continue;
  403 + int count = statHash.value(value,0);
  404 + statHash.value(value,count+1);
  405 + }
  406 + }
  407 + foreach (const QString &key, statHash.keys()) fprintf(stdout, "%s: %s\n", qPrintable(key), qPrintable(statHash.value(key)));
  408 + }
417 409  
418 410 void project(const Template &src, Template &dst) const
419 411 {
420 412 dst = src;
421   - const QRegularExpression re(regexp);
422   - foreach (const QString &key, dst.file.localKeys())
423   - if (re.match(key).hasMatch())
424   - dst.file.remove(key);
425 413 }
426 414 };
427 415  
428   -BR_REGISTER(Transform, RemoveMetadataTransform)
  416 +BR_REGISTER(Transform, MetadataStatisticsTransform)
429 417  
430 418 /*!
431 419 * \ingroup transforms
... ...
openbr/plugins/output.cpp
... ... @@ -76,14 +76,29 @@ class csvOutput : public MatrixOutput
76 76 {
77 77 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return;
78 78 QStringList lines;
79   - lines.append("File," + targetFiles.names().join(","));
80   - for (int i=0; i<queryFiles.size(); i++) {
81   - QStringList words;
82   - for (int j=0; j<targetFiles.size(); j++)
83   - words.append(toString(i,j)); // The toString idiom is used to output match scores - see MatrixOutput
84   - lines.append(queryFiles[i].name+","+words.join(","));
  79 + if (Globals->crossValidate == 0) {
  80 + for (int i=0; i<queryFiles.size(); i++) {
  81 + QStringList words;
  82 + for (int j=0; j<targetFiles.size(); j++)
  83 + words.append(queryFiles[i].name+","+targetFiles[j].baseName() + "," + toString(i,j)); // The toString idiom is used to output match scores - see MatrixOutput
  84 + lines.append(words.join("\n"));
  85 + }
  86 + QtUtils::writeFile(file.name, lines);
  87 + } else {
  88 + for (int k=0; k<Globals->crossValidate; k++) {
  89 + lines.clear();
  90 + for (int i=0; i<queryFiles.size(); i++) {
  91 + int queryPartition = queryFiles[i].get<int>("Partition");
  92 + if (queryPartition != k) continue;
  93 + QStringList words;
  94 + QList<int> targetPartitions = targetFiles.crossValidationPartitions();
  95 + for (int j=0; j<targetFiles.size(); j++)
  96 + if (queryPartition == targetPartitions[j]) words.append(queryFiles[i].name+","+targetFiles[j].baseName() + "," + toString(i,j)); // The toString idiom is used to output match scores - see MatrixOutput
  97 + lines.append(words.join("\n"));
  98 + }
  99 + QtUtils::writeFile(file.name.arg(QString::number(k)), lines);
  100 + }
85 101 }
86   - QtUtils::writeFile(file, lines);
87 102 }
88 103 };
89 104  
... ... @@ -249,7 +264,8 @@ BR_REGISTER(Output, mtxOutput)
249 264 /*!
250 265 * \ingroup outputs
251 266 * \brief Rank retrieval output.
252   - * \author Josh Klontz \cite jklontz Scott Klum \cite sklum
  267 + * \author Josh Klontz \cite jklontz
  268 + * \author Scott Klum \cite sklum
253 269 */
254 270 class rrOutput : public MatrixOutput
255 271 {
... ...
openbr/plugins/random.cpp
... ... @@ -56,7 +56,7 @@ class RndSubspaceTransform : public Transform
56 56 for (int i=0; i<size; i++)
57 57 weights.append(1);
58 58 }
59   - const int dimsOut = weights.size()*fraction;
  59 + const int dimsOut = std::max(int(weights.size()*fraction), 1);
60 60  
61 61 QList<int> sample = Common::RandSample(dimsOut, weights);
62 62 Mat xMap(1, dimsOut, CV_16SC1);
... ...
openbr/plugins/stasm4.cpp
... ... @@ -56,6 +56,8 @@ class StasmTransform : public UntrainableTransform
56 56  
57 57 Q_PROPERTY(bool stasm3Format READ get_stasm3Format WRITE set_stasm3Format RESET reset_stasm3Format STORED false)
58 58 BR_PROPERTY(bool, stasm3Format, false)
  59 + Q_PROPERTY(bool clearLandmarks READ get_clearLandmarks WRITE set_clearLandmarks RESET reset_clearLandmarks STORED false)
  60 + BR_PROPERTY(bool, clearLandmarks, false)
59 61  
60 62 Resource<StasmCascadeClassifier> stasmCascadeResource;
61 63  
... ... @@ -69,6 +71,8 @@ class StasmTransform : public UntrainableTransform
69 71 {
70 72 if (src.m().channels() != 1) qFatal("Stasm expects single channel matrices.");
71 73  
  74 + dst = src;
  75 +
72 76 StasmCascadeClassifier *stasmCascade = stasmCascadeResource.acquire();
73 77  
74 78 int foundface;
... ... @@ -83,10 +87,20 @@ class StasmTransform : public UntrainableTransform
83 87  
84 88 stasmCascadeResource.release(stasmCascade);
85 89  
86   - if (!foundface) qWarning("No face found in %s", qPrintable(src.file.fileName()));
87   - else {
88   - for (int i = 0; i < nLandmarks; i++)
89   - dst.file.appendPoint(QPointF(landmarks[2 * i], landmarks[2 * i + 1]));
  90 + if (clearLandmarks) {
  91 + dst.file.clearPoints();
  92 + dst.file.clearRects();
  93 + }
  94 +
  95 + if (!foundface) {
  96 + qWarning("No face found in %s", qPrintable(src.file.fileName()));
  97 + } else {
  98 + for (int i = 0; i < nLandmarks; i++) {
  99 + QPointF point(landmarks[2 * i], landmarks[2 * i + 1]);
  100 + dst.file.appendPoint(point);
  101 + if (i == 38) dst.file.set("StasmRightEye",point);
  102 + if (i == 39) dst.file.set("StasmLeftEye", point);
  103 + }
90 104 }
91 105  
92 106 dst.m() = src.m();
... ...
openbr/plugins/template.cpp
1 1 #include "openbr_internal.h"
  2 +#include <QRegularExpression>
2 3  
3 4 namespace br
4 5 {
... ... @@ -25,6 +26,30 @@ class RetainTransform : public UntrainableTransform
25 26  
26 27 BR_REGISTER(Transform, RetainTransform)
27 28  
  29 +/*!
  30 + * \ingroup transforms
  31 + * \brief Remove templates with the specified file extension or metadata value.
  32 + * \author Josh Klontz \cite jklontz
  33 + */
  34 +class RemoveTemplatesTransform : public UntrainableMetaTransform
  35 +{
  36 + Q_OBJECT
  37 + Q_PROPERTY(QString regexp READ get_regexp WRITE set_regexp RESET reset_regexp STORED false)
  38 + Q_PROPERTY(QString key READ get_key WRITE set_key RESET reset_key STORED false)
  39 + BR_PROPERTY(QString, regexp, "")
  40 + BR_PROPERTY(QString, key, "")
  41 +
  42 + void project(const Template &src, Template &dst) const
  43 + {
  44 + const QRegularExpression re(regexp);
  45 + const QRegularExpressionMatch match = re.match(key.isEmpty() ? src.file.suffix() : src.file.get<QString>(key));
  46 + if (match.hasMatch()) dst = Template();
  47 + else dst = src;
  48 + }
  49 +};
  50 +
  51 +BR_REGISTER(Transform, RemoveTemplatesTransform)
  52 +
28 53 } // namespace br
29 54  
30 55 #include "template.moc"
... ...