Commit bd13c06ee2a748c98139e2f4a7526385206294be
1 parent
fa4557b7
Fixed crossValidation allPartitions bug
Showing
5 changed files
with
90 additions
and
33 deletions
openbr/openbr_plugin.cpp
| @@ -388,33 +388,44 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) | @@ -388,33 +388,44 @@ TemplateList TemplateList::fromGallery(const br::File &gallery) | ||
| 388 | const int crossValidate = gallery.get<int>("crossValidate"); | 388 | const int crossValidate = gallery.get<int>("crossValidate"); |
| 389 | if (crossValidate > 0) srand(0); | 389 | if (crossValidate > 0) srand(0); |
| 390 | 390 | ||
| 391 | - for (int i=newTemplates.size()-1; i>=0; i--) { | ||
| 392 | - newTemplates[i].file.set("Index", i+templates.size()); | ||
| 393 | - newTemplates[i].file.set("Gallery", gallery.name); | ||
| 394 | - | ||
| 395 | - if (crossValidate > 0) { | ||
| 396 | - if (newTemplates[i].file.getBool("duplicatePartitions")) { | ||
| 397 | - // The duplicatePartitions flag is used to add target images | ||
| 398 | - // crossValidate times to the simmat/mask | ||
| 399 | - // when multiple training sets are being used | ||
| 400 | - | ||
| 401 | - // Set template to the first parition | ||
| 402 | - newTemplates[i].file.set("Partition", QVariant(0)); | ||
| 403 | - | ||
| 404 | - // Insert templates for all the other partitions | ||
| 405 | - for (int j=crossValidate-1; j>=1; j--) { | ||
| 406 | - Template allPartitionTemplate = newTemplates[i]; | ||
| 407 | - allPartitionTemplate.file.set("Partition", j); | ||
| 408 | - newTemplates.insert(i+1, allPartitionTemplate); | 391 | + if (gallery.getBool("leaveOneOut", 0)) { |
| 392 | + QStringList subjects = File::get(newTemplates.files(),"Subject","-1"); | ||
| 393 | + subjects. | ||
| 394 | + // Get QStringLists of unique subjects | ||
| 395 | + | ||
| 396 | + // For each list of unique subjects, decide randomly which to test on | ||
| 397 | + for (int i = 0; i < subjects.size(); i++) { | ||
| 398 | + if (subjects | ||
| 399 | + } | ||
| 400 | + } else { | ||
| 401 | + for (int i=newTemplates.size()-1; i>=0; i--) { | ||
| 402 | + newTemplates[i].file.set("Index", i+templates.size()); | ||
| 403 | + newTemplates[i].file.set("Gallery", gallery.name); | ||
| 404 | + | ||
| 405 | + if (crossValidate > 0) { | ||
| 406 | + if (newTemplates[i].file.getBool("duplicatePartitions")) { | ||
| 407 | + // The duplicatePartitions flag is used to add target images | ||
| 408 | + // crossValidate times to the simmat/mask | ||
| 409 | + // when multiple training sets are being used | ||
| 410 | + | ||
| 411 | + // Set template to the first parition | ||
| 412 | + newTemplates[i].file.set("Partition", QVariant(0)); | ||
| 413 | + | ||
| 414 | + // Insert templates for all the other partitions | ||
| 415 | + for (int j=crossValidate-1; j>0; j--) { | ||
| 416 | + Template duplicatePartitionsTemplate = newTemplates[i]; | ||
| 417 | + duplicatePartitionsTemplate.file.set("Partition", j); | ||
| 418 | + newTemplates.insert(i+1, duplicatePartitionsTemplate); | ||
| 419 | + } | ||
| 420 | + } else if (newTemplates[i].file.getBool("allPartitions")) { | ||
| 421 | + // The allPartitions flag is used to add an extended set | ||
| 422 | + // of target images to every partition | ||
| 423 | + newTemplates[i].file.set("Partition", -1); | ||
| 424 | + } else { | ||
| 425 | + const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Subject").toLatin1(), QCryptographicHash::Md5); | ||
| 426 | + // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow | ||
| 427 | + newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate); | ||
| 409 | } | 428 | } |
| 410 | - } else if (newTemplates[i].file.getBool("allPartitions")) { | ||
| 411 | - // The allPartitions flag is used to add an extended set | ||
| 412 | - // of target images to every partition | ||
| 413 | - newTemplates[i].file.set("Partition", -1); | ||
| 414 | - } else { | ||
| 415 | - const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Subject").toLatin1(), QCryptographicHash::Md5); | ||
| 416 | - // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow | ||
| 417 | - newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate); | ||
| 418 | } | 429 | } |
| 419 | } | 430 | } |
| 420 | } | 431 | } |
openbr/plugins/eyes.cpp
| @@ -182,8 +182,8 @@ private: | @@ -182,8 +182,8 @@ private: | ||
| 182 | float second_eye_y = (right_rect.y + maxLoc.y)*gray.rows/height+roi.y; | 182 | float second_eye_y = (right_rect.y + maxLoc.y)*gray.rows/height+roi.y; |
| 183 | 183 | ||
| 184 | dst.m() = src.m(); | 184 | dst.m() = src.m(); |
| 185 | - dst.file.appendPoint(QPointF(first_eye_x, first_eye_y)); | ||
| 186 | - dst.file.appendPoint(QPointF(second_eye_x, second_eye_y)); | 185 | + //dst.file.appendPoint(QPointF(first_eye_x, first_eye_y)); |
| 186 | + //dst.file.appendPoint(QPointF(second_eye_x, second_eye_y)); | ||
| 187 | dst.file.set("First_Eye", QPointF(first_eye_x, first_eye_y)); | 187 | dst.file.set("First_Eye", QPointF(first_eye_x, first_eye_y)); |
| 188 | dst.file.set("Second_Eye", QPointF(second_eye_x, second_eye_y)); | 188 | dst.file.set("Second_Eye", QPointF(second_eye_x, second_eye_y)); |
| 189 | dst.file.set("Face", QRect(roi.x, roi.y, roi.width, roi.height)); | 189 | dst.file.set("Face", QRect(roi.x, roi.y, roi.width, roi.height)); |
openbr/plugins/landmarks.cpp
| @@ -164,6 +164,7 @@ class DelaunayTransform : public UntrainableTransform | @@ -164,6 +164,7 @@ class DelaunayTransform : public UntrainableTransform | ||
| 164 | 164 | ||
| 165 | if (points.empty() || rects.empty()) { | 165 | if (points.empty() || rects.empty()) { |
| 166 | dst = src; | 166 | dst = src; |
| 167 | + dst.file.clearRects(); | ||
| 167 | qWarning("Delauney triangulation failed because points or rects are empty."); | 168 | qWarning("Delauney triangulation failed because points or rects are empty."); |
| 168 | return; | 169 | return; |
| 169 | } | 170 | } |
| @@ -292,11 +293,54 @@ class DelaunayTransform : public UntrainableTransform | @@ -292,11 +293,54 @@ class DelaunayTransform : public UntrainableTransform | ||
| 292 | dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox)); | 293 | dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox)); |
| 293 | } | 294 | } |
| 294 | } | 295 | } |
| 295 | - | ||
| 296 | }; | 296 | }; |
| 297 | 297 | ||
| 298 | BR_REGISTER(Transform, DelaunayTransform) | 298 | BR_REGISTER(Transform, DelaunayTransform) |
| 299 | 299 | ||
| 300 | +/*! | ||
| 301 | + * \ingroup transforms | ||
| 302 | + * \brief Loads a set of fiduciary points from a .dat file | ||
| 303 | + * \author Scott Klum \cite sklum | ||
| 304 | + */ | ||
| 305 | +class LoadLandmarksTransform : public UntrainableTransform | ||
| 306 | +{ | ||
| 307 | + Q_OBJECT | ||
| 308 | + | ||
| 309 | + Q_PROPERTY(QString filePath READ get_filePath WRITE set_filePath RESET reset_filePath STORED false) | ||
| 310 | + BR_PROPERTY(QString, filePath, QString()) | ||
| 311 | + | ||
| 312 | + void project(const Template &src, Template &dst) const | ||
| 313 | + { | ||
| 314 | + dst = src; | ||
| 315 | + | ||
| 316 | + QString path = Globals->path + "/" + src.file.baseName() + ".dat"; | ||
| 317 | + | ||
| 318 | + QFile f(path); | ||
| 319 | + if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(path)); | ||
| 320 | + | ||
| 321 | + QList<QPointF> landmarks; | ||
| 322 | + while(!f.atEnd()) { | ||
| 323 | + QByteArray line = f.readLine(); | ||
| 324 | + QString pointSet(line); | ||
| 325 | + pointSet = pointSet.simplified(); | ||
| 326 | + if (!pointSet.isEmpty()) { | ||
| 327 | + QStringList points = pointSet.split(" "); | ||
| 328 | + landmarks.append(QPointF(points[0].toFloat(),points[1].toFloat())); | ||
| 329 | + } | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + dst.file.set("rightEye", landmarks[16]); | ||
| 333 | + dst.file.set("leftEye", landmarks[18]); | ||
| 334 | + | ||
| 335 | + landmarks.removeAt(18); | ||
| 336 | + landmarks.removeAt(16); | ||
| 337 | + | ||
| 338 | + dst.file.appendPoints(landmarks); | ||
| 339 | + } | ||
| 340 | +}; | ||
| 341 | + | ||
| 342 | +BR_REGISTER(Transform, LoadLandmarksTransform) | ||
| 343 | + | ||
| 300 | } // namespace br | 344 | } // namespace br |
| 301 | 345 | ||
| 302 | #include "landmarks.moc" | 346 | #include "landmarks.moc" |
openbr/plugins/output.cpp
| @@ -259,7 +259,8 @@ class rrOutput : public MatrixOutput | @@ -259,7 +259,8 @@ class rrOutput : public MatrixOutput | ||
| 259 | { | 259 | { |
| 260 | if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; | 260 | if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return; |
| 261 | const int limit = file.get<int>("limit", 20); | 261 | const int limit = file.get<int>("limit", 20); |
| 262 | - const bool byLine = file.get<bool>("byLine", false); | 262 | + const bool byLine = file.getBool("byLine"); |
| 263 | + const bool simple = file.getBool("simple"); | ||
| 263 | const float threshold = file.get<float>("threshold", -std::numeric_limits<float>::max()); | 264 | const float threshold = file.get<float>("threshold", -std::numeric_limits<float>::max()); |
| 264 | 265 | ||
| 265 | QStringList lines; | 266 | QStringList lines; |
| @@ -273,7 +274,8 @@ class rrOutput : public MatrixOutput | @@ -273,7 +274,8 @@ class rrOutput : public MatrixOutput | ||
| 273 | if (pair.first < threshold) break; | 274 | if (pair.first < threshold) break; |
| 274 | File target = targetFiles[pair.second]; | 275 | File target = targetFiles[pair.second]; |
| 275 | target.set("Score", QString::number(pair.first)); | 276 | target.set("Score", QString::number(pair.first)); |
| 276 | - files.append(target.flat()); | 277 | + if (simple) files.append(target.baseName() + " " + QString::number(pair.first)); |
| 278 | + else files.append(target.flat()); | ||
| 277 | } | 279 | } |
| 278 | lines.append(files.join(byLine ? "\n" : ",")); | 280 | lines.append(files.join(byLine ? "\n" : ",")); |
| 279 | } | 281 | } |
openbr/plugins/validate.cpp
| @@ -53,10 +53,10 @@ class CrossValidateTransform : public MetaTransform | @@ -53,10 +53,10 @@ class CrossValidateTransform : public MetaTransform | ||
| 53 | 53 | ||
| 54 | void project(const Template &src, Template &dst) const | 54 | void project(const Template &src, Template &dst) const |
| 55 | { | 55 | { |
| 56 | - // If the src partition is greater than the number of training partitions, | 56 | + // If the src partition is 1, |
| 57 | // assume that projection should be done using the same training data for all partitions. | 57 | // assume that projection should be done using the same training data for all partitions. |
| 58 | int partition = src.file.get<int>("Partition", 0); | 58 | int partition = src.file.get<int>("Partition", 0); |
| 59 | - if (partition >= transforms.size()) partition = 0; | 59 | + if (partition == -1 ) partition = 0; |
| 60 | 60 | ||
| 61 | transforms[partition]->project(src, dst); | 61 | transforms[partition]->project(src, dst); |
| 62 | } | 62 | } |