diff --git a/runtime_data/openalpr.conf b/runtime_data/openalpr.conf index 4e0645b..953a4c0 100644 --- a/runtime_data/openalpr.conf +++ b/runtime_data/openalpr.conf @@ -1,5 +1,9 @@ [common] +; Specify the path to the runtime data directory +runtime_dir = /usr/share/openalpr/runtime_data + + ocr_img_size_percent = 1.33333333 state_id_img_size_percent = 2.0 diff --git a/src/main.cpp b/src/main.cpp index 4eb859a..d205966 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,7 +44,7 @@ bool measureProcessingTime = false; int main( int argc, const char** argv ) { std::string filename; - std::string runtimePath = ""; + std::string configFile = ""; bool outputJson = false; int seektoms = 0; bool detectRegion = false; @@ -59,7 +59,7 @@ int main( int argc, const char** argv ) TCLAP::ValueArg countryCodeArg("c","country","Country code to identify (either us for USA or eu for Europe). Default=us",false, "us" ,"country_code"); TCLAP::ValueArg seekToMsArg("","seek","Seek to the specied millisecond in a video file. Default=0",false, 0 ,"integer_ms"); - TCLAP::ValueArg runtimeDirArg("r","runtime_dir","Path to the OpenAlpr runtime data directory",false, "" ,"runtime_dir"); + TCLAP::ValueArg configFileArg("","config","Path to the openalpr.conf file",false, "" ,"config_file"); TCLAP::ValueArg templateRegionArg("t","template_region","Attempt to match the plate number against a region template (e.g., md for Maryland, ca for California)",false, "" ,"region code"); TCLAP::ValueArg topNArg("n","topn","Max number of possible plate numbers to return. Default=10",false, 10 ,"topN"); @@ -69,12 +69,12 @@ int main( int argc, const char** argv ) try { - cmd.add( fileArg ); - cmd.add( countryCodeArg ); + cmd.add( templateRegionArg ); cmd.add( seekToMsArg ); cmd.add( topNArg ); - cmd.add( runtimeDirArg ); - cmd.add( templateRegionArg ); + cmd.add( configFileArg ); + cmd.add( fileArg ); + cmd.add( countryCodeArg ); cmd.parse( argc, argv ); @@ -83,7 +83,7 @@ int main( int argc, const char** argv ) country = countryCodeArg.getValue(); seektoms = seekToMsArg.getValue(); outputJson = jsonSwitch.getValue(); - runtimePath = runtimeDirArg.getValue(); + configFile = configFileArg.getValue(); detectRegion = detectRegionSwitch.getValue(); templateRegion = templateRegionArg.getValue(); topn = topNArg.getValue(); @@ -98,7 +98,7 @@ int main( int argc, const char** argv ) cv::Mat frame; - Alpr alpr(country, runtimePath); + Alpr alpr(country, configFile); alpr.setTopN(topn); if (detectRegion) @@ -109,7 +109,7 @@ int main( int argc, const char** argv ) if (alpr.isLoaded() == false) { - std::cerr << "Error loading OpenAlpr" << std::endl; + std::cerr << "Error loading OpenALPR" << std::endl; return 1; } diff --git a/src/openalpr/CMakeLists.txt b/src/openalpr/CMakeLists.txt index eabd23b..2d7330c 100644 --- a/src/openalpr/CMakeLists.txt +++ b/src/openalpr/CMakeLists.txt @@ -48,4 +48,5 @@ install (FILES alpr.h DESTINATION include) install (TARGETS openalpr DESTINATION lib) # Add definition for default runtime dir -add_definitions(-DDEFAULT_RUNTIME_DIR="/usr/share/openalpr/runtime_data") \ No newline at end of file +#add_definitions(-DDEFAULT_RUNTIME_DIR="/usr/share/openalpr/runtime_data") +add_definitions(-DDEFAULT_CONFIG_FILE="/etc/openalpr/openalpr.conf") diff --git a/src/openalpr/alpr.cpp b/src/openalpr/alpr.cpp index 06d8f02..e087352 100644 --- a/src/openalpr/alpr.cpp +++ b/src/openalpr/alpr.cpp @@ -22,9 +22,9 @@ // ALPR code -Alpr::Alpr(const std::string country, const std::string runtimeDir) +Alpr::Alpr(const std::string country, const std::string configFile) { - impl = new AlprImpl(country, runtimeDir); + impl = new AlprImpl(country, configFile); } Alpr::~Alpr() @@ -68,7 +68,7 @@ void Alpr::setDefaultRegion(std::string region) bool Alpr::isLoaded() { - return true; + return impl->isLoaded(); } std::string Alpr::getVersion() diff --git a/src/openalpr/alpr.h b/src/openalpr/alpr.h index 5068d67..97f2e7d 100644 --- a/src/openalpr/alpr.h +++ b/src/openalpr/alpr.h @@ -63,7 +63,7 @@ class Alpr { public: - Alpr(const std::string country, const std::string runtimeDir = ""); + Alpr(const std::string country, const std::string configFile = ""); virtual ~Alpr(); void setDetectRegion(bool detectRegion); diff --git a/src/openalpr/alpr_impl.cpp b/src/openalpr/alpr_impl.cpp index c7276fe..8e09f23 100644 --- a/src/openalpr/alpr_impl.cpp +++ b/src/openalpr/alpr_impl.cpp @@ -21,9 +21,19 @@ void plateAnalysisThread(void* arg); -AlprImpl::AlprImpl(const std::string country, const std::string runtimeDir) +AlprImpl::AlprImpl(const std::string country, const std::string configFile) { - config = new Config(country, runtimeDir); + config = new Config(country, configFile); + + // Config file or runtime dir not found. Don't process any further. + if (config->loaded == false) + { + plateDetector = ALPR_NULL_PTR; + stateIdentifier = ALPR_NULL_PTR; + ocr = ALPR_NULL_PTR; + return; + } + plateDetector = new RegionDetector(config); stateIdentifier = new StateIdentifier(config); ocr = new OCR(config); @@ -37,9 +47,20 @@ AlprImpl::AlprImpl(const std::string country, const std::string runtimeDir) AlprImpl::~AlprImpl() { delete config; - delete plateDetector; - delete stateIdentifier; - delete ocr; + + if (plateDetector != ALPR_NULL_PTR) + delete plateDetector; + + if (stateIdentifier != ALPR_NULL_PTR) + delete stateIdentifier; + + if (ocr != ALPR_NULL_PTR) + delete ocr; +} + +bool AlprImpl::isLoaded() +{ + return config->loaded; } diff --git a/src/openalpr/alpr_impl.h b/src/openalpr/alpr_impl.h index a21e5cb..6db7fc6 100644 --- a/src/openalpr/alpr_impl.h +++ b/src/openalpr/alpr_impl.h @@ -45,11 +45,13 @@ #define DEFAULT_TOPN 25 #define DEFAULT_DETECT_REGION false +#define ALPR_NULL_PTR 0 + class AlprImpl { public: - AlprImpl(const std::string country, const std::string runtimeDir = ""); + AlprImpl(const std::string country, const std::string configFile = ""); virtual ~AlprImpl(); std::vector recognize(cv::Mat img); @@ -65,6 +67,8 @@ class AlprImpl Config* config; + bool isLoaded(); + private: RegionDetector* plateDetector; diff --git a/src/openalpr/config.cpp b/src/openalpr/config.cpp index 79c66bf..1443220 100644 --- a/src/openalpr/config.cpp +++ b/src/openalpr/config.cpp @@ -20,48 +20,83 @@ #include "config.h" -Config::Config(const std::string country, const std::string runtimeBaseDir) +Config::Config(const std::string country, const std::string config_file) { - this->runtimeBaseDir = runtimeBaseDir; + + string debug_message = ""; + + this->loaded = false; ini = new CSimpleIniA(); - char* envRuntimeDir; - envRuntimeDir = getenv (ENV_VARIABLE_RUNTIME_DIR); - if (runtimeBaseDir.compare("") != 0) + string configFile; + + char* envConfigFile; + envConfigFile = getenv (ENV_VARIABLE_CONFIG_FILE); + if (config_file.compare("") != 0) { - // User has supplied a runtime directory. Use that. - + // User has supplied a config file. Use that. + configFile = config_file; + debug_message = "Config file location provided via API"; } - else if (envRuntimeDir!=NULL) + else if (envConfigFile != NULL) { // Environment variable is non-empty. Use that. - this->runtimeBaseDir = envRuntimeDir; + configFile = envConfigFile; + debug_message = "Config file location provided via environment variable: " + string(ENV_VARIABLE_CONFIG_FILE); } else { // Use the default - this->runtimeBaseDir = DEFAULT_RUNTIME_DIR; + configFile = DEFAULT_CONFIG_FILE; + debug_message = "Config file location provided via default location"; } - string configFile = (this->runtimeBaseDir + CONFIG_FILE); + //string configFile = (this->runtimeBaseDir + CONFIG_FILE); + + if (fileExists(configFile.c_str()) == false) + { + std::cerr << "--(!) Config file '" << configFile << "' does not exist!" << endl; + std::cerr << "--(!) You can specify the configuration file location via the command line " << endl; + std::cerr << "--(!) or by setting the environment variable '" << ENV_VARIABLE_CONFIG_FILE << "'" << endl; + return; + } + else if (DirectoryExists(configFile.c_str())) + { + std::cerr << "--(!) Config file '" << configFile << "' was specified as a directory, rather than a file!" << endl; + std::cerr << "--(!) Please specify the full path to the 'openalpr.conf file'" << endl; + std::cerr << "--(!) e.g., /etc/openalpr/openalpr.conf" << endl; + return; + } + + ini->LoadFile(configFile.c_str()); + + this->country = country; + + + loadValues(country); + if (DirectoryExists(this->runtimeBaseDir.c_str()) == false) { - std::cerr << "--(!)Runtime directory '" << this->runtimeBaseDir << "' does not exist!" << endl; + std::cerr << "--(!) Runtime directory '" << this->runtimeBaseDir << "' does not exist!" << endl; + std::cerr << "--(!) Please update the OpenALPR config file: '" << configFile << "'" << endl; + std::cerr << "--(!) to point to the correct location of your runtime_dir" << endl; return; } - else if (fileExists(configFile.c_str()) == false) + else if (fileExists((this->runtimeBaseDir + "/ocr/tessdata/l" + country + ".traineddata").c_str()) == false) { - std::cerr << "--(!)Runtime directory '" << this->runtimeBaseDir << "' does not contain a config file '" << CONFIG_FILE << "'!" << endl; + std::cerr << "--(!) Runtime directory '" << this->runtimeBaseDir << "' is invalid. Missing OCR data for the country: '" << country<< "'!" << endl; return; } - ini->LoadFile(configFile.c_str()); - this->country = country; + if (this->debugGeneral) + { + std::cout << debug_message << endl; + } - loadValues(country); + this->loaded = true; } Config::~Config() { @@ -71,6 +106,8 @@ Config::~Config() void Config::loadValues(string country) { + runtimeBaseDir = getString("common", "runtime_dir", "/usr/share/openalpr/runtime_data"); + opencl_enabled = getBoolean("common", "opencl_enabled", false); multithreading_cores = getInt("common", "multithreading_cores", 1); diff --git a/src/openalpr/config.h b/src/openalpr/config.h index ad74e34..f1d083b 100644 --- a/src/openalpr/config.h +++ b/src/openalpr/config.h @@ -38,9 +38,11 @@ class Config { public: - Config(const std::string country, const std::string runtimeDir = ""); + Config(const std::string country, const std::string config_file = ""); virtual ~Config(); + bool loaded; + string country; bool opencl_enabled; diff --git a/src/openalpr/constants.h b/src/openalpr/constants.h index 0cf137f..53d2524 100644 --- a/src/openalpr/constants.h +++ b/src/openalpr/constants.h @@ -26,10 +26,10 @@ #define CASCADE_DIR "/region/" #define POSTPROCESS_DIR "/postprocess" -#ifndef DEFAULT_RUNTIME_DIR -#define DEFAULT_RUNTIME_DIR "/default_runtime_data_dir/" +#ifndef DEFAULT_CONFIG_FILE + #define DEFAULT_CONFIG_FILE "/etc/openalpr/openalpr.conf" #endif -#define ENV_VARIABLE_RUNTIME_DIR "OPENALPR_RUNTIME_DIR" +#define ENV_VARIABLE_CONFIG_FILE "OPENALPR_CONFIG_FILE" #endif // OPENALPR_CONSTANTS_H \ No newline at end of file