From 96cc6f3221a5a3f68924862764b7f2171f56ba52 Mon Sep 17 00:00:00 2001 From: Ralph Lessmann Date: Thu, 3 Feb 2022 15:21:30 +0100 Subject: [PATCH 1/5] adding a method to read the model file from an Android Archive Android Archives AAR contians an asset folder, which is accessible by using the Android Asset Manager. A reference to the Android Asset manager can be obtained from the App using Java/Kotlin. Within a JNI call the reference must be converted into an opaque C pointer. The NDK Asset Manager functions can then be used to load the model file from the AAR assets. --- .../include/nfiq2_algorithm.hpp | 7 ++ .../include/prediction/RandomForestML.h | 16 +++- .../src/nfiq2/nfiq2_algorithm.cpp | 12 ++- .../src/nfiq2/nfiq2_algorithm_impl.cpp | 38 ++++++++-- .../src/nfiq2/nfiq2_algorithm_impl.hpp | 15 ++++ .../src/prediction/RandomForestML.cpp | 73 +++++++++++++++++-- NFIQ2/NFIQ2Api/CMakeLists.txt | 1 + 7 files changed, 145 insertions(+), 17 deletions(-) diff --git a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp index 2ea4df0d..b0b7b1ea 100644 --- a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp +++ b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp @@ -20,6 +20,10 @@ #include #include +#ifdef __ANDROID__ +# include +#endif + namespace NFIQ2 { /** @@ -48,6 +52,9 @@ class Algorithm { * The md5 checksum of the provided file. */ Algorithm(const std::string &fileName, const std::string &fileHash); +#ifdef __ANDROID__ + Algorithm(AAssetManager* assets, const std::string &fileName, const std::string &fileHash); +#endif /** * @brief diff --git a/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h b/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h index 21d619af..da1b526e 100644 --- a/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h +++ b/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h @@ -8,6 +8,11 @@ #include #include +#ifdef __ANDROID__ +#include +#include +#endif + namespace NFIQ2 { namespace Prediction { /** @@ -32,8 +37,15 @@ class RandomForestML { #endif /** Initialize model (When not using embedded parameters). */ - std::string initModule(const std::string &fileName, - const std::string &fileHash); + std::string initModule( + const std::string &fileName, const std::string &fileHash); + +#ifdef __ANDROID__ + /** Initialize model from Android AAR (When not using embedded + * parameters). */ + std::string initModule(AAssetManager *assets, + const std::string &fileName, const std::string &fileHash); +#endif /** * Compute NFIQ2 quality score based on model and provided diff --git a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp index 969e47ea..212914a2 100644 --- a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp +++ b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp @@ -8,8 +8,8 @@ NFIQ2::Algorithm::Algorithm() { } -NFIQ2::Algorithm::Algorithm(const std::string &fileName, - const std::string &fileHash) +NFIQ2::Algorithm::Algorithm( + const std::string &fileName, const std::string &fileHash) : pimpl { new NFIQ2::Algorithm::Impl(fileName, fileHash) } { } @@ -20,6 +20,14 @@ NFIQ2::Algorithm::Algorithm(const NFIQ2::ModelInfo &modelInfoObj) { } +#ifdef __ANDROID__ +NFIQ2::Algorithm::Algorithm(AAssetManager *assets, const std::string &fileName, + const std::string &fileHash) + : pimpl { new NFIQ2::Algorithm::Impl(assets, fileName, fileHash) } +{ +} +#endif + NFIQ2::Algorithm::Algorithm(const Algorithm &rhs) : pimpl(new Impl(*rhs.pimpl)) { diff --git a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp index 9b4f7c37..ab5a06b5 100644 --- a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp +++ b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp @@ -28,14 +28,41 @@ NFIQ2::Algorithm::Impl::Impl() #endif } -NFIQ2::Algorithm::Impl::Impl(const std::string &fileName, +NFIQ2::Algorithm::Impl::Impl( + const std::string &fileName, const std::string &fileHash) + : initialized { false } +{ + // init RF module that takes some time to load the parameters + try { + this->m_parameterHash = m_RandomForestML.initModule( + fileName, fileHash); + this->initialized = true; + } catch (const cv::Exception &e) { + throw Exception(NFIQ2::ErrorCode::BadArguments, + "Could not initialize random forest parameters with " + "external file. Most likely, the file does not exist. " + "Check the path (" + + fileName + ") and hash (" + fileHash + + ") (initial error: " + e.msg + ")."); + } catch (const NFIQ2::Exception &e) { + throw Exception(NFIQ2::ErrorCode::BadArguments, + "Could not initialize random forest parameters with " + "external file. Most likely, the hash is not correct. " + "Check the path (" + + fileName + ") and hash (" + fileHash + + ") (initial error: " + e.what() + ")."); + } +} + +#ifdef __ANDROID__ +NFIQ2::Algorithm::Impl::Impl(AAssetManager *assets, const std::string &fileName, const std::string &fileHash) : initialized { false } { // init RF module that takes some time to load the parameters try { - this->m_parameterHash = m_RandomForestML.initModule(fileName, - fileHash); + this->m_parameterHash = m_RandomForestML.initModule( + assets, fileName, fileHash); this->initialized = true; } catch (const cv::Exception &e) { throw Exception(NFIQ2::ErrorCode::BadArguments, @@ -53,6 +80,7 @@ NFIQ2::Algorithm::Impl::Impl(const std::string &fileName, ") (initial error: " + e.what() + ")."); } } +#endif NFIQ2::Algorithm::Impl::~Impl() = default; @@ -120,8 +148,8 @@ NFIQ2::Algorithm::Impl::computeQualityScore( * Nothing should get here, but computeQualityModules() calls * a lot of code... */ - throw NFIQ2::Exception(NFIQ2::ErrorCode::UnknownError, - e.what()); + throw NFIQ2::Exception( + NFIQ2::ErrorCode::UnknownError, e.what()); } const std::unordered_map quality = diff --git a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp index 0ac84346..da53a18d 100644 --- a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp +++ b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp @@ -41,6 +41,21 @@ class Algorithm::Impl { */ Impl(const std::string &fileName, const std::string &fileHash); +#ifdef __ANDROID__ + /** + * @brief + * Constructor that loads random forest parameters from AAR. + * + * @param assets + * The Android Asset Manager, provided by the App. + * @param fileName + * The file path containing the random forest model. + * @param fileHash + * The md5 checksum of the provided file. + */ + Impl(AAssetManager* assets, const std::string &fileName, const std::string &fileHash); +#endif + /** Destructor. */ virtual ~Impl(); diff --git a/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp b/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp index 1fe768c7..298d8f31 100644 --- a/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp +++ b/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp @@ -104,8 +104,8 @@ NFIQ2::Prediction::RandomForestML::initModule() #endif std::string -NFIQ2::Prediction::RandomForestML::initModule(const std::string &fileName, - const std::string &fileHash) +NFIQ2::Prediction::RandomForestML::initModule( + const std::string &fileName, const std::string &fileHash) { std::ifstream input(fileName); std::string params((std::istreambuf_iterator(input)), @@ -123,6 +123,63 @@ NFIQ2::Prediction::RandomForestML::initModule(const std::string &fileName, return hash; } +#ifdef __ANDROID__ +std::string +NFIQ2::Prediction::RandomForestML::initModule(AAssetManager *assets, + const std::string &fileName, const std::string &fileHash) +{ + if (assets == nullptr) { + throw NFIQ2::Exception(NFIQ2::ErrorCode::BadArguments, + "Prediction::RandomForestML::initModule: AAssetManager is null"); + } + if (fileName.empty()) { + throw NFIQ2::Exception(NFIQ2::ErrorCode::BadArguments, + "Prediction::RandomForestML::initModule: " + "file name is empty"); + } + if (fileHash.empty()) { + throw NFIQ2::Exception(NFIQ2::ErrorCode::BadArguments, + "Prediction::RandomForestML::initModule: " + "hash value is empty"); + } + AAsset *asset = AAssetManager_open( + assets, fileName.c_str(), AASSET_MODE_STREAMING); + if (asset == nullptr) { + throw NFIQ2::Exception(NFIQ2::ErrorCode::InvalidConfiguration, + "Prediction::RandomForestML::initModule: " + "requested asset not found"); + } + // reading the file with the asset manager + std::stringstream ss; + char buffer[BUFSIZ + 1]; // BUFSIZ defined in stdio.h + int cnt = AAsset_read(asset, buffer, BUFSIZ); + while (cnt > 0 && cnt <= BUFSIZ) { + buffer[cnt] = 0; // add terminating '\0' + ss << buffer; + cnt = AAsset_read(asset, buffer, BUFSIZ); + } + AAsset_close(asset); + // verify the read data and initialize model + std::string params = ss.str(); + if (params.size() == 0) { + throw NFIQ2::Exception(NFIQ2::ErrorCode::InvalidConfiguration, + "The trained network could not be initialized!" + "Invalid model"); + } + // calculate and compare the hash + std::string hash = calculateHashString(params); + if (fileHash.compare(hash) != 0) { + m_pTrainedRF->clear(); + throw NFIQ2::Exception(NFIQ2::ErrorCode::InvalidConfiguration, + "The trained network could not be initialized! " + "Error: " + + hash); + } + initModule(params); + return hash; +} +#endif + void NFIQ2::Prediction::RandomForestML::evaluate( const std::unordered_map &features, @@ -255,8 +312,8 @@ NFIQ2::Prediction::RandomForestML::evaluate( } // copy data to structure - cv::Mat sample_data = cv::Mat(1, rfFeatureOrder.size(), - CV_32FC1); + cv::Mat sample_data = cv::Mat( + 1, rfFeatureOrder.size(), CV_32FC1); for (unsigned int i { 0 }; i < rfFeatureOrder.size(); ++i) { sample_data.at(0, i) = features.at( @@ -265,16 +322,16 @@ NFIQ2::Prediction::RandomForestML::evaluate( // returns probability that between 0 and 1 that result belongs // to second class - float prob = m_pTrainedRF->predict(sample_data, cv::noArray(), - cv::ml::StatModel::RAW_OUTPUT); + float prob = m_pTrainedRF->predict( + sample_data, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT); // return quality value qualityValue = (int)(prob + 0.5); } catch (const cv::Exception &e) { throw Exception(NFIQ2::ErrorCode::MachineLearningError, e.msg); } catch (const std::out_of_range &e) { - throw Exception(NFIQ2::ErrorCode::FeatureCalculationError, - e.what()); + throw Exception( + NFIQ2::ErrorCode::FeatureCalculationError, e.what()); } } diff --git a/NFIQ2/NFIQ2Api/CMakeLists.txt b/NFIQ2/NFIQ2Api/CMakeLists.txt index f5ba423e..86253c22 100644 --- a/NFIQ2/NFIQ2Api/CMakeLists.txt +++ b/NFIQ2/NFIQ2Api/CMakeLists.txt @@ -84,6 +84,7 @@ elseif("${TARGET_PLATFORM}" MATCHES "android*") find_package(Threads REQUIRED) set( PROJECT_LIBS ${PROJECT_LIBS} ${CMAKE_THREAD_LIBS_INIT} + android log ) else() From 6fe6d387cce9a839869d629877d91cc0e7d7818a Mon Sep 17 00:00:00 2001 From: Greg Fiumara Date: Mon, 7 Feb 2022 07:09:06 -0500 Subject: [PATCH 2/5] Apply clang-format 12 to PR. --- .../include/nfiq2_algorithm.hpp | 5 +++-- .../include/prediction/RandomForestML.h | 4 ++-- .../src/nfiq2/nfiq2_algorithm.cpp | 4 ++-- .../src/nfiq2/nfiq2_algorithm_impl.cpp | 16 +++++++-------- .../src/nfiq2/nfiq2_algorithm_impl.hpp | 5 +++-- .../src/prediction/RandomForestML.cpp | 20 +++++++++---------- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp index b0b7b1ea..c4090e87 100644 --- a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp +++ b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp @@ -21,7 +21,7 @@ #include #ifdef __ANDROID__ -# include +#include #endif namespace NFIQ2 { @@ -53,7 +53,8 @@ class Algorithm { */ Algorithm(const std::string &fileName, const std::string &fileHash); #ifdef __ANDROID__ - Algorithm(AAssetManager* assets, const std::string &fileName, const std::string &fileHash); + Algorithm(AAssetManager *assets, const std::string &fileName, + const std::string &fileHash); #endif /** diff --git a/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h b/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h index da1b526e..957ef440 100644 --- a/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h +++ b/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h @@ -37,8 +37,8 @@ class RandomForestML { #endif /** Initialize model (When not using embedded parameters). */ - std::string initModule( - const std::string &fileName, const std::string &fileHash); + std::string initModule(const std::string &fileName, + const std::string &fileHash); #ifdef __ANDROID__ /** Initialize model from Android AAR (When not using embedded diff --git a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp index 212914a2..0eb153fe 100644 --- a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp +++ b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm.cpp @@ -8,8 +8,8 @@ NFIQ2::Algorithm::Algorithm() { } -NFIQ2::Algorithm::Algorithm( - const std::string &fileName, const std::string &fileHash) +NFIQ2::Algorithm::Algorithm(const std::string &fileName, + const std::string &fileHash) : pimpl { new NFIQ2::Algorithm::Impl(fileName, fileHash) } { } diff --git a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp index ab5a06b5..c5496f68 100644 --- a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp +++ b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.cpp @@ -28,14 +28,14 @@ NFIQ2::Algorithm::Impl::Impl() #endif } -NFIQ2::Algorithm::Impl::Impl( - const std::string &fileName, const std::string &fileHash) +NFIQ2::Algorithm::Impl::Impl(const std::string &fileName, + const std::string &fileHash) : initialized { false } { // init RF module that takes some time to load the parameters try { - this->m_parameterHash = m_RandomForestML.initModule( - fileName, fileHash); + this->m_parameterHash = m_RandomForestML.initModule(fileName, + fileHash); this->initialized = true; } catch (const cv::Exception &e) { throw Exception(NFIQ2::ErrorCode::BadArguments, @@ -61,8 +61,8 @@ NFIQ2::Algorithm::Impl::Impl(AAssetManager *assets, const std::string &fileName, { // init RF module that takes some time to load the parameters try { - this->m_parameterHash = m_RandomForestML.initModule( - assets, fileName, fileHash); + this->m_parameterHash = m_RandomForestML.initModule(assets, + fileName, fileHash); this->initialized = true; } catch (const cv::Exception &e) { throw Exception(NFIQ2::ErrorCode::BadArguments, @@ -148,8 +148,8 @@ NFIQ2::Algorithm::Impl::computeQualityScore( * Nothing should get here, but computeQualityModules() calls * a lot of code... */ - throw NFIQ2::Exception( - NFIQ2::ErrorCode::UnknownError, e.what()); + throw NFIQ2::Exception(NFIQ2::ErrorCode::UnknownError, + e.what()); } const std::unordered_map quality = diff --git a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp index da53a18d..fa158a4a 100644 --- a/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp +++ b/NFIQ2/NFIQ2Algorithm/src/nfiq2/nfiq2_algorithm_impl.hpp @@ -47,13 +47,14 @@ class Algorithm::Impl { * Constructor that loads random forest parameters from AAR. * * @param assets - * The Android Asset Manager, provided by the App. + * The Android Asset Manager, provided by the App. * @param fileName * The file path containing the random forest model. * @param fileHash * The md5 checksum of the provided file. */ - Impl(AAssetManager* assets, const std::string &fileName, const std::string &fileHash); + Impl(AAssetManager *assets, const std::string &fileName, + const std::string &fileHash); #endif /** Destructor. */ diff --git a/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp b/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp index 298d8f31..d4348683 100644 --- a/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp +++ b/NFIQ2/NFIQ2Algorithm/src/prediction/RandomForestML.cpp @@ -104,8 +104,8 @@ NFIQ2::Prediction::RandomForestML::initModule() #endif std::string -NFIQ2::Prediction::RandomForestML::initModule( - const std::string &fileName, const std::string &fileHash) +NFIQ2::Prediction::RandomForestML::initModule(const std::string &fileName, + const std::string &fileHash) { std::ifstream input(fileName); std::string params((std::istreambuf_iterator(input)), @@ -142,8 +142,8 @@ NFIQ2::Prediction::RandomForestML::initModule(AAssetManager *assets, "Prediction::RandomForestML::initModule: " "hash value is empty"); } - AAsset *asset = AAssetManager_open( - assets, fileName.c_str(), AASSET_MODE_STREAMING); + AAsset *asset = AAssetManager_open(assets, fileName.c_str(), + AASSET_MODE_STREAMING); if (asset == nullptr) { throw NFIQ2::Exception(NFIQ2::ErrorCode::InvalidConfiguration, "Prediction::RandomForestML::initModule: " @@ -312,8 +312,8 @@ NFIQ2::Prediction::RandomForestML::evaluate( } // copy data to structure - cv::Mat sample_data = cv::Mat( - 1, rfFeatureOrder.size(), CV_32FC1); + cv::Mat sample_data = cv::Mat(1, rfFeatureOrder.size(), + CV_32FC1); for (unsigned int i { 0 }; i < rfFeatureOrder.size(); ++i) { sample_data.at(0, i) = features.at( @@ -322,16 +322,16 @@ NFIQ2::Prediction::RandomForestML::evaluate( // returns probability that between 0 and 1 that result belongs // to second class - float prob = m_pTrainedRF->predict( - sample_data, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT); + float prob = m_pTrainedRF->predict(sample_data, cv::noArray(), + cv::ml::StatModel::RAW_OUTPUT); // return quality value qualityValue = (int)(prob + 0.5); } catch (const cv::Exception &e) { throw Exception(NFIQ2::ErrorCode::MachineLearningError, e.msg); } catch (const std::out_of_range &e) { - throw Exception( - NFIQ2::ErrorCode::FeatureCalculationError, e.what()); + throw Exception(NFIQ2::ErrorCode::FeatureCalculationError, + e.what()); } } From 51250d7fe7c34d6fea66f1d21bb703ba296dec16 Mon Sep 17 00:00:00 2001 From: RLessmann <36705123+RLessmann@users.noreply.github.com> Date: Mon, 7 Feb 2022 14:12:35 +0100 Subject: [PATCH 3/5] Update NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp Co-authored-by: Greg Fiumara --- NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp index c4090e87..eab7dbe3 100644 --- a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp +++ b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp @@ -53,7 +53,7 @@ class Algorithm { */ Algorithm(const std::string &fileName, const std::string &fileHash); #ifdef __ANDROID__ - Algorithm(AAssetManager *assets, const std::string &fileName, + Algorithm(const AAssetManager *assets, const std::string &fileName, const std::string &fileHash); #endif From 93dafcdd0631dec691e469de9ac17ad6e56cce07 Mon Sep 17 00:00:00 2001 From: RLessmann <36705123+RLessmann@users.noreply.github.com> Date: Mon, 7 Feb 2022 14:12:47 +0100 Subject: [PATCH 4/5] Update NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h Co-authored-by: Greg Fiumara --- NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h | 1 - 1 file changed, 1 deletion(-) diff --git a/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h b/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h index 957ef440..8aabf63a 100644 --- a/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h +++ b/NFIQ2/NFIQ2Algorithm/include/prediction/RandomForestML.h @@ -10,7 +10,6 @@ #ifdef __ANDROID__ #include -#include #endif namespace NFIQ2 { namespace Prediction { From 0760eea50e7569042df0a21f1bf41901d66d3347 Mon Sep 17 00:00:00 2001 From: Greg Fiumara Date: Tue, 8 Feb 2022 08:27:25 -0500 Subject: [PATCH 5/5] Revert "Update NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp" This reverts commit 51250d7fe7c34d6fea66f1d21bb703ba296dec16. --- NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp index eab7dbe3..c4090e87 100644 --- a/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp +++ b/NFIQ2/NFIQ2Algorithm/include/nfiq2_algorithm.hpp @@ -53,7 +53,7 @@ class Algorithm { */ Algorithm(const std::string &fileName, const std::string &fileHash); #ifdef __ANDROID__ - Algorithm(const AAssetManager *assets, const std::string &fileName, + Algorithm(AAssetManager *assets, const std::string &fileName, const std::string &fileHash); #endif