Refactored openalpr.conf to use a default config file and allow an override

in /etc/openalpr/openalpr.conf.  
This makes upgrades easier, since the package can maintain the default config 
without overriding user settings
This commit is contained in:
Matt Hill
2016-03-21 16:50:20 -04:00
parent 41991a3d8d
commit 4504921c14
8 changed files with 278 additions and 112 deletions

View File

@@ -0,0 +1,2 @@
; This configuration file overrides the default values specified
; in ${CMAKE_INSTALL_PREFIX}/share/openalpr/config/openalpr.defaults.conf

View File

@@ -15,6 +15,8 @@ add_definitions( -DOPENALPR_PATCH_VERSION=${OPENALPR_PATCH_VERSION})
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules/")
add_definitions( -DINSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
# TODO: switch to http://www.cmake.org/cmake/help/v2.8.5/cmake.html#module:GNUInstallDirs ?
IF (NOT CMAKE_INSTALL_SYSCONFDIR)
SET(CMAKE_INSTALL_SYSCONFDIR "/etc")
@@ -203,9 +205,12 @@ ENDIF()
install (DIRECTORY ${CMAKE_SOURCE_DIR}/../runtime_data DESTINATION ${CMAKE_INSTALL_PREFIX}/share/openalpr)
# set runtime_data to reflect the current CMAKE_INSTALL_PREFIX
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/../config/openalpr.conf.in ${CMAKE_CURRENT_BINARY_DIR}/config/openalpr.conf)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/../config/openalpr.conf.user ${CMAKE_CURRENT_BINARY_DIR}/config/openalpr.conf)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/config/openalpr.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/openalpr/ COMPONENT config)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/../config/openalpr.conf.defaults ${CMAKE_CURRENT_BINARY_DIR}/share/openalpr/config/openalpr.defaults.conf)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/share/openalpr/config/openalpr.defaults.conf DESTINATION ${CMAKE_INSTALL_PREFIX}/share/openalpr/config COMPONENT config)
IF (WITH_DAEMON)
install (TARGETS alprd DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
install (FILES ${CMAKE_SOURCE_DIR}/../config/alprd.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/openalpr COMPONENT config)

View File

@@ -5,6 +5,7 @@ set(lpr_source_files
alpr.cpp
alpr_impl.cpp
config.cpp
config_helper.cpp
detection/detector.cpp
detection/detectorcpu.cpp
detection/detectorcuda.cpp

View File

@@ -22,6 +22,7 @@
#include "support/platform.h"
#include "simpleini/simpleini.h"
#include "utility.h"
#include "config_helper.h"
using namespace std;
@@ -29,12 +30,6 @@ namespace alpr
{
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);
std::vector<float> getAllFloats(CSimpleIniA* ini, string section, string key);
Config::Config(const std::string country, const std::string config_file, const std::string runtime_dir)
{
@@ -153,13 +148,26 @@ namespace alpr
void Config::loadCommonValues(string configFile)
{
CSimpleIniA* ini = NULL;
CSimpleIniA iniObj;
iniObj.LoadFile(configFile.c_str());
CSimpleIniA* ini = &iniObj;
if (fileExists(configFile.c_str()))
{
iniObj.LoadFile(configFile.c_str());
ini = &iniObj;
}
runtimeBaseDir = getString(ini, "", "runtime_dir", "/usr/share/openalpr/runtime_data");
std::string detectorString = getString(ini, "", "detector", "lbpcpu");
CSimpleIniA* defaultIni = NULL;
CSimpleIniA defaultIniObj;
if (fileExists(CONFIG_FILE_TEMPLATE_LOCATION))
{
defaultIniObj.LoadFile(CONFIG_FILE_TEMPLATE_LOCATION);
defaultIni = &defaultIniObj;
}
runtimeBaseDir = getString(ini,defaultIni, "", "runtime_dir", DEFAULT_RUNTIME_DATA_DIR);
std::string detectorString = getString(ini, defaultIni, "", "detector", "lbpcpu");
std::transform(detectorString.begin(), detectorString.end(), detectorString.begin(), ::tolower);
if (detectorString.compare("lbpcpu") == 0)
@@ -176,50 +184,50 @@ namespace alpr
detector = DETECTOR_LBP_CPU;
}
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);
detection_iteration_increase = getFloat(ini, defaultIni, "", "detection_iteration_increase", 1.1);
detectionStrictness = getInt(ini, defaultIni, "", "detection_strictness", 3);
maxPlateWidthPercent = getFloat(ini, defaultIni, "", "max_plate_width_percent", 100);
maxPlateHeightPercent = getFloat(ini, defaultIni, "", "max_plate_height_percent", 100);
maxDetectionInputWidth = getInt(ini, defaultIni, "", "max_detection_input_width", 1280);
maxDetectionInputHeight = getInt(ini, defaultIni, "", "max_detection_input_height", 768);
contrastDetectionThreshold = getFloat(ini, "", "contrast_detection_threshold", 0.3);
contrastDetectionThreshold = getFloat(ini, defaultIni, "", "contrast_detection_threshold", 0.3);
mustMatchPattern = getBoolean(ini, "", "must_match_pattern", false);
mustMatchPattern = getBoolean(ini, defaultIni, "", "must_match_pattern", false);
skipDetection = getBoolean(ini, "", "skip_detection", false);
skipDetection = getBoolean(ini, defaultIni, "", "skip_detection", false);
detection_mask_image = getString(ini, "", "detection_mask_image", "");
detection_mask_image = getString(ini, defaultIni, "", "detection_mask_image", "");
analysis_count = getInt(ini, "", "analysis_count", 1);
analysis_count = getInt(ini, defaultIni, "", "analysis_count", 1);
prewarp = getString(ini, "", "prewarp", "");
prewarp = getString(ini, defaultIni, "", "prewarp", "");
maxPlateAngleDegrees = getInt(ini, "", "max_plate_angle_degrees", 15);
maxPlateAngleDegrees = getInt(ini, defaultIni, "", "max_plate_angle_degrees", 15);
ocrImagePercent = getFloat(ini, "", "ocr_img_size_percent", 100);
stateIdImagePercent = getFloat(ini, "", "state_id_img_size_percent", 100);
ocrImagePercent = getFloat(ini, defaultIni, "", "ocr_img_size_percent", 100);
stateIdImagePercent = getFloat(ini, defaultIni, "", "state_id_img_size_percent", 100);
ocrMinFontSize = getInt(ini, "", "ocr_min_font_point", 100);
ocrMinFontSize = getInt(ini, defaultIni, "", "ocr_min_font_point", 100);
postProcessMinConfidence = getFloat(ini, "", "postprocess_min_confidence", 100);
postProcessConfidenceSkipLevel = getFloat(ini, "", "postprocess_confidence_skip_level", 100);
postProcessMinConfidence = getFloat(ini, defaultIni, "", "postprocess_min_confidence", 100);
postProcessConfidenceSkipLevel = getFloat(ini, defaultIni, "", "postprocess_confidence_skip_level", 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);
debugGeneral = getBoolean(ini, defaultIni, "", "debug_general", false);
debugTiming = getBoolean(ini, defaultIni, "", "debug_timing", false);
debugPrewarp = getBoolean(ini, defaultIni, "", "debug_prewarp", false);
debugDetector = getBoolean(ini, defaultIni, "", "debug_detector", false);
debugStateId = getBoolean(ini, defaultIni, "", "debug_state_id", false);
debugPlateLines = getBoolean(ini, defaultIni, "", "debug_plate_lines", false);
debugPlateCorners = getBoolean(ini, defaultIni, "", "debug_plate_corners", false);
debugCharSegmenter = getBoolean(ini, defaultIni, "", "debug_char_segment", false);
debugCharAnalysis = getBoolean(ini, defaultIni, "", "debug_char_analysis", false);
debugColorFiler = getBoolean(ini, defaultIni, "", "debug_color_filter", false);
debugOcr = getBoolean(ini, defaultIni, "", "debug_ocr", false);
debugPostProcess = getBoolean(ini, defaultIni, "", "debug_postprocess", false);
debugShowImages = getBoolean(ini, defaultIni, "", "debug_show_images", false);
debugPauseOnFrame = getBoolean(ini, defaultIni, "", "debug_pause_on_frame", false);
}
@@ -396,69 +404,6 @@ namespace alpr
return true;
}
float 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)
{
return defaultValue;
}
float val = atof(pszValue);
return val;
}
std::vector<float> getAllFloats(CSimpleIniA* ini, string section, string key)
{
CSimpleIniA::TNamesDepend values;
ini->GetAllValues(section.c_str(), key.c_str(), values);
// sort the values into the original load order
values.sort(CSimpleIniA::Entry::LoadOrder());
std::vector<float> response;
// output all of the items
CSimpleIniA::TNamesDepend::const_iterator i;
for (i = values.begin(); i != values.end(); ++i) {
response.push_back(atof(i->pItem));
}
return response;
}
int 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)
{
return defaultValue;
}
int val = atoi(pszValue);
return val;
}
bool 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)
{
return defaultValue;
}
int val = atoi(pszValue);
return val != 0;
}
string 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)
{
return defaultValue;
}
string val = string(pszValue);
return val;
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2015 OpenALPR Technology, Inc.
* Open source Automated License Plate Recognition [http://www.openalpr.com]
*
* This file is part of OpenALPR.
*
* OpenALPR is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config_helper.h"
#include <iostream>
using namespace std;
namespace alpr
{
float getFloat(CSimpleIniA* ini, string section, string key, float defaultValue)
{
if (ini == NULL)
return defaultValue;
const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/);
if (pszValue == NULL)
{
return defaultValue;
}
float val = atof(pszValue);
return val;
}
std::vector<float> getAllFloats(CSimpleIniA* ini, string section, string key)
{
CSimpleIniA::TNamesDepend values;
ini->GetAllValues(section.c_str(), key.c_str(), values);
// sort the values into the original load order
values.sort(CSimpleIniA::Entry::LoadOrder());
std::vector<float> response;
// output all of the items
CSimpleIniA::TNamesDepend::const_iterator i;
for (i = values.begin(); i != values.end(); ++i) {
response.push_back(atof(i->pItem));
}
return response;
}
int getInt(CSimpleIniA* ini, string section, string key, int defaultValue)
{
if (ini == NULL)
return defaultValue;
const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/);
if (pszValue == NULL)
{
return defaultValue;
}
int val = atoi(pszValue);
return val;
}
bool getBoolean(CSimpleIniA* ini, string section, string key, bool defaultValue)
{
if (ini == NULL)
return defaultValue;
const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/);
if (pszValue == NULL)
{
return defaultValue;
}
int val = atoi(pszValue);
return val != 0;
}
string getString(CSimpleIniA* ini, string section, string key, string defaultValue)
{
if (ini == NULL)
return defaultValue;
const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/);
if (pszValue == NULL)
{
return defaultValue;
}
string val = string(pszValue);
return val;
}
bool hasValue(CSimpleIniA* ini, std::string section, std::string key)
{
const char * pszValue = ini->GetValue(section.c_str(), key.c_str(), NULL /*default*/);
return pszValue != NULL;
}
int getInt(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, int defaultValue)
{
if (hasValue(ini, section, key))
return getInt(ini, section, key, defaultValue);
if (defaultIni != NULL && hasValue(defaultIni, section, key))
return getInt(defaultIni, section, key, defaultValue);
std::cerr << "Missing config value for " << key << std::endl;
return defaultValue;
}
float getFloat(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, float defaultValue)
{
if (hasValue(ini, section, key))
return getFloat(ini, section, key, defaultValue);
if (defaultIni != NULL && hasValue(defaultIni, section, key))
return getFloat(defaultIni, section, key, defaultValue);
std::cerr << "Missing config value for " << key << std::endl;
return defaultValue;
}
std::string getString(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, std::string defaultValue)
{
if (hasValue(ini, section, key))
return getString(ini, section, key, defaultValue);
if (defaultIni != NULL && hasValue(defaultIni, section, key))
return getString(defaultIni, section, key, defaultValue);
std::cerr << "Missing config value for " << key << std::endl;
return defaultValue;
}
bool getBoolean(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, bool defaultValue)
{
if (hasValue(ini, section, key))
return getBoolean(ini, section, key, defaultValue);
if (defaultIni != NULL && hasValue(defaultIni, section, key))
return getBoolean(defaultIni, section, key, defaultValue);
std::cerr << "Missing config value for " << key << std::endl;
return defaultValue;
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2015 OpenALPR Technology, Inc.
* Open source Automated License Plate Recognition [http://www.openalpr.com]
*
* This file is part of OpenALPR.
*
* OpenALPR is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENALPR_CONFIG_HELPER_H
#define OPENALPR_CONFIG_HELPER_H
#include "simpleini/simpleini.h"
#include <string>
#include <vector>
namespace alpr
{
bool hasValue(CSimpleIniA* ini, std::string section, std::string key);
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);
std::vector<float> getAllFloats(CSimpleIniA* ini, std::string section, std::string key);
// Checks the ini objects in the order they are placed in the vector
// e.g., second ini object overrides the first if they both have the value
int getInt(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, int defaultValue);
float getFloat(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, float defaultValue);
std::string getString(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, std::string defaultValue);
bool getBoolean(CSimpleIniA* ini, CSimpleIniA* defaultIni, std::string section, std::string key, bool defaultValue);
}
#endif /* CONFIG_HELPER_H */

View File

@@ -27,6 +27,11 @@
#define CASCADE_DIR "/region/"
#define POSTPROCESS_DIR "/postprocess"
#define DEFAULT_SHARE_DIR INSTALL_PREFIX "/share/openalpr"
#define DEFAULT_RUNTIME_DATA_DIR DEFAULT_SHARE_DIR "/runtime_data"
#define CONFIG_FILE_TEMPLATE_LOCATION DEFAULT_SHARE_DIR "/config/openalpr.defaults.conf"
#ifndef DEFAULT_CONFIG_FILE
#define DEFAULT_CONFIG_FILE "/etc/openalpr/openalpr.conf"
#endif