Commit a64bd9fe759fd1b111a44bfe9e828a1a9c57ab2c
Merge branch 'master' of https://github.com/biometrics/openbr into temp
Showing
7 changed files
with
79 additions
and
21 deletions
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), |
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)]]' |