diff --git a/config/openalpr.conf.in b/config/openalpr.conf.in index 130ab74..56530f0 100644 --- a/config/openalpr.conf.in +++ b/config/openalpr.conf.in @@ -1,4 +1,3 @@ -[common] ; Specify the path to the runtime data directory runtime_dir = ${CMAKE_INSTALL_PREFIX}/share/openalpr/runtime_data @@ -58,90 +57,21 @@ postprocess_max_substitutions = 2 postprocess_min_characters = 4 postprocess_max_characters = 8 -[debug] -general = 0 -timing = 0 -detector = 0 -state_id = 0 -plate_lines = 0 -plate_corners = 0 -char_segment = 0 -char_analysis = 0 -color_filter = 0 -ocr = 0 -postprocess = 0 -show_images = 0 -pause_on_frame = 0 -;;; Country Specific variables ;;;; +debug_general = 0 +debug_timing = 0 +debug_detector = 0 +debug_state_id = 0 +debug_plate_lines = 0 +debug_plate_corners = 0 +debug_char_segment = 0 +debug_char_analysis = 0 +debug_color_filter = 0 +debug_ocr = 0 +debug_postprocess = 0 +debug_show_images = 0 +debug_pause_on_frame = 0 -[us] -; 30-50, 40-60, 50-70, 60-80 -char_analysis_min_pct = 0.30 -char_analysis_height_range = 0.20 -char_analysis_height_step_size = 0.10 -char_analysis_height_num_steps = 4 -segmentation_min_box_width_px = 4 -segmentation_min_charheight_percent = 0.5; -segmentation_max_segment_width_percent_vs_average = 1.35; -plate_width_mm = 304.8 -plate_height_mm = 152.4 - -multiline = 0 - -char_height_mm = 70 -char_width_mm = 35 -char_whitespace_top_mm = 38 -char_whitespace_bot_mm = 38 - -template_max_width_px = 120 -template_max_height_px = 60 - -; Higher sensitivity means less lines -plateline_sensitivity_vertical = 25 -plateline_sensitivity_horizontal = 45 - -; Regions smaller than this will be disqualified -min_plate_size_width_px = 70 -min_plate_size_height_px = 35 - -ocr_language = lus - -[eu] -; One-line European style plates - -; 35-50; 45-60, 55-70, 65-80, 75-90 -char_analysis_min_pct = 0.35 -char_analysis_height_range = 0.15 -char_analysis_height_step_size = 0.10 -char_analysis_height_num_steps = 5 - -segmentation_min_box_width_px = 5 -segmentation_min_charheight_percent = 0.4; -segmentation_max_segment_width_percent_vs_average = 2.0; - -plate_width_mm = 520 -plate_height_mm = 110 - -multiline = 0 - -char_height_mm = 80 -char_width_mm = 53 -char_whitespace_top_mm = 10 -char_whitespace_bot_mm = 10 - -template_max_width_px = 184 -template_max_height_px = 46 - -; Higher sensitivity means less lines -plateline_sensitivity_vertical = 18 -plateline_sensitivity_horizontal = 55 - -; Regions smaller than this will be disqualified -min_plate_size_width_px = 100 -min_plate_size_height_px = 20 - -ocr_language = leu diff --git a/runtime_data/config/eu.conf b/runtime_data/config/eu.conf new file mode 100644 index 0000000..b677804 --- /dev/null +++ b/runtime_data/config/eu.conf @@ -0,0 +1,34 @@ +; One-line European style plates + +; 35-50; 45-60, 55-70, 65-80, 75-90 +char_analysis_min_pct = 0.35 +char_analysis_height_range = 0.15 +char_analysis_height_step_size = 0.10 +char_analysis_height_num_steps = 5 + +segmentation_min_box_width_px = 5 +segmentation_min_charheight_percent = 0.4; +segmentation_max_segment_width_percent_vs_average = 2.0; + +plate_width_mm = 520 +plate_height_mm = 110 + +multiline = 0 + +char_height_mm = 80 +char_width_mm = 53 +char_whitespace_top_mm = 10 +char_whitespace_bot_mm = 10 + +template_max_width_px = 184 +template_max_height_px = 46 + +; Higher sensitivity means less lines +plateline_sensitivity_vertical = 18 +plateline_sensitivity_horizontal = 55 + +; Regions smaller than this will be disqualified +min_plate_size_width_px = 100 +min_plate_size_height_px = 20 + +ocr_language = leu diff --git a/runtime_data/config/us.conf b/runtime_data/config/us.conf new file mode 100644 index 0000000..d311841 --- /dev/null +++ b/runtime_data/config/us.conf @@ -0,0 +1,32 @@ +; 30-50, 40-60, 50-70, 60-80 +char_analysis_min_pct = 0.30 +char_analysis_height_range = 0.20 +char_analysis_height_step_size = 0.10 +char_analysis_height_num_steps = 4 + +segmentation_min_box_width_px = 4 +segmentation_min_charheight_percent = 0.5; +segmentation_max_segment_width_percent_vs_average = 1.35; + +plate_width_mm = 304.8 +plate_height_mm = 152.4 + +multiline = 0 + +char_height_mm = 70 +char_width_mm = 35 +char_whitespace_top_mm = 38 +char_whitespace_bot_mm = 38 + +template_max_width_px = 120 +template_max_height_px = 60 + +; Higher sensitivity means less lines +plateline_sensitivity_vertical = 25 +plateline_sensitivity_horizontal = 45 + +; Regions smaller than this will be disqualified +min_plate_size_width_px = 70 +min_plate_size_height_px = 35 + +ocr_language = lus diff --git a/src/openalpr/config.cpp b/src/openalpr/config.cpp index 59966d6..a8a054e 100644 --- a/src/openalpr/config.cpp +++ b/src/openalpr/config.cpp @@ -31,7 +31,6 @@ namespace alpr this->loaded = false; - ini = new CSimpleIniA(); string configFile; @@ -78,12 +77,11 @@ namespace alpr return; } - ini->LoadFile(configFile.c_str()); this->country = country; - loadValues(country); + loadCommonValues(configFile); if (runtime_dir.compare("") != 0) { @@ -106,13 +104,22 @@ namespace alpr std::cerr << "--(!) to point to the correct location of your runtime_dir" << endl; return; } - else if (fileExists((this->runtimeBaseDir + "/ocr/tessdata/" + this->ocrLanguage + ".traineddata").c_str()) == false) + + std::string country_config_file = this->runtimeBaseDir + "/config/" + country + ".conf"; + if (fileExists(country_config_file.c_str()) == false) + { + std::cerr << "--(!) Country config file '" << country_config_file << "' does not exist. Missing config for the country: '" << country<< "'!" << endl; + return; + } + + loadCountryValues(country_config_file, country); + + if (fileExists((this->runtimeBaseDir + "/ocr/tessdata/" + this->ocrLanguage + ".traineddata").c_str()) == false) { std::cerr << "--(!) Runtime directory '" << this->runtimeBaseDir << "' is invalid. Missing OCR data for the country: '" << country<< "'!" << endl; return; } - - + if (this->debugGeneral) { std::cout << debug_message << endl; @@ -122,15 +129,19 @@ namespace alpr } Config::~Config() { - delete ini; + } - void Config::loadValues(string country) + void Config::loadCommonValues(string configFile) { - runtimeBaseDir = getString("common", "runtime_dir", "/usr/share/openalpr/runtime_data"); + CSimpleIniA iniObj; + iniObj.LoadFile(configFile.c_str()); + CSimpleIniA* ini = &iniObj; + + runtimeBaseDir = getString(ini, "", "runtime_dir", "/usr/share/openalpr/runtime_data"); - std::string detectorString = getString("common", "detector", "lbpcpu"); + std::string detectorString = getString(ini, "", "detector", "lbpcpu"); std::transform(detectorString.begin(), detectorString.end(), detectorString.begin(), ::tolower); if (detectorString.compare("lbpcpu") == 0) @@ -145,81 +156,90 @@ namespace alpr detector = DETECTOR_LBP_CPU; } - detection_iteration_increase = getFloat("common", "detection_iteration_increase", 1.1); - detectionStrictness = getInt("common", "detection_strictness", 3); - maxPlateWidthPercent = getFloat("common", "max_plate_width_percent", 100); - maxPlateHeightPercent = getFloat("common", "max_plate_height_percent", 100); - maxDetectionInputWidth = getInt("common", "max_detection_input_width", 1280); - maxDetectionInputHeight = getInt("common", "max_detection_input_height", 768); + detection_iteration_increase = getFloat(ini, "", "detection_iteration_increase", 1.1); + detectionStrictness = getInt(ini, "", "detection_strictness", 3); + maxPlateWidthPercent = getFloat(ini, "", "max_plate_width_percent", 100); + maxPlateHeightPercent = getFloat(ini, "", "max_plate_height_percent", 100); + maxDetectionInputWidth = getInt(ini, "", "max_detection_input_width", 1280); + maxDetectionInputHeight = getInt(ini, "", "max_detection_input_height", 768); - skipDetection = getBoolean("common", "skip_detection", false); + skipDetection = getBoolean(ini, "", "skip_detection", false); - prewarp = getString("common", "prewarp", ""); + prewarp = getString(ini, "", "prewarp", ""); - maxPlateAngleDegrees = getInt("common", "max_plate_angle_degrees", 15); + maxPlateAngleDegrees = getInt(ini, "", "max_plate_angle_degrees", 15); - minPlateSizeWidthPx = getInt(country, "min_plate_size_width_px", 100); - minPlateSizeHeightPx = getInt(country, "min_plate_size_height_px", 100); - multiline = getBoolean(country, "multiline", false); + ocrImagePercent = getFloat(ini, "", "ocr_img_size_percent", 100); + stateIdImagePercent = getFloat(ini, "", "state_id_img_size_percent", 100); - plateWidthMM = getFloat(country, "plate_width_mm", 100); - plateHeightMM = getFloat(country, "plate_height_mm", 100); + ocrMinFontSize = getInt(ini, "", "ocr_min_font_point", 100); - charHeightMM = getFloat(country, "char_height_mm", 100); - charWidthMM = getFloat(country, "char_width_mm", 100); - charWhitespaceTopMM = getFloat(country, "char_whitespace_top_mm", 100); - charWhitespaceBotMM = getFloat(country, "char_whitespace_bot_mm", 100); + postProcessMinConfidence = getFloat(ini, "", "postprocess_min_confidence", 100); + postProcessConfidenceSkipLevel = getFloat(ini, "", "postprocess_confidence_skip_level", 100); + postProcessMaxSubstitutions = getInt(ini, "", "postprocess_max_substitutions", 100); + postProcessMinCharacters = getInt(ini, "", "postprocess_min_characters", 100); + postProcessMaxCharacters = getInt(ini, "", "postprocess_max_characters", 100); - templateWidthPx = getInt(country, "template_max_width_px", 100); - templateHeightPx = getInt(country, "template_max_height_px", 100); + debugGeneral = getBoolean(ini, "", "debug_general", false); + debugTiming = getBoolean(ini, "", "debug_timing", false); + debugPrewarp = getBoolean(ini, "", "debug_prewarp", false); + debugDetector = getBoolean(ini, "", "debug_detector", false); + debugStateId = getBoolean(ini, "", "debug_state_id", false); + debugPlateLines = getBoolean(ini, "", "debug_plate_lines", false); + debugPlateCorners = getBoolean(ini, "", "debug_plate_corners", false); + debugCharSegmenter = getBoolean(ini, "", "debug_char_segment", false); + debugCharAnalysis = getBoolean(ini, "", "debug_char_analysis", false); + debugColorFiler = getBoolean(ini, "", "debug_color_filter", false); + debugOcr = getBoolean(ini, "", "debug_ocr", false); + debugPostProcess = getBoolean(ini, "", "debug_postprocess", false); + debugShowImages = getBoolean(ini, "", "debug_show_images", false); + debugPauseOnFrame = getBoolean(ini, "", "debug_pause_on_frame", false); - float ocrImagePercent = getFloat("common", "ocr_img_size_percent", 100); + } + + + void Config::loadCountryValues(string configFile, string country) + { + CSimpleIniA iniObj; + iniObj.LoadFile(configFile.c_str()); + CSimpleIniA* ini = &iniObj; + + minPlateSizeWidthPx = getInt(ini, "", "min_plate_size_width_px", 100); + minPlateSizeHeightPx = getInt(ini, "", "min_plate_size_height_px", 100); + + multiline = getBoolean(ini, "", "multiline", false); + + plateWidthMM = getFloat(ini, "", "plate_width_mm", 100); + plateHeightMM = getFloat(ini, "", "plate_height_mm", 100); + + charHeightMM = getFloat(ini, "", "char_height_mm", 100); + charWidthMM = getFloat(ini, "", "char_width_mm", 100); + charWhitespaceTopMM = getFloat(ini, "", "char_whitespace_top_mm", 100); + charWhitespaceBotMM = getFloat(ini, "", "char_whitespace_bot_mm", 100); + + templateWidthPx = getInt(ini, "", "template_max_width_px", 100); + templateHeightPx = getInt(ini, "", "template_max_height_px", 100); + + charAnalysisMinPercent = getFloat(ini, "", "char_analysis_min_pct", 0); + charAnalysisHeightRange = getFloat(ini, "", "char_analysis_height_range", 0); + charAnalysisHeightStepSize = getFloat(ini, "", "char_analysis_height_step_size", 0); + charAnalysisNumSteps = getInt(ini, "", "char_analysis_height_num_steps", 0); + + segmentationMinBoxWidthPx = getInt(ini, "", "segmentation_min_box_width_px", 0); + segmentationMinCharHeightPercent = getFloat(ini, "", "segmentation_min_charheight_percent", 0); + segmentationMaxCharWidthvsAverage = getFloat(ini, "", "segmentation_max_segment_width_percent_vs_average", 0); + + plateLinesSensitivityVertical = getFloat(ini, "", "plateline_sensitivity_vertical", 0); + plateLinesSensitivityHorizontal = getFloat(ini, "", "plateline_sensitivity_horizontal", 0); + + ocrLanguage = getString(ini, "", "ocr_language", "none"); + ocrImageWidthPx = round(((float) templateWidthPx) * ocrImagePercent); ocrImageHeightPx = round(((float)templateHeightPx) * ocrImagePercent); - - - float stateIdImagePercent = getFloat("common", "state_id_img_size_percent", 100); stateIdImageWidthPx = round(((float)templateWidthPx) * stateIdImagePercent); stateIdimageHeightPx = round(((float)templateHeightPx) * stateIdImagePercent); - - - charAnalysisMinPercent = getFloat(country, "char_analysis_min_pct", 0); - charAnalysisHeightRange = getFloat(country, "char_analysis_height_range", 0); - charAnalysisHeightStepSize = getFloat(country, "char_analysis_height_step_size", 0); - charAnalysisNumSteps = getInt(country, "char_analysis_height_num_steps", 0); - - segmentationMinBoxWidthPx = getInt(country, "segmentation_min_box_width_px", 0); - segmentationMinCharHeightPercent = getFloat(country, "segmentation_min_charheight_percent", 0); - segmentationMaxCharWidthvsAverage = getFloat(country, "segmentation_max_segment_width_percent_vs_average", 0); - - plateLinesSensitivityVertical = getFloat(country, "plateline_sensitivity_vertical", 0); - plateLinesSensitivityHorizontal = getFloat(country, "plateline_sensitivity_horizontal", 0); - - ocrLanguage = getString(country, "ocr_language", "none"); - ocrMinFontSize = getInt("common", "ocr_min_font_point", 100); - - postProcessMinConfidence = getFloat("common", "postprocess_min_confidence", 100); - postProcessConfidenceSkipLevel = getFloat("common", "postprocess_confidence_skip_level", 100); - postProcessMaxSubstitutions = getInt("common", "postprocess_max_substitutions", 100); - postProcessMinCharacters = getInt("common", "postprocess_min_characters", 100); - postProcessMaxCharacters = getInt("common", "postprocess_max_characters", 100); - - debugGeneral = getBoolean("debug", "general", false); - debugTiming = getBoolean("debug", "timing", false); - debugPrewarp = getBoolean("debug", "prewarp", false); - debugDetector = getBoolean("debug", "detector", false); - debugStateId = getBoolean("debug", "state_id", false); - debugPlateLines = getBoolean("debug", "plate_lines", false); - debugPlateCorners = getBoolean("debug", "plate_corners", false); - debugCharSegmenter = getBoolean("debug", "char_segment", false); - debugCharAnalysis = getBoolean("debug", "char_analysis", false); - debugColorFiler = getBoolean("debug", "color_filter", false); - debugOcr = getBoolean("debug", "ocr", false); - debugPostProcess = getBoolean("debug", "postprocess", false); - debugShowImages = getBoolean("debug", "show_images", false); - debugPauseOnFrame = getBoolean("debug", "pause_on_frame", false); - + } void Config::debugOff() @@ -258,7 +278,7 @@ namespace alpr - float Config::getFloat(string section, string key, float defaultValue) + float Config::getFloat(CSimpleIniA* ini, string section, string key, float defaultValue) { const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/); if (pszValue == NULL) @@ -271,7 +291,7 @@ namespace alpr float val = atof(pszValue); return val; } - int Config::getInt(string section, string key, int defaultValue) + int Config::getInt(CSimpleIniA* ini, string section, string key, int defaultValue) { const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/); if (pszValue == NULL) @@ -284,7 +304,7 @@ namespace alpr int val = atoi(pszValue); return val; } - bool Config::getBoolean(string section, string key, bool defaultValue) + bool Config::getBoolean(CSimpleIniA* ini, string section, string key, bool defaultValue) { const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/); if (pszValue == NULL) @@ -297,7 +317,7 @@ namespace alpr int val = atoi(pszValue); return val != 0; } - string Config::getString(string section, string key, string defaultValue) + string Config::getString(CSimpleIniA* ini, string section, string key, string defaultValue) { const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/); if (pszValue == NULL) diff --git a/src/openalpr/config.h b/src/openalpr/config.h index 6960aa6..11a0eb4 100644 --- a/src/openalpr/config.h +++ b/src/openalpr/config.h @@ -128,17 +128,20 @@ namespace alpr std::string getPostProcessRuntimeDir(); std::string getTessdataPrefix(); - private: - CSimpleIniA* ini; - + private: + + float ocrImagePercent; + float stateIdImagePercent; + std::string runtimeBaseDir; - void loadValues(std::string country); + void loadCommonValues(std::string configFile); + void loadCountryValues(std::string configFile, std::string country); - int getInt(std::string section, std::string key, int defaultValue); - float getFloat(std::string section, std::string key, float defaultValue); - std::string getString(std::string section, std::string key, std::string defaultValue); - bool getBoolean(std::string section, std::string key, bool defaultValue); + int getInt(CSimpleIniA* ini, std::string section, std::string key, int defaultValue); + float getFloat(CSimpleIniA* ini, std::string section, std::string key, float defaultValue); + std::string getString(CSimpleIniA* ini, std::string section, std::string key, std::string defaultValue); + bool getBoolean(CSimpleIniA* ini, std::string section, std::string key, bool defaultValue); };