Commit be996aacdff87778e92e38f33ffe46357798c83f
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
21 changed files
with
410 additions
and
119 deletions
CMakeLists.txt
| ... | ... | @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8.9) |
| 3 | 3 | |
| 4 | 4 | # Global settings |
| 5 | 5 | set(BR_SHARE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/share/openbr") |
| 6 | +set(BR_SCRIPTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/scripts") | |
| 6 | 7 | set(CMAKE_AUTOMOC ON) |
| 7 | 8 | set(CPACK_PACKAGE_NAME "OpenBR") |
| 8 | 9 | set(CPACK_PACKAGE_VENDOR "OpenBiometrics") |
| ... | ... | @@ -117,7 +118,7 @@ if(BUILD_TESTING) |
| 117 | 118 | endif() |
| 118 | 119 | |
| 119 | 120 | # Build the SDK |
| 120 | -include_directories(.) | |
| 121 | +include_directories(BEFORE .) # Find the local headers first | |
| 121 | 122 | add_subdirectory(openbr) |
| 122 | 123 | |
| 123 | 124 | # Build applications |
| ... | ... | @@ -138,6 +139,14 @@ install(FILES CHANGELOG.md LICENSE.txt README.md DESTINATION .) |
| 138 | 139 | install(DIRECTORY share DESTINATION .) |
| 139 | 140 | install(DIRECTORY ${BR_THIRDPARTY_SHARE} DESTINATION share) |
| 140 | 141 | |
| 142 | +# install brpy | |
| 143 | +option(BR_INSTALL_BRPY "Install brpy, the Python wrapper to the C API (requires Python)") | |
| 144 | +if(${BR_INSTALL_BRPY}) | |
| 145 | + find_package(PythonInterp REQUIRED) | |
| 146 | + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import site, sys; sys.stdout.write(site.getsitepackages()[-1])" OUTPUT_VARIABLE PYTHON_SITE_DIR) | |
| 147 | + install(DIRECTORY ${BR_SCRIPTS_DIR}/brpy DESTINATION ${PYTHON_SITE_DIR}) | |
| 148 | +endif() | |
| 149 | + | |
| 141 | 150 | # Package |
| 142 | 151 | set(CPACK_PACKAGE_EXECUTABLES "OpenBR" "OpenBR") |
| 143 | 152 | set(CPACK_CREATE_DESKTOP_LINKS "OpenBR") | ... | ... |
openbr/core/core.cpp
| ... | ... | @@ -56,11 +56,6 @@ struct AlgorithmCore |
| 56 | 56 | |
| 57 | 57 | TemplateList data(TemplateList::fromGallery(input)); |
| 58 | 58 | |
| 59 | - // set the Train bool metadata, in case a Transform's project | |
| 60 | - // needs to know if it's called during train or enroll | |
| 61 | - for (int i=0; i<data.size(); i++) | |
| 62 | - data[i].file.set("Train", true); | |
| 63 | - | |
| 64 | 59 | if (transform.isNull()) qFatal("Null transform."); |
| 65 | 60 | qDebug("%d Training Files", data.size()); |
| 66 | 61 | |
| ... | ... | @@ -153,9 +148,12 @@ struct AlgorithmCore |
| 153 | 148 | if (data.empty()) |
| 154 | 149 | return files; |
| 155 | 150 | |
| 151 | + // Store steps for ProgressCounter | |
| 152 | + Globals->currentStep = 0; | |
| 153 | + Globals->totalSteps = data.length(); | |
| 154 | + | |
| 156 | 155 | // Trust me, this makes complete sense. |
| 157 | 156 | // We're just going to make a pipe with a placeholder first transform |
| 158 | - Globals->totalSteps = data.length(); | |
| 159 | 157 | QString pipeDesc = "Identity+GalleryOutput("+gallery.flat()+")+ProgressCounter("+QString::number(data.length())+")+Discard"; |
| 160 | 158 | QScopedPointer<Transform> basePipe(Transform::make(pipeDesc,NULL)); |
| 161 | 159 | |
| ... | ... | @@ -430,6 +428,13 @@ void br::Compare(const File &targetGallery, const File &queryGallery, const File |
| 430 | 428 | AlgorithmManager::getAlgorithm(output.get<QString>("algorithm"))->compare(targetGallery, queryGallery, output); |
| 431 | 429 | } |
| 432 | 430 | |
| 431 | +void br::CompareTemplateLists(const TemplateList &target, const TemplateList &query, Output *output) | |
| 432 | +{ | |
| 433 | + QString alg = output->file.get<QString>("algorithm"); | |
| 434 | + QSharedPointer<Distance> dist = Distance::fromAlgorithm(alg); | |
| 435 | + dist->compare(target, query, output); | |
| 436 | +} | |
| 437 | + | |
| 433 | 438 | void br::PairwiseCompare(const File &targetGallery, const File &queryGallery, const File &output) |
| 434 | 439 | { |
| 435 | 440 | AlgorithmManager::getAlgorithm(output.get<QString>("algorithm"))->pairwiseCompare(targetGallery, queryGallery, output); |
| ... | ... | @@ -456,7 +461,7 @@ void br::Convert(const File &fileType, const File &inputFile, const File &output |
| 456 | 461 | |
| 457 | 462 | if ((targetFiles.size() != m.cols || queryFiles.size() != m.rows) |
| 458 | 463 | && (m.cols != 1 || targetFiles.size() != m.rows || queryFiles.size() != m.rows)) |
| 459 | - qFatal("Similarity matrix and file size mismatch."); | |
| 464 | + qFatal("Similarity matrix (%d, %d) and header (%d, %d) size mismatch.", m.rows, m.cols, queryFiles.size(), targetFiles.size()); | |
| 460 | 465 | |
| 461 | 466 | QSharedPointer<Output> o(Factory<Output>::make(outputFile)); |
| 462 | 467 | o->initialize(targetFiles, queryFiles); | ... | ... |
openbr/core/fuse.cpp
| ... | ... | @@ -30,6 +30,9 @@ using namespace cv; |
| 30 | 30 | |
| 31 | 31 | static void normalizeMatrix(Mat &matrix, const Mat &mask, const QString &method) |
| 32 | 32 | { |
| 33 | + if (matrix.rows != mask.rows && matrix.cols != mask.cols) | |
| 34 | + qFatal("Similarity matrix (%d, %d) and mask (%d, %d) size mismatch.", matrix.rows, matrix.cols, mask.rows, mask.cols); | |
| 35 | + | |
| 33 | 36 | if (method == "None") return; |
| 34 | 37 | |
| 35 | 38 | QList<float> vals; vals.reserve(matrix.rows*matrix.cols); | ... | ... |
openbr/gui/progress.cpp
| ... | ... | @@ -26,7 +26,7 @@ br::Progress::Progress(QWidget *parent) |
| 26 | 26 | void br::Progress::checkProgress() |
| 27 | 27 | { |
| 28 | 28 | const int progress = 100 * br_progress(); |
| 29 | - const bool visible = progress >= 0; | |
| 29 | + const bool visible = progress >= 0 && progress < 100; | |
| 30 | 30 | |
| 31 | 31 | if (visible) { |
| 32 | 32 | showMessage(br_most_recent_message()); | ... | ... |
openbr/gui/utility.cpp
| 1 | -#include <QImage> | |
| 2 | 1 | #include <limits> |
| 3 | 2 | #include <vector> |
| 4 | 3 | #include <opencv2/imgproc/imgproc.hpp> |
| 4 | +#include "utility.h" | |
| 5 | 5 | |
| 6 | 6 | using namespace cv; |
| 7 | 7 | |
| 8 | -/**** STATIC ****/ | |
| 9 | -QImage toQImage(const Mat &mat) | |
| 8 | +QImage br::toQImage(const Mat &mat) | |
| 10 | 9 | { |
| 11 | 10 | // Convert to 8U depth |
| 12 | 11 | Mat mat8u; | ... | ... |
openbr/gui/utility.h
| ... | ... | @@ -3,7 +3,13 @@ |
| 3 | 3 | |
| 4 | 4 | #include <QImage> |
| 5 | 5 | #include <opencv2/core/core.hpp> |
| 6 | +#include <openbr/openbr_export.h> | |
| 6 | 7 | |
| 7 | -QImage toQImage(const cv::Mat &mat); | |
| 8 | +namespace br | |
| 9 | +{ | |
| 10 | + | |
| 11 | +BR_EXPORT QImage toQImage(const cv::Mat &mat); | |
| 12 | + | |
| 13 | +} // namespace br | |
| 8 | 14 | |
| 9 | 15 | #endif // BR_UTILITY_H | ... | ... |
openbr/janus.cpp
| ... | ... | @@ -80,7 +80,7 @@ janus_error janus_finalize_template(janus_incomplete_template incomplete_templat |
| 80 | 80 | templateBytes = currentTemplateBytes; |
| 81 | 81 | if (templateBytes != currentTemplateBytes) |
| 82 | 82 | return JANUS_UNKNOWN_ERROR; |
| 83 | - if (*bytes + templateBytes > JANUS_MAX_TEMPLATE_SIZE) | |
| 83 | + if (*bytes + templateBytes > janus_max_template_size()) | |
| 84 | 84 | break; |
| 85 | 85 | memcpy(pos, m.data, templateBytes); |
| 86 | 86 | *bytes += templateBytes; |
| ... | ... | @@ -94,21 +94,49 @@ janus_error janus_finalize_template(janus_incomplete_template incomplete_templat |
| 94 | 94 | return JANUS_SUCCESS; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | -janus_error janus_verify(const janus_template a, const janus_template b, float *similarity) | |
| 97 | +janus_error janus_verify(const janus_template a, const size_t a_bytes, const janus_template b, const size_t b_bytes, double *similarity) | |
| 98 | 98 | { |
| 99 | - size_t a_bytes, a_templates, b_bytes, b_templates; | |
| 100 | - a_bytes = *(reinterpret_cast<size_t*>(a)+0); | |
| 99 | + (void) a_bytes; | |
| 100 | + (void) b_bytes; | |
| 101 | + | |
| 102 | + size_t a_template_bytes, a_templates, b_template_bytes, b_templates; | |
| 103 | + a_template_bytes = *(reinterpret_cast<size_t*>(a)+0); | |
| 101 | 104 | a_templates = *(reinterpret_cast<size_t*>(a)+1); |
| 102 | - b_bytes = *(reinterpret_cast<size_t*>(b)+0); | |
| 105 | + b_template_bytes = *(reinterpret_cast<size_t*>(b)+0); | |
| 103 | 106 | b_templates = *(reinterpret_cast<size_t*>(b)+1); |
| 104 | - if (a_bytes != b_bytes) | |
| 107 | + if (a_template_bytes != b_template_bytes) | |
| 105 | 108 | return JANUS_UNKNOWN_ERROR; |
| 106 | 109 | |
| 107 | 110 | float dist = 0; |
| 108 | 111 | for (size_t i=0; i<a_templates; i++) |
| 109 | 112 | for (size_t j=0; j<b_templates; j++) |
| 110 | - dist += distance->compare(cv::Mat(1, a_bytes, CV_8UC1, a+2*sizeof(size_t)+i*a_bytes), | |
| 111 | - cv::Mat(1, b_bytes, CV_8UC1, b+2*sizeof(size_t)+i*b_bytes)); | |
| 113 | + dist += distance->compare(cv::Mat(1, a_template_bytes, CV_8UC1, a+2*sizeof(size_t)+i*a_template_bytes), | |
| 114 | + cv::Mat(1, b_template_bytes, CV_8UC1, b+2*sizeof(size_t)+i*b_template_bytes)); | |
| 112 | 115 | *similarity = a_templates * b_templates / dist; |
| 113 | 116 | return JANUS_SUCCESS; |
| 114 | 117 | } |
| 118 | + | |
| 119 | +struct janus_incomplete_gallery_type | |
| 120 | +{ | |
| 121 | + QList< QPair<janus_template, janus_template_id> > templates; | |
| 122 | +}; | |
| 123 | + | |
| 124 | +janus_error janus_initialize_gallery(janus_incomplete_gallery *incomplete_gallery) | |
| 125 | +{ | |
| 126 | + *incomplete_gallery = new janus_incomplete_gallery_type(); | |
| 127 | + return JANUS_SUCCESS; | |
| 128 | +} | |
| 129 | + | |
| 130 | +janus_error janus_add_template(const janus_template template_, const size_t bytes, const janus_template_id template_id, janus_incomplete_gallery incomplete_gallery) | |
| 131 | +{ | |
| 132 | + (void) bytes; | |
| 133 | + incomplete_gallery->templates.append(QPair<janus_template, janus_template_id>(template_, template_id)); | |
| 134 | + return JANUS_SUCCESS; | |
| 135 | +} | |
| 136 | + | |
| 137 | +janus_error janus_finalize_gallery(janus_incomplete_gallery incomplete_gallery, const char *gallery_file) | |
| 138 | +{ | |
| 139 | + (void) incomplete_gallery; | |
| 140 | + (void) gallery_file; | |
| 141 | + return JANUS_SUCCESS; | |
| 142 | +} | ... | ... |
openbr/openbr.cpp
| ... | ... | @@ -53,6 +53,12 @@ void br_compare(const char *target_gallery, const char *query_gallery, const cha |
| 53 | 53 | Compare(File(target_gallery), File(query_gallery), File(output)); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | +void br_compare_n(int num_targets, const char *target_galleries[], const char *query_gallery, const char *output) | |
| 57 | +{ | |
| 58 | + if (num_targets > 1) Compare(QtUtils::toStringList(num_targets, target_galleries).join(";")+"(separator=;)", File(query_gallery), File(output)); | |
| 59 | + else Compare(File(target_galleries[0]), File(query_gallery), File(output)); | |
| 60 | +} | |
| 61 | + | |
| 56 | 62 | void br_pairwise_compare(const char *target_gallery, const char *query_gallery, const char *output) |
| 57 | 63 | { |
| 58 | 64 | PairwiseCompare(File(target_gallery), File(query_gallery), File(output)); |
| ... | ... | @@ -323,6 +329,14 @@ unsigned char *br_unload_img(br_template tmpl) |
| 323 | 329 | return t->m().data; |
| 324 | 330 | } |
| 325 | 331 | |
| 332 | +br_template_list br_template_list_from_buffer(const char *buf, int len) | |
| 333 | +{ | |
| 334 | + QByteArray arr(buf, len); | |
| 335 | + TemplateList *tl = new TemplateList(); | |
| 336 | + *tl = TemplateList::fromBuffer(arr); | |
| 337 | + return (br_template_list)tl; | |
| 338 | +} | |
| 339 | + | |
| 326 | 340 | void br_free_template(br_template tmpl) |
| 327 | 341 | { |
| 328 | 342 | Template *t = reinterpret_cast<Template*>(tmpl); |
| ... | ... | @@ -335,6 +349,12 @@ void br_free_template_list(br_template_list tl) |
| 335 | 349 | delete realTL; |
| 336 | 350 | } |
| 337 | 351 | |
| 352 | +void br_free_output(br_matrix_output output) | |
| 353 | +{ | |
| 354 | + MatrixOutput *matOut = reinterpret_cast<MatrixOutput*>(output); | |
| 355 | + delete matOut; | |
| 356 | +} | |
| 357 | + | |
| 338 | 358 | int br_img_rows(br_template tmpl) |
| 339 | 359 | { |
| 340 | 360 | Template *t = reinterpret_cast<Template*>(tmpl); |
| ... | ... | @@ -359,6 +379,12 @@ bool br_img_is_empty(br_template tmpl) |
| 359 | 379 | return t->m().empty(); |
| 360 | 380 | } |
| 361 | 381 | |
| 382 | +const char* br_get_filename(br_template tmpl) | |
| 383 | +{ | |
| 384 | + Template *t = reinterpret_cast<Template*>(tmpl); | |
| 385 | + return t->file.name.toStdString().c_str(); | |
| 386 | +} | |
| 387 | + | |
| 362 | 388 | void br_set_filename(br_template tmpl, const char *filename) |
| 363 | 389 | { |
| 364 | 390 | Template *t = reinterpret_cast<Template*>(tmpl); |
| ... | ... | @@ -391,6 +417,21 @@ void br_enroll_template_list(br_template_list tl) |
| 391 | 417 | Enroll(*realTL); |
| 392 | 418 | } |
| 393 | 419 | |
| 420 | +br_matrix_output br_compare_template_lists(br_template_list target, br_template_list query) | |
| 421 | +{ | |
| 422 | + TemplateList *targetTL = reinterpret_cast<TemplateList*>(target); | |
| 423 | + TemplateList *queryTL = reinterpret_cast<TemplateList*>(query); | |
| 424 | + MatrixOutput *output = MatrixOutput::make(targetTL->files(), queryTL->files()); | |
| 425 | + CompareTemplateLists(*targetTL, *queryTL, output); | |
| 426 | + return (br_matrix_output)output; | |
| 427 | +} | |
| 428 | + | |
| 429 | +float br_get_matrix_output_at(br_matrix_output output, int row, int col) | |
| 430 | +{ | |
| 431 | + MatrixOutput *matOut = reinterpret_cast<MatrixOutput*>(output); | |
| 432 | + return matOut->data.at<float>(row, col); | |
| 433 | +} | |
| 434 | + | |
| 394 | 435 | br_template br_get_template(br_template_list tl, int index) |
| 395 | 436 | { |
| 396 | 437 | TemplateList *realTL = reinterpret_cast<TemplateList*>(tl); |
| ... | ... | @@ -412,7 +453,7 @@ br_gallery br_make_gallery(const char *gallery) |
| 412 | 453 | br_template_list br_load_from_gallery(br_gallery gallery) |
| 413 | 454 | { |
| 414 | 455 | Gallery *gal = reinterpret_cast<Gallery*>(gallery); |
| 415 | - TemplateList *tl = static_cast<TemplateList*>(malloc(sizeof(TemplateList))); | |
| 456 | + TemplateList *tl = new TemplateList(); | |
| 416 | 457 | *tl = gal->read(); |
| 417 | 458 | return (br_template_list)tl; |
| 418 | 459 | } | ... | ... |
openbr/openbr.h
| ... | ... | @@ -102,6 +102,12 @@ BR_EXPORT void br_combine_masks(int num_input_masks, const char *input_masks[], |
| 102 | 102 | */ |
| 103 | 103 | BR_EXPORT void br_compare(const char *target_gallery, const char *query_gallery, const char *output = ""); |
| 104 | 104 | |
| 105 | +/*! | |
| 106 | + * \brief Convenience function for comparing to multiple targets. | |
| 107 | + * \see br_compare | |
| 108 | + */ | |
| 109 | +BR_EXPORT void br_compare_n(int num_targets, const char *target_galleries[], const char *query_gallery, const char *output); | |
| 110 | + | |
| 105 | 111 | BR_EXPORT void br_pairwise_compare(const char *target_gallery, const char *query_gallery, const char *output = ""); |
| 106 | 112 | |
| 107 | 113 | /*! |
| ... | ... | @@ -437,6 +443,7 @@ BR_EXPORT void br_slave_process(const char * baseKey); |
| 437 | 443 | typedef void* br_template; |
| 438 | 444 | typedef void* br_template_list; |
| 439 | 445 | typedef void* br_gallery; |
| 446 | +typedef void* br_matrix_output; | |
| 440 | 447 | /*! |
| 441 | 448 | * \brief Load an image from a string buffer. |
| 442 | 449 | * Easy way to pass an image in memory from another programming language to openbr. |
| ... | ... | @@ -452,6 +459,12 @@ BR_EXPORT br_template br_load_img(const char *data, int len); |
| 452 | 459 | */ |
| 453 | 460 | BR_EXPORT unsigned char* br_unload_img(br_template tmpl); |
| 454 | 461 | /*! |
| 462 | + * \brief Deserialize a br::TemplateList from a buffer. | |
| 463 | + * Can be the buffer for a .gal file, | |
| 464 | + * since they are just a TemplateList serialized to disk. | |
| 465 | + */ | |
| 466 | +BR_EXPORT br_template_list br_template_list_from_buffer(const char *buf, int len); | |
| 467 | +/*! | |
| 455 | 468 | * \brief Free a br::Template's memory. |
| 456 | 469 | */ |
| 457 | 470 | BR_EXPORT void br_free_template(br_template tmpl); |
| ... | ... | @@ -460,6 +473,10 @@ BR_EXPORT void br_free_template(br_template tmpl); |
| 460 | 473 | */ |
| 461 | 474 | BR_EXPORT void br_free_template_list(br_template_list tl); |
| 462 | 475 | /*! |
| 476 | + * \brief Free a br::Output's memory. | |
| 477 | + */ | |
| 478 | +BR_EXPORT void br_free_output(br_matrix_output output); | |
| 479 | +/*! | |
| 463 | 480 | * \brief Get the number of rows in an image. |
| 464 | 481 | * \param tmpl Pointer to a br::Template. |
| 465 | 482 | */ |
| ... | ... | @@ -479,7 +496,11 @@ BR_EXPORT int br_img_channels(br_template tmpl); |
| 479 | 496 | */ |
| 480 | 497 | BR_EXPORT bool br_img_is_empty(br_template tmpl); |
| 481 | 498 | /*! |
| 482 | - * \brief Set the filename for a template. | |
| 499 | + * \brief Get the filename for a br::Template | |
| 500 | + */ | |
| 501 | +BR_EXPORT const char* br_get_filename(br_template tmpl); | |
| 502 | +/*! | |
| 503 | + * \brief Set the filename for a br::Template. | |
| 483 | 504 | */ |
| 484 | 505 | BR_EXPORT void br_set_filename(br_template tmpl, const char *filename); |
| 485 | 506 | /*! |
| ... | ... | @@ -493,10 +514,19 @@ BR_EXPORT const char* br_get_metadata_string(br_template, const char *key); |
| 493 | 514 | BR_EXPORT br_template_list br_enroll_template(br_template tmpl); |
| 494 | 515 | /*! |
| 495 | 516 | * \brief Enroll a br::TemplateList from the C API! |
| 496 | - * \param tmpl Pointer to a br::TemplateList. | |
| 517 | + * \param tl Pointer to a br::TemplateList. | |
| 497 | 518 | */ |
| 498 | 519 | BR_EXPORT void br_enroll_template_list(br_template_list tl); |
| 499 | 520 | /*! |
| 521 | + * \brief Compare br::TemplateLists from the C API! | |
| 522 | + * \return Pointer to a br::MatrixOutput. | |
| 523 | + */ | |
| 524 | +BR_EXPORT br_matrix_output br_compare_template_lists(br_template_list target, br_template_list query); | |
| 525 | +/*! | |
| 526 | + * \brief Get a value in the br::MatrixOutput. | |
| 527 | + */ | |
| 528 | +BR_EXPORT float br_get_matrix_output_at(br_matrix_output output, int row, int col); | |
| 529 | +/*! | |
| 500 | 530 | * \brief Get a pointer to a br::Template at a specified index. |
| 501 | 531 | * \param tl Pointer to a br::TemplateList. |
| 502 | 532 | * \param index The index of the br::Template. | ... | ... |
openbr/openbr_plugin.cpp
| ... | ... | @@ -863,7 +863,7 @@ void br::Context::printStatus() |
| 863 | 863 | const float p = progress(); |
| 864 | 864 | if (p < 1) { |
| 865 | 865 | int s = timeRemaining(); |
| 866 | - fprintf(stderr, "%05.2f%% REMAINING=%s COUNT=%g \r", 100 * p, QtUtils::toTime(s/1000.0f).toStdString().c_str(), totalSteps); | |
| 866 | + fprintf(stderr, "%05.2f%% ELAPSED=%s REMAINING=%s COUNT=%g/%g \r", p*100, QtUtils::toTime(Globals->startTime.elapsed()/1000.0f).toStdString().c_str(), QtUtils::toTime(s).toStdString().c_str(), Globals->currentStep, Globals->totalSteps); | |
| 867 | 867 | } |
| 868 | 868 | } |
| 869 | 869 | ... | ... |
openbr/openbr_plugin.h
| ... | ... | @@ -332,6 +332,20 @@ private: |
| 332 | 332 | void init(const QString &file); |
| 333 | 333 | }; |
| 334 | 334 | |
| 335 | +/*!< \brief Specialization for boolean type. */ | |
| 336 | +template <> | |
| 337 | +inline bool File::get<bool>(const QString &key, const bool &defaultValue) const | |
| 338 | +{ | |
| 339 | + return getBool(key, defaultValue); | |
| 340 | +} | |
| 341 | + | |
| 342 | +/*!< \brief Specialization for boolean type. */ | |
| 343 | +template <> | |
| 344 | +inline bool File::get<bool>(const QString &key) const | |
| 345 | +{ | |
| 346 | + return getBool(key); | |
| 347 | +} | |
| 348 | + | |
| 335 | 349 | BR_EXPORT QDebug operator<<(QDebug dbg, const File &file); /*!< \brief Prints br::File::flat() to \c stderr. */ |
| 336 | 350 | BR_EXPORT QDataStream &operator<<(QDataStream &stream, const File &file); /*!< \brief Serializes the file to a stream. */ |
| 337 | 351 | BR_EXPORT QDataStream &operator>>(QDataStream &stream, File &file); /*!< \brief Deserializes the file from a stream. */ |
| ... | ... | @@ -469,7 +483,7 @@ struct TemplateList : public QList<Template> |
| 469 | 483 | } |
| 470 | 484 | |
| 471 | 485 | /*! |
| 472 | - * \brief Returns a #br::TemplateList containing templates with one matrix at the specified index \em index. | |
| 486 | + * \brief Returns a list of #br::TemplateList with each #br::Template in a given #br::TemplateList containing the number of matrices specified by \em partitionSizes. | |
| 473 | 487 | */ |
| 474 | 488 | QList<TemplateList> partition(const QList<int> &partitionSizes) const |
| 475 | 489 | { |
| ... | ... | @@ -1329,6 +1343,11 @@ BR_EXPORT void Enroll(TemplateList &tmpl); |
| 1329 | 1343 | * \see br_compare |
| 1330 | 1344 | */ |
| 1331 | 1345 | BR_EXPORT void Compare(const File &targetGallery, const File &queryGallery, const File &output); |
| 1346 | +/*! | |
| 1347 | + * \brief High-level function for comparing templates. | |
| 1348 | + */ | |
| 1349 | +BR_EXPORT void CompareTemplateLists(const TemplateList &target, const TemplateList &query, Output *output); | |
| 1350 | + | |
| 1332 | 1351 | |
| 1333 | 1352 | /*! |
| 1334 | 1353 | * \brief High-level function for doing a series of pairwise comparisons. | ... | ... |
openbr/plugins/distance.cpp
| ... | ... | @@ -179,58 +179,93 @@ BR_REGISTER(Distance, PipeDistance) |
| 179 | 179 | |
| 180 | 180 | /*! |
| 181 | 181 | * \ingroup distances |
| 182 | - * \brief Computes an operation on distances across multiple matrices of compared templates | |
| 182 | + * \brief Fuses similarity scores across multiple matrices of compared templates | |
| 183 | 183 | * \author Scott Klum \cite sklum |
| 184 | 184 | * \note Operation: Mean, sum, min, max are supported. |
| 185 | 185 | */ |
| 186 | -class OperationDistance : public Distance | |
| 186 | +class FuseDistance : public Distance | |
| 187 | 187 | { |
| 188 | 188 | Q_OBJECT |
| 189 | 189 | Q_ENUMS(Operation) |
| 190 | - Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) | |
| 190 | + Q_PROPERTY(QString description READ get_description WRITE set_description RESET reset_description STORED false) | |
| 191 | 191 | Q_PROPERTY(Operation operation READ get_operation WRITE set_operation RESET reset_operation STORED false) |
| 192 | + Q_PROPERTY(QList<float> weights READ get_weights WRITE set_weights RESET reset_weights STORED false) | |
| 193 | + | |
| 194 | + QList<br::Distance*> distances; | |
| 192 | 195 | |
| 193 | 196 | public: |
| 194 | 197 | /*!< */ |
| 195 | 198 | enum Operation {Mean, Sum, Max, Min}; |
| 196 | 199 | |
| 197 | 200 | private: |
| 198 | - BR_PROPERTY(br::Distance*, distance, make("Dist(L2)")) | |
| 201 | + BR_PROPERTY(QString, description, "IdenticalDistance") | |
| 199 | 202 | BR_PROPERTY(Operation, operation, Mean) |
| 203 | + BR_PROPERTY(QList<float>, weights, QList<float>()) | |
| 200 | 204 | |
| 201 | 205 | void train(const TemplateList &src) |
| 202 | 206 | { |
| 203 | - distance->train(src); | |
| 207 | + // Partition the templates by matrix | |
| 208 | + QList<int> split; | |
| 209 | + for (int i=0; i<src.at(0).size(); i++) split.append(1); | |
| 210 | + | |
| 211 | + QList<TemplateList> partitionedSrc = src.partition(split); | |
| 212 | + | |
| 213 | + while (distances.size() < partitionedSrc.size()) | |
| 214 | + distances.append(make(description)); | |
| 215 | + | |
| 216 | + // Train on each of the partitions | |
| 217 | + for (int i=0; i<distances.size(); i++) | |
| 218 | + distances[i]->train(partitionedSrc[i]); | |
| 204 | 219 | } |
| 205 | 220 | |
| 206 | 221 | float compare(const Template &a, const Template &b) const |
| 207 | 222 | { |
| 208 | 223 | if (a.size() != b.size()) qFatal("Comparison size mismatch"); |
| 209 | 224 | |
| 210 | - QList<float> distances; | |
| 211 | - for (int i = 0; i < a.size(); i++) | |
| 212 | - distances.append(distance->compare(a[i],b[i])); | |
| 225 | + QList<float> scores; | |
| 226 | + for (int i=0; i<distances.size(); i++) { | |
| 227 | + float weight; | |
| 228 | + weights.isEmpty() ? weight = 1. : weight = weights[i]; | |
| 229 | + scores.append(weight*distances[i]->compare(Template(a.file, a[i]),Template(b.file, b[i]))); | |
| 230 | + } | |
| 213 | 231 | |
| 214 | 232 | switch (operation) { |
| 215 | 233 | case Mean: |
| 216 | - return std::accumulate(distances.begin(),distances.end(),0.0)/(float)distances.size(); | |
| 234 | + return std::accumulate(scores.begin(),scores.end(),0.0)/(float)scores.size(); | |
| 217 | 235 | break; |
| 218 | 236 | case Sum: |
| 219 | - return std::accumulate(distances.begin(),distances.end(),0.0); | |
| 237 | + return std::accumulate(scores.begin(),scores.end(),0.0); | |
| 220 | 238 | break; |
| 221 | 239 | case Min: |
| 222 | - return *std::min_element(distances.begin(),distances.end()); | |
| 240 | + return *std::min_element(scores.begin(),scores.end()); | |
| 223 | 241 | break; |
| 224 | 242 | case Max: |
| 225 | - return *std::max_element(distances.begin(),distances.end()); | |
| 243 | + return *std::max_element(scores.begin(),scores.end()); | |
| 226 | 244 | break; |
| 227 | 245 | default: |
| 228 | 246 | qFatal("Invalid operation."); |
| 229 | 247 | } |
| 230 | 248 | } |
| 249 | + | |
| 250 | + void store(QDataStream &stream) const | |
| 251 | + { | |
| 252 | + stream << distances.size(); | |
| 253 | + foreach (Distance *distance, distances) | |
| 254 | + distance->store(stream); | |
| 255 | + } | |
| 256 | + | |
| 257 | + void load(QDataStream &stream) | |
| 258 | + { | |
| 259 | + int numDistances; | |
| 260 | + stream >> numDistances; | |
| 261 | + while (distances.size() < numDistances) | |
| 262 | + distances.append(make(description)); | |
| 263 | + foreach (Distance *distance, distances) | |
| 264 | + distance->load(stream); | |
| 265 | + } | |
| 231 | 266 | }; |
| 232 | 267 | |
| 233 | -BR_REGISTER(Distance, OperationDistance) | |
| 268 | +BR_REGISTER(Distance, FuseDistance) | |
| 234 | 269 | |
| 235 | 270 | /*! |
| 236 | 271 | * \ingroup distances | ... | ... |
openbr/plugins/gallery.cpp
| ... | ... | @@ -99,12 +99,12 @@ class galGallery : public Gallery |
| 99 | 99 | void init() |
| 100 | 100 | { |
| 101 | 101 | gallery.setFileName(file); |
| 102 | - if (file.get<bool>("remove", false)) | |
| 102 | + if (file.get<bool>("remove")) | |
| 103 | 103 | gallery.remove(); |
| 104 | 104 | QtUtils::touchDir(gallery); |
| 105 | 105 | QFile::OpenMode mode = QFile::ReadWrite; |
| 106 | 106 | |
| 107 | - if (file.contains("append")) | |
| 107 | + if (file.get<bool>("append")) | |
| 108 | 108 | mode |= QFile::Append; |
| 109 | 109 | |
| 110 | 110 | if (!gallery.open(mode)) | ... | ... |
openbr/plugins/gui.cpp
| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 | |
| 14 | 14 | #include <opencv2/imgproc/imgproc.hpp> |
| 15 | 15 | #include "openbr_internal.h" |
| 16 | +#include "openbr/gui/utility.h" | |
| 16 | 17 | |
| 17 | 18 | using namespace cv; |
| 18 | 19 | |
| ... | ... | @@ -121,45 +122,6 @@ public slots: |
| 121 | 122 | } |
| 122 | 123 | }; |
| 123 | 124 | |
| 124 | -QImage toQImage(const Mat &mat) | |
| 125 | -{ | |
| 126 | - // Convert to 8U depth | |
| 127 | - Mat mat8u; | |
| 128 | - if (mat.depth() != CV_8U) { | |
| 129 | - double globalMin = std::numeric_limits<double>::max(); | |
| 130 | - double globalMax = -std::numeric_limits<double>::max(); | |
| 131 | - | |
| 132 | - std::vector<Mat> mv; | |
| 133 | - split(mat, mv); | |
| 134 | - for (size_t i=0; i<mv.size(); i++) { | |
| 135 | - double min, max; | |
| 136 | - minMaxLoc(mv[i], &min, &max); | |
| 137 | - globalMin = std::min(globalMin, min); | |
| 138 | - globalMax = std::max(globalMax, max); | |
| 139 | - } | |
| 140 | - assert(globalMax >= globalMin); | |
| 141 | - | |
| 142 | - double range = globalMax - globalMin; | |
| 143 | - if (range != 0) { | |
| 144 | - double scale = 255 / range; | |
| 145 | - convertScaleAbs(mat, mat8u, scale, -(globalMin * scale)); | |
| 146 | - } else { | |
| 147 | - // Monochromatic | |
| 148 | - mat8u = Mat(mat.size(), CV_8UC1, Scalar((globalMin+globalMax)/2)); | |
| 149 | - } | |
| 150 | - } else { | |
| 151 | - mat8u = mat; | |
| 152 | - } | |
| 153 | - | |
| 154 | - // Convert to 3 channels | |
| 155 | - Mat mat8uc3; | |
| 156 | - if (mat8u.channels() == 4) cvtColor(mat8u, mat8uc3, CV_BGRA2RGB); | |
| 157 | - else if (mat8u.channels() == 3) cvtColor(mat8u, mat8uc3, CV_BGR2RGB); | |
| 158 | - else if (mat8u.channels() == 1) cvtColor(mat8u, mat8uc3, CV_GRAY2RGB); | |
| 159 | - | |
| 160 | - return QImage(mat8uc3.data, mat8uc3.cols, mat8uc3.rows, 3*mat8uc3.cols, QImage::Format_RGB888).copy(); | |
| 161 | -} | |
| 162 | - | |
| 163 | 125 | class DisplayWindow : public QLabel |
| 164 | 126 | { |
| 165 | 127 | Q_OBJECT | ... | ... |
openbr/plugins/independent.cpp
| ... | ... | @@ -156,8 +156,8 @@ class IndependentTransform : public MetaTransform |
| 156 | 156 | |
| 157 | 157 | QFutureSynchronizer<void> futures; |
| 158 | 158 | for (int i=0; i<templatesList.size(); i++) |
| 159 | - futures.addFuture(QtConcurrent::run(_train, transforms[i], &templatesList[i])); | |
| 160 | - futures.waitForFinished(); | |
| 159 | + futures.addFuture(QtConcurrent::run(_train, transforms[i], &templatesList[i])); | |
| 160 | + futures.waitForFinished(); | |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | void project(const Template &src, Template &dst) const | ... | ... |
openbr/plugins/misc.cpp
| ... | ... | @@ -514,28 +514,16 @@ class ProgressCounterTransform : public TimeVaryingTransform |
| 514 | 514 | void projectUpdate(const TemplateList &src, TemplateList &dst) |
| 515 | 515 | { |
| 516 | 516 | dst = src; |
| 517 | - qint64 elapsed = timer.elapsed(); | |
| 518 | - calls++; | |
| 519 | - set_calls++; | |
| 520 | - // updated every 10 seconds | |
| 521 | - if (elapsed > 5 * 1000) { | |
| 522 | - float f_elapsed = elapsed / 1000.0f; | |
| 523 | - // remaining calls (according to our input variable) | |
| 524 | - int remaining = totalTemplates - calls; | |
| 525 | - // calls / second | |
| 526 | - float speed = set_calls / f_elapsed; | |
| 527 | - | |
| 528 | - float p = 100 * float(calls) / totalTemplates; | |
| 529 | - | |
| 530 | - // seconds remaining | |
| 531 | - int s = float(remaining) / speed; | |
| 532 | 517 | |
| 533 | - fprintf(stderr, "%05.2f%% ELAPSED=%s REMAINING=%s COUNT=%g \r", p, QtUtils::toTime(Globals->startTime.elapsed()/1000.0f).toStdString().c_str(), QtUtils::toTime(s).toStdString().c_str(), float(calls)); | |
| 518 | + qint64 elapsed = timer.elapsed(); | |
| 534 | 519 | |
| 520 | + // updated every second | |
| 521 | + if (elapsed > 1000) { | |
| 522 | + Globals->printStatus(); | |
| 535 | 523 | timer.start(); |
| 536 | - set_calls = 0; | |
| 537 | 524 | } |
| 538 | 525 | |
| 526 | + Globals->currentStep++; | |
| 539 | 527 | |
| 540 | 528 | return; |
| 541 | 529 | } |
| ... | ... | @@ -548,24 +536,18 @@ class ProgressCounterTransform : public TimeVaryingTransform |
| 548 | 536 | void finalize(TemplateList & data) |
| 549 | 537 | { |
| 550 | 538 | (void) data; |
| 551 | - float p = 100 * float(calls) / totalTemplates; | |
| 552 | - qDebug("%05.2f%% ELAPSED=%s REMAINING=%s COUNT=%g \r", p, QtUtils::toTime(Globals->startTime.elapsed()/1000.0f).toStdString().c_str(), QtUtils::toTime(0).toStdString().c_str(), float(calls)); | |
| 539 | + float p = br_progress(); | |
| 540 | + qDebug("%05.2f%% ELAPSED=%s REMAINING=%s COUNT=%g/%g \r", p*100., QtUtils::toTime(Globals->startTime.elapsed()/1000.0f).toStdString().c_str(), QtUtils::toTime(0).toStdString().c_str(), Globals->currentStep, Globals->totalSteps); | |
| 553 | 541 | } |
| 554 | 542 | |
| 555 | 543 | void init() |
| 556 | 544 | { |
| 557 | - calls = 0; | |
| 558 | - set_calls = 0; | |
| 559 | 545 | timer.start(); |
| 560 | 546 | } |
| 561 | 547 | |
| 562 | 548 | public: |
| 563 | 549 | ProgressCounterTransform() : TimeVaryingTransform(false,false) {} |
| 564 | - bool initialized; | |
| 565 | 550 | QElapsedTimer timer; |
| 566 | - qint64 calls; | |
| 567 | - qint64 set_calls; | |
| 568 | - | |
| 569 | 551 | }; |
| 570 | 552 | |
| 571 | 553 | BR_REGISTER(Transform, ProgressCounterTransform) | ... | ... |
openbr/plugins/quality.cpp
| ... | ... | @@ -173,7 +173,7 @@ class MatchProbabilityDistance : public Distance |
| 173 | 173 | for (int j=0; j<i; j++) { |
| 174 | 174 | const float score = matrixOutput.data()->data.at<float>(i, j); |
| 175 | 175 | if (score == -std::numeric_limits<float>::max()) continue; |
| 176 | - if (crossModality) if(src[i].file.get<QString>("MODALITY") == src[j].file.get<QString>("MODALITY")) continue; | |
| 176 | + if (crossModality && src[i].file.get<QString>("MODALITY") == src[j].file.get<QString>("MODALITY")) continue; | |
| 177 | 177 | if (labels[i] == labels[j]) genuineScores.append(score); |
| 178 | 178 | else impostorScores.append(score); |
| 179 | 179 | } |
| ... | ... | @@ -211,6 +211,65 @@ protected: |
| 211 | 211 | |
| 212 | 212 | BR_REGISTER(Distance, MatchProbabilityDistance) |
| 213 | 213 | |
| 214 | +class ZScoreDistance : public Distance | |
| 215 | +{ | |
| 216 | + Q_OBJECT | |
| 217 | + Q_PROPERTY(br::Distance* distance READ get_distance WRITE set_distance RESET reset_distance STORED false) | |
| 218 | + Q_PROPERTY(bool crossModality READ get_crossModality WRITE set_crossModality RESET reset_crossModality STORED false) | |
| 219 | + BR_PROPERTY(br::Distance*, distance, make("Dist(L2)")) | |
| 220 | + BR_PROPERTY(bool, crossModality, false) | |
| 221 | + | |
| 222 | + float min, max; | |
| 223 | + double mean, stddev; | |
| 224 | + | |
| 225 | + void train(const TemplateList &src) | |
| 226 | + { | |
| 227 | + distance->train(src); | |
| 228 | + | |
| 229 | + QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size()))); | |
| 230 | + distance->compare(src, src, matrixOutput.data()); | |
| 231 | + | |
| 232 | + QList<float> scores; | |
| 233 | + scores.reserve(src.size()*src.size()); | |
| 234 | + for (int i=0; i<src.size(); i++) { | |
| 235 | + for (int j=0; j<i; j++) { | |
| 236 | + const float score = matrixOutput.data()->data.at<float>(i, j); | |
| 237 | + if (score == -std::numeric_limits<float>::max()) continue; | |
| 238 | + if (crossModality && src[i].file.get<QString>("MODALITY") == src[j].file.get<QString>("MODALITY")) continue; | |
| 239 | + scores.append(score); | |
| 240 | + } | |
| 241 | + } | |
| 242 | + | |
| 243 | + Common::MinMax(scores, &min, &max); | |
| 244 | + Common::MeanStdDev(scores, &mean, &stddev); | |
| 245 | + | |
| 246 | + if (stddev == 0) qFatal("Stddev is 0."); | |
| 247 | + } | |
| 248 | + | |
| 249 | + float compare(const Template &target, const Template &query) const | |
| 250 | + { | |
| 251 | + float score = distance->compare(target,query); | |
| 252 | + if (score == -std::numeric_limits<float>::max()) score = (min - mean) / stddev; | |
| 253 | + else if (score == std::numeric_limits<float>::max()) score = (max - mean) / stddev; | |
| 254 | + else score = (score - mean) / stddev; | |
| 255 | + return score; | |
| 256 | + } | |
| 257 | + | |
| 258 | + void store(QDataStream &stream) const | |
| 259 | + { | |
| 260 | + distance->store(stream); | |
| 261 | + stream << min << max << mean << stddev; | |
| 262 | + } | |
| 263 | + | |
| 264 | + void load(QDataStream &stream) | |
| 265 | + { | |
| 266 | + distance->load(stream); | |
| 267 | + stream >> min >> max >> mean >> stddev; | |
| 268 | + } | |
| 269 | +}; | |
| 270 | + | |
| 271 | +BR_REGISTER(Distance, ZScoreDistance) | |
| 272 | + | |
| 214 | 273 | /*! |
| 215 | 274 | * \ingroup distances |
| 216 | 275 | * \brief Match Probability modification for heat maps \cite klare12 | ... | ... |
openbr/plugins/slidingwindow.cpp
| ... | ... | @@ -216,7 +216,7 @@ static TemplateList cropTrainingSamples(const TemplateList &data, const float as |
| 216 | 216 | |
| 217 | 217 | /*! |
| 218 | 218 | * \ingroup transforms |
| 219 | - * \brief . | |
| 219 | + * \brief Document me | |
| 220 | 220 | * \author Austin Blanton \cite imaus10 |
| 221 | 221 | */ |
| 222 | 222 | class BuildScalesTransform : public Transform | ... | ... |
openbr/plugins/validate.cpp
| ... | ... | @@ -104,15 +104,13 @@ class CrossValidateTransform : public MetaTransform |
| 104 | 104 | // since it is assumed that the allPartitions |
| 105 | 105 | // flag is only used during comparison |
| 106 | 106 | // (i.e. only used when making a mask) |
| 107 | - if (src.file.getBool("Train", false)) dst = src; | |
| 108 | - else { | |
| 109 | - // If we want to duplicate templates but use the same training data | |
| 110 | - // for all partitions (i.e. transforms.size() == 1), we need to | |
| 111 | - // restrict the partition | |
| 112 | - int partition = src.file.get<int>("Partition", 0); | |
| 113 | - partition = (partition >= transforms.size()) ? 0 : partition; | |
| 114 | - transforms[partition]->project(src, dst); | |
| 115 | - } | |
| 107 | + | |
| 108 | + // If we want to duplicate templates but use the same training data | |
| 109 | + // for all partitions (i.e. transforms.size() == 1), we need to | |
| 110 | + // restrict the partition | |
| 111 | + int partition = src.file.get<int>("Partition", 0); | |
| 112 | + partition = (partition >= transforms.size()) ? 0 : partition; | |
| 113 | + transforms[partition]->project(src, dst); | |
| 116 | 114 | } |
| 117 | 115 | |
| 118 | 116 | void store(QDataStream &stream) const | ... | ... |
scripts/brpy/__init__.py
0 โ 100644
| 1 | +from ctypes import * | |
| 2 | +import os | |
| 3 | + | |
| 4 | +def _string_args(n): | |
| 5 | + s = [] | |
| 6 | + for i in range(n): | |
| 7 | + s.append(c_char_p) | |
| 8 | + return s | |
| 9 | + | |
| 10 | +def _var_string_args(n): | |
| 11 | + s = [c_int, POINTER(c_char_p)] | |
| 12 | + s.extend(_string_args(n)) | |
| 13 | + return s | |
| 14 | + | |
| 15 | +def init_brpy(br_loc='/usr/local/lib'): | |
| 16 | + """Takes the ctypes lib object for br and initializes all function inputs and outputs""" | |
| 17 | + br_loc += '/libopenbr.%s' | |
| 18 | + if os.path.exists(br_loc % 'dylib'): | |
| 19 | + br = cdll.LoadLibrary(br_loc % 'dylib') | |
| 20 | + elif os.path.exists(br_loc % 'so'): | |
| 21 | + br = cdll.LoadLibrary(br_loc % 'so') | |
| 22 | + else: | |
| 23 | + raise ValueError('Neither .so nor .dylib libopenbr found in %s' % br_loc) | |
| 24 | + | |
| 25 | + plot_args = _var_string_args(1) + [c_bool] | |
| 26 | + br.br_about.restype = c_char_p | |
| 27 | + br.br_cat.argtypes = _var_string_args(1) | |
| 28 | + br.br_cluster.argtypes = [c_int, POINTER(c_char_p), c_float, c_char_p] | |
| 29 | + br.br_combine_masks.argtypes = _var_string_args(2) | |
| 30 | + br.br_compare.argtypes = _string_args(3) | |
| 31 | + br.br_compare_n.argtypes = [c_int, POINTER(c_char_p)] + _string_args(2) | |
| 32 | + br.br_pairwise_compare.argtypes = _string_args(3) | |
| 33 | + br.br_convert.argtypes = _string_args(3) | |
| 34 | + br.br_enroll.argtypes = _string_args(2) | |
| 35 | + br.br_enroll_n.argtypes = _var_string_args(1) | |
| 36 | + br.br_eval.argtypes = _string_args(3) | |
| 37 | + br.br_eval.restype = c_float | |
| 38 | + br.br_eval_classification.argtypes = _string_args(4) | |
| 39 | + br.br_eval_clustering.argtypes = _string_args(2) | |
| 40 | + br.br_eval_detection.argtypes = _string_args(3) | |
| 41 | + br.br_eval_detection.restype = c_float | |
| 42 | + br.br_eval_landmarking.argtypes = _string_args(3) + [c_int, c_int] | |
| 43 | + br.br_eval_landmarking.restype = c_float | |
| 44 | + br.br_eval_regression.argtypes = _string_args(4) | |
| 45 | + br.br_fuse.argtypes = _var_string_args(3) | |
| 46 | + br.br_initialize.argtypes = _var_string_args(1) | |
| 47 | + br.br_is_classifier.argtypes = [c_char_p] | |
| 48 | + br.br_is_classifier.restype = c_bool | |
| 49 | + br.br_make_mask.argtypes = _string_args(3) | |
| 50 | + br.br_make_pairwise_mask.argtypes = _string_args(3) | |
| 51 | + br.br_most_recent_message.restype = c_char_p | |
| 52 | + br.br_objects.argtypes = _string_args(2) + [c_bool] | |
| 53 | + br.br_objects.restype = c_char_p | |
| 54 | + br.br_plot.argtypes = plot_args | |
| 55 | + br.br_plot.restype = c_bool | |
| 56 | + br.br_plot_detection.argtypes = plot_args | |
| 57 | + br.br_plot_detection.restype = c_bool | |
| 58 | + br.br_plot_landmarking.argtypes = plot_args | |
| 59 | + br.br_plot_landmarking.restype = c_bool | |
| 60 | + br.br_plot_metadata.argtypes = plot_args | |
| 61 | + br.br_plot_metadata.restype = c_bool | |
| 62 | + br.br_progress.restype = c_float | |
| 63 | + br.br_read_pipe.argtypes = [c_char_p, POINTER(c_int), POINTER(POINTER(c_char_p))] | |
| 64 | + br.br_scratch_path.restype = c_char_p | |
| 65 | + br.br_sdk_path.restype = c_char_p | |
| 66 | + br.br_get_header.argtypes = [c_char_p, POINTER(c_char_p), POINTER(c_char_p)] | |
| 67 | + br.br_set_header.argtypes = _string_args(3) | |
| 68 | + br.br_set_property.argtypes = _string_args(2) | |
| 69 | + br.br_time_remaining.restype = c_int | |
| 70 | + br.br_train.argtypes = _string_args(2) | |
| 71 | + br.br_train_n.argtypes = _var_string_args(1) | |
| 72 | + br.br_version.restype = c_char_p | |
| 73 | + br.br_slave_process.argtypes = [c_char_p] | |
| 74 | + br.br_load_img.argtypes = [c_char_p, c_int] | |
| 75 | + br.br_load_img.restype = c_void_p | |
| 76 | + br.br_unload_img.argtypes = [c_void_p] | |
| 77 | + br.br_unload_img.restype = POINTER(c_ubyte) | |
| 78 | + br.br_template_list_from_buffer.argtypes = [c_char_p, c_int] | |
| 79 | + br.br_template_list_from_buffer.restype = c_void_p | |
| 80 | + br.br_free_template.argtypes = [c_void_p] | |
| 81 | + br.br_free_template_list.argtypes = [c_void_p] | |
| 82 | + br.br_free_output.argtypes = [c_void_p] | |
| 83 | + br.br_img_rows.argtypes = [c_void_p] | |
| 84 | + br.br_img_rows.restype = c_int | |
| 85 | + br.br_img_cols.argtypes = [c_void_p] | |
| 86 | + br.br_img_cols.restype = c_int | |
| 87 | + br.br_img_channels.argtypes = [c_void_p] | |
| 88 | + br.br_img_channels.restype = c_int | |
| 89 | + br.br_img_is_empty.argtypes = [c_void_p] | |
| 90 | + br.br_img_is_empty.restype = c_bool | |
| 91 | + br.br_get_filename.argtypes = [c_void_p] | |
| 92 | + br.br_get_filename.restype = c_char_p | |
| 93 | + br.br_set_filename.argtypes = [c_void_p, c_char_p] | |
| 94 | + br.br_get_metadata_string.argtypes = [c_void_p, c_char_p] | |
| 95 | + br.br_get_metadata_string.restype = c_char_p | |
| 96 | + br.br_enroll_template.argtypes = [c_void_p] | |
| 97 | + br.br_enroll_template.restype = c_void_p | |
| 98 | + br.br_enroll_template_list.argtypes = [c_void_p] | |
| 99 | + br.br_enroll_template_list.restype = c_void_p | |
| 100 | + br.br_compare_template_lists.argtypes = [c_void_p, c_void_p] | |
| 101 | + br.br_compare_template_lists.restype = c_void_p | |
| 102 | + br.br_get_matrix_output_at.argtypes = [c_void_p, c_int, c_int] | |
| 103 | + br.br_get_matrix_output_at.restype = c_float | |
| 104 | + br.br_get_template.argtypes = [c_void_p, c_int] | |
| 105 | + br.br_get_template.restype = c_void_p | |
| 106 | + br.br_num_templates.argtypes = [c_void_p] | |
| 107 | + br.br_num_templates.restype = c_int | |
| 108 | + br.br_make_gallery.argtypes = [c_char_p] | |
| 109 | + br.br_make_gallery.restype = c_void_p | |
| 110 | + br.br_load_from_gallery.argtypes = [c_void_p] | |
| 111 | + br.br_load_from_gallery.restype = c_void_p | |
| 112 | + br.br_add_to_gallery.argtypes = [c_void_p, c_void_p] | |
| 113 | + br.br_close_gallery.argtypes = [c_void_p] | |
| 114 | + | |
| 115 | + return br | ... | ... |