Commit a64bd9fe759fd1b111a44bfe9e828a1a9c57ab2c

Authored by Scott Klum
2 parents 84472ab9 36c800db

Merge branch 'master' of https://github.com/biometrics/openbr into temp

app/br/br.cpp
@@ -100,9 +100,6 @@ public: @@ -100,9 +100,6 @@ public:
100 } else if (!strcmp(fun, "compare")) { 100 } else if (!strcmp(fun, "compare")) {
101 check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'."); 101 check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'.");
102 br_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); 102 br_compare(parv[0], parv[1], parc == 3 ? parv[2] : "");
103 - } else if (!strcmp(fun, "pairwiseCompare")) {  
104 - check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'.");  
105 - br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : "");  
106 } else if (!strcmp(fun, "eval")) { 103 } else if (!strcmp(fun, "eval")) {
107 check((parc >= 1) && (parc <= 4), "Incorrect parameter count for 'eval'."); 104 check((parc >= 1) && (parc <= 4), "Incorrect parameter count for 'eval'.");
108 if (parc == 1) { 105 if (parc == 1) {
@@ -126,9 +123,6 @@ public: @@ -126,9 +123,6 @@ public:
126 } else { 123 } else {
127 br_eval(parv[0], parv[1], parv[2], atoi(parv[3])); 124 br_eval(parv[0], parv[1], parv[2], atoi(parv[3]));
128 } 125 }
129 - } else if (!strcmp(fun, "inplaceEval")) {  
130 - check((parc >= 3) && (parc <= 4), "Incorrect parameter count for 'inplaceEval'.");  
131 - br_inplace_eval(parv[0], parv[1], parv[2], parc == 4 ? parv[3] : "");  
132 } else if (!strcmp(fun, "plot")) { 126 } else if (!strcmp(fun, "plot")) {
133 check(parc >= 2, "Incorrect parameter count for 'plot'."); 127 check(parc >= 2, "Incorrect parameter count for 'plot'.");
134 br_plot(parc-1, parv, parv[parc-1], true); 128 br_plot(parc-1, parv, parv[parc-1], true);
@@ -174,6 +168,12 @@ public: @@ -174,6 +168,12 @@ public:
174 } else if (!strcmp(fun, "evalRegression")) { 168 } else if (!strcmp(fun, "evalRegression")) {
175 check(parc >= 2 && parc <= 4, "Incorrect parameter count for 'evalRegression'."); 169 check(parc >= 2 && parc <= 4, "Incorrect parameter count for 'evalRegression'.");
176 br_eval_regression(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? parv[3] : ""); 170 br_eval_regression(parv[0], parv[1], parc >= 3 ? parv[2] : "", parc >= 4 ? parv[3] : "");
  171 + } else if (!strcmp(fun, "pairwiseCompare")) {
  172 + check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'pairwiseCompare'.");
  173 + br_pairwise_compare(parv[0], parv[1], parc == 3 ? parv[2] : "");
  174 + } else if (!strcmp(fun, "inplaceEval")) {
  175 + check((parc >= 3) && (parc <= 4), "Incorrect parameter count for 'inplaceEval'.");
  176 + br_inplace_eval(parv[0], parv[1], parv[2], parc == 4 ? parv[3] : "");
177 } else if (!strcmp(fun, "plotDetection")) { 177 } else if (!strcmp(fun, "plotDetection")) {
178 check(parc >= 2, "Incorrect parameter count for 'plotDetection'."); 178 check(parc >= 2, "Incorrect parameter count for 'plotDetection'.");
179 br_plot_detection(parc-1, parv, parv[parc-1], true); 179 br_plot_detection(parc-1, parv, parv[parc-1], true);
@@ -257,10 +257,8 @@ private: @@ -257,10 +257,8 @@ private:
257 "-train <gallery> ... <gallery> [{model}]\n" 257 "-train <gallery> ... <gallery> [{model}]\n"
258 "-enroll <input_gallery> ... <input_gallery> {output_gallery}\n" 258 "-enroll <input_gallery> ... <input_gallery> {output_gallery}\n"
259 "-compare <target_gallery> <query_gallery> [{output}]\n" 259 "-compare <target_gallery> <query_gallery> [{output}]\n"
260 - "-pairwiseCompare <target_gallery> <query_gallery> [{output}]\n"  
261 "-eval <simmat> [<mask>] [{csv}] [{matches}]\n" 260 "-eval <simmat> [<mask>] [{csv}] [{matches}]\n"
262 - "-inplaceEval <simmat> <target> <query> [{csv}]\n"  
263 - "-plot <file> ... <file> {destination}\n" 261 + "-plot <csv> ... <csv> {destination}\n"
264 "\n" 262 "\n"
265 "==== Other Commands ====\n" 263 "==== Other Commands ====\n"
266 "-fuse <simmat> ... <simmat> (None|MinMax|ZScore|WScore) (Min|Max|Sum[W1:W2:...:Wn]|Replace|Difference|None) {simmat}\n" 264 "-fuse <simmat> ... <simmat> (None|MinMax|ZScore|WScore) (Min|Max|Sum[W1:W2:...:Wn]|Replace|Difference|None) {simmat}\n"
@@ -275,6 +273,8 @@ private: @@ -275,6 +273,8 @@ private:
275 "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}]\n" 273 "-evalDetection <predicted_gallery> <truth_gallery> [{csv}] [{normalize}] [{minSize}] [{maxSize}]\n"
276 "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n" 274 "-evalLandmarking <predicted_gallery> <truth_gallery> [{csv} [<normalization_index_a> <normalization_index_b>] [sample_index] [total_examples]]\n"
277 "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n" 275 "-evalRegression <predicted_gallery> <truth_gallery> <predicted property name> <ground truth property name>\n"
  276 + "-pairwiseCompare <target_gallery> <query_gallery> [{output}]\n"
  277 + "-inplaceEval <simmat> <target> <query> [{csv}]\n"
278 "-assertEval <simmat> <mask> <accuracy>\n" 278 "-assertEval <simmat> <mask> <accuracy>\n"
279 "-plotDetection <file> ... <file> {destination}\n" 279 "-plotDetection <file> ... <file> {destination}\n"
280 "-plotLandmarking <file> ... <file> {destination}\n" 280 "-plotLandmarking <file> ... <file> {destination}\n"
openbr/core/core.cpp
@@ -266,7 +266,7 @@ struct AlgorithmCore @@ -266,7 +266,7 @@ struct AlgorithmCore
266 266
267 void retrieveOrEnroll(const File &file, QScopedPointer<Gallery> &gallery, FileList &galleryFiles) 267 void retrieveOrEnroll(const File &file, QScopedPointer<Gallery> &gallery, FileList &galleryFiles)
268 { 268 {
269 - if (!file.getBool("enroll") && (QStringList() << "gal" << "mem" << "template" << "ut").contains(file.suffix())) { 269 + if (!file.getBool("enroll") && (QStringList() << "gal" << "mem" << "template" << "t").contains(file.suffix())) {
270 // Retrieve it 270 // Retrieve it
271 gallery.reset(Gallery::make(file)); 271 gallery.reset(Gallery::make(file));
272 galleryFiles = gallery->files(); 272 galleryFiles = gallery->files();
@@ -443,7 +443,7 @@ struct AlgorithmCore @@ -443,7 +443,7 @@ struct AlgorithmCore
443 colEnrolledGallery = colGallery.baseName() + colGallery.hash() + '.' + targetExtension; 443 colEnrolledGallery = colGallery.baseName() + colGallery.hash() + '.' + targetExtension;
444 444
445 // Check if we have to do real enrollment, and not just convert the gallery's type. 445 // Check if we have to do real enrollment, and not just convert the gallery's type.
446 - if (!(QStringList() << "gal" << "template" << "mem" << "ut").contains(colGallery.suffix())) 446 + if (!(QStringList() << "gal" << "template" << "mem" << "t").contains(colGallery.suffix()))
447 enroll(colGallery, colEnrolledGallery); 447 enroll(colGallery, colEnrolledGallery);
448 448
449 // If the gallery does have enrolled templates, but is not the right type, we do a simple 449 // If the gallery does have enrolled templates, but is not the right type, we do a simple
@@ -465,7 +465,7 @@ struct AlgorithmCore @@ -465,7 +465,7 @@ struct AlgorithmCore
465 // which compares incoming templates against a gallery, we will handle enrollment of the row set by simply 465 // which compares incoming templates against a gallery, we will handle enrollment of the row set by simply
466 // building a transform that does enrollment (using the current algorithm), then does the comparison in one 466 // building a transform that does enrollment (using the current algorithm), then does the comparison in one
467 // step. This way, we don't have to retain the complete enrolled row gallery in memory, or on disk. 467 // step. This way, we don't have to retain the complete enrolled row gallery in memory, or on disk.
468 - else if (!(QStringList() << "gal" << "mem" << "template" << "ut").contains(rowGallery.suffix())) 468 + else if (!(QStringList() << "gal" << "mem" << "template" << "t").contains(rowGallery.suffix()))
469 needEnrollRows = true; 469 needEnrollRows = true;
470 470
471 // At this point, we have decided how we will structure the comparison (either in transpose mode, or not), 471 // At this point, we have decided how we will structure the comparison (either in transpose mode, or not),
1 -Subproject commit 8cdda77000209ea279093b0d4fad3988f22f0548 1 +Subproject commit bab25ea9b9f26791859415abe953f6df82ace86e
openbr/janus.cpp
@@ -24,13 +24,13 @@ janus_error janus_initialize(const char *sdk_path, const char *temp_path, const @@ -24,13 +24,13 @@ janus_error janus_initialize(const char *sdk_path, const char *temp_path, const
24 Globals->enrollAll = true; 24 Globals->enrollAll = true;
25 Globals->file.set(QString("temp_path"), QString(temp_path)); 25 Globals->file.set(QString("temp_path"), QString(temp_path));
26 const QString algorithm = model_file; 26 const QString algorithm = model_file;
  27 + detect.reset(Transform::make("Cvt(Gray)+Cascade(FrontalFace,ROCMode=true)", NULL));
27 if (algorithm.isEmpty()) { 28 if (algorithm.isEmpty()) {
28 - detect.reset(Transform::make("Cvt(Gray)+Cascade(FrontalFace,ROCMode=true)", NULL));  
29 augment.reset(Transform::make("Cvt(Gray)+Affine(88,88,0.25,0.35)+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>", NULL)); 29 augment.reset(Transform::make("Cvt(Gray)+Affine(88,88,0.25,0.35)+<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>", NULL));
30 distance = Distance::fromAlgorithm("FaceRecognition"); 30 distance = Distance::fromAlgorithm("FaceRecognition");
31 } else { 31 } else {
32 - augment.reset(Transform::make(algorithm + "Enroll", NULL));  
33 - distance.reset(Distance::make(algorithm + "Compare", NULL)); 32 + augment = Transform::fromAlgorithm(algorithm);
  33 + distance = Distance::fromAlgorithm(algorithm);
34 } 34 }
35 return JANUS_SUCCESS; 35 return JANUS_SUCCESS;
36 } 36 }
openbr/plugins/imgproc/cropfromlandmarks.cpp 0 โ†’ 100644
  1 +#include <openbr/plugins/openbr_internal.h>
  2 +
  3 +using namespace cv;
  4 +
  5 +namespace br
  6 +{
  7 +
  8 +/*!
  9 + * \ingroup transforms
  10 + * \brief Crops around the landmarks numbers provided.
  11 + * \author Brendan Klare \cite bklare
  12 + * \param padding Percentage of height and width to pad the image.
  13 + */
  14 +class CropFromLandmarksTransform : public UntrainableTransform
  15 +{
  16 + Q_OBJECT
  17 +
  18 + Q_PROPERTY(QList<int> indices READ get_indices WRITE set_indices RESET reset_indices STORED false)
  19 + Q_PROPERTY(float paddingHorizontal READ get_paddingHorizontal WRITE set_paddingHorizontal RESET reset_paddingHorizontal STORED false)
  20 + Q_PROPERTY(float paddingVertical READ get_paddingVertical WRITE set_paddingVertical RESET reset_paddingVertical STORED false)
  21 + BR_PROPERTY(QList<int>, indices, QList<int>())
  22 + BR_PROPERTY(float, paddingHorizontal, .1)
  23 + BR_PROPERTY(float, paddingVertical, .1)
  24 +
  25 + void project(const Template &src, Template &dst) const
  26 + {
  27 + int minX = src.m().cols - 1,
  28 + maxX = 1,
  29 + minY = src.m().rows - 1,
  30 + maxY = 1;
  31 +
  32 + for (int i = 0; i <indices.size(); i++) {
  33 + if (minX > src.file.points()[indices[i]].x())
  34 + minX = src.file.points()[indices[i]].x();
  35 + if (minY > src.file.points()[indices[i]].y())
  36 + minY = src.file.points()[indices[i]].y();
  37 + if (maxX < src.file.points()[indices[i]].x())
  38 + maxX = src.file.points()[indices[i]].x();
  39 + if (maxY < src.file.points()[indices[i]].y())
  40 + maxY = src.file.points()[indices[i]].y();
  41 + }
  42 +
  43 + int padW = qRound((maxX - minX) * (paddingHorizontal / 2));
  44 + int padH = qRound((maxY - minY) * (paddingVertical / 2));
  45 +
  46 + dst = Mat(src, Rect(minX - padW, minY - padH, (maxX - minX + 1) + padW * 2, (maxY - minY + 1) + padH * 2));
  47 + }
  48 +};
  49 +
  50 +BR_REGISTER(Transform, CropFromLandmarksTransform)
  51 +
  52 +} // namespace br
  53 +
  54 +#include "imgproc/cropfromlandmarks.moc"
openbr/plugins/metadata/cascade.cpp
@@ -401,18 +401,22 @@ class CascadeTransform : public MetaTransform @@ -401,18 +401,22 @@ class CascadeTransform : public MetaTransform
401 } 401 }
402 402
403 for (int i=0; i<t.size(); i++) { 403 for (int i=0; i<t.size(); i++) {
  404 + const int maxDetections = t.file.get<int>("MaxDetections", std::numeric_limits<int>::max());
  405 + const int flags = (enrollAll && (maxDetections != 1)) ? 0 : CASCADE_FIND_BIGGEST_OBJECT;
  406 +
404 Mat m; 407 Mat m;
405 OpenCVUtils::cvtUChar(t[i], m); 408 OpenCVUtils::cvtUChar(t[i], m);
406 std::vector<Rect> rects; 409 std::vector<Rect> rects;
407 std::vector<int> rejectLevels; 410 std::vector<int> rejectLevels;
408 std::vector<double> levelWeights; 411 std::vector<double> levelWeights;
409 - if (ROCMode) cascade->detectMultiScale(m, rects, rejectLevels, levelWeights, 1.2, minNeighbors, (enrollAll ? 0 : CASCADE_FIND_BIGGEST_OBJECT) | CASCADE_SCALE_IMAGE, Size(minSize, minSize), Size(), true);  
410 - else cascade->detectMultiScale(m, rects, 1.2, minNeighbors, enrollAll ? 0 : CASCADE_FIND_BIGGEST_OBJECT, Size(minSize, minSize)); 412 + if (ROCMode) cascade->detectMultiScale(m, rects, rejectLevels, levelWeights, 1.2, minNeighbors, flags | CASCADE_SCALE_IMAGE, Size(minSize, minSize), Size(), true);
  413 + else cascade->detectMultiScale(m, rects, 1.2, minNeighbors, flags, Size(minSize, minSize));
411 414
412 if (!enrollAll && rects.empty()) 415 if (!enrollAll && rects.empty())
413 rects.push_back(Rect(0, 0, m.cols, m.rows)); 416 rects.push_back(Rect(0, 0, m.cols, m.rows));
414 417
415 - for (size_t j=0; j<rects.size(); j++) { 418 + const size_t detections = std::min(size_t(maxDetections), rects.size());
  419 + for (size_t j=0; j<detections; j++) {
416 Template u(t.file, m); 420 Template u(t.file, m);
417 if (rejectLevels.size() > j) 421 if (rejectLevels.size() > j)
418 u.file.set("Confidence", rejectLevels[j]*levelWeights[j]); 422 u.file.set("Confidence", rejectLevels[j]*levelWeights[j]);
scripts/evalFaceRecognition-LFW.sh
@@ -20,7 +20,7 @@ if [ ! -e Algorithm_Dataset ]; then @@ -20,7 +20,7 @@ if [ ! -e Algorithm_Dataset ]; then
20 fi 20 fi
21 21
22 # Run the LFW test protocol 22 # Run the LFW test protocol
23 -br -algorithm $ALGORITHM -path ../data/LFW/img/ -crossValidate 10 -pairwiseCompare ../data/LFW/sigset/test_image_restricted_target.xml ../data/LFW/sigset/test_image_restricted_query.xml ${ALGORITHM}_LFW.mtx -convert Output ${ALGORITHM}_lfw.mtx Algorithm_Dataset/${ALGORITHM}_LFW%1.eval 23 +br -algorithm $ALGORITHM -path ../data/LFW/img/ -crossValidate 10 -pairwiseCompare ../data/LFW/sigset/test_image_restricted_target.xml ../data/LFW/sigset/test_image_restricted_query.xml ${ALGORITHM}_LFW.mtx -convert Output ${ALGORITHM}_LFW.mtx Algorithm_Dataset/${ALGORITHM}_LFW%1.eval
24 24
25 # Plot results 25 # Plot results
26 -br -plot Algorithm_Dataset/* 'lfw_results.pdf[smooth=Dataset,rocOptions[yLimits=(0,1)]]' 26 +br -plot Algorithm_Dataset/* 'lfw_results.pdf[smooth=Dataset,rocOptions=[yLimits=(0,1)]]'