Added two new configuration options to control detection.

Enforcing a maximum resolution for the image input to detection
Adding a configurable "strictness" to tighten or loosen the detection leniency
This commit is contained in:
Matt Hill
2014-06-10 18:03:42 -04:00
parent caaf44120c
commit d1d83fe404
4 changed files with 42 additions and 6 deletions

View File

@@ -7,16 +7,30 @@ runtime_dir = /usr/share/openalpr/runtime_data
ocr_img_size_percent = 1.33333333 ocr_img_size_percent = 1.33333333
state_id_img_size_percent = 2.0 state_id_img_size_percent = 2.0
; detection will ignore plates that are too large. This is a good efficiency technique to use if the
; plates are going to be a fixed distance away from the camera (e.g., you will never see plates that fill
; up the entire image
max_plate_width_percent = 100 max_plate_width_percent = 100
max_plate_height_percent = 100 max_plate_height_percent = 100
; detection_iteration_increase is the percentage that the LBP frame increases each iteration. ; detection_iteration_increase is the percentage that the LBP frame increases each iteration.
; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time. ; It must be greater than 1.0. A value of 1.01 means increase by 1%, 1.10 increases it by 10% each time.
; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing ; So a 1% increase would be ~10x slower than 10% to process, but it has a higher chance of landing
; directly on the plate and getting a strong detection ; directly on the plate and getting a strong detection
detection_iteration_increase = 1.1 detection_iteration_increase = 1.1
; The minimum detection strength determines how sure the detection algorithm must be before signaling that
; a plate region exists. Technically this corresponds to LBP nearest neighbors (e.g., how many detections
; are clustered around the same area). For example, 2 = very lenient, 9 = very strict.
detection_strictness = 3
; The detection doesn't necessarily need an extremely high resolution image in order to detect plates
; Using a smaller input image should still find the plates and will do it faster
; Tweaking the max_detection_input values will resize the input image if it is larger than these sizes
; max_detection_input_width/height are specified in pixels
max_detection_input_width = 1280
max_detection_input_height = 720
opencl_enabled = 0 opencl_enabled = 0
multithreading_cores = 1 multithreading_cores = 1

View File

@@ -118,8 +118,11 @@ void Config::loadValues(string country)
multithreading_cores = getInt("common", "multithreading_cores", 1); multithreading_cores = getInt("common", "multithreading_cores", 1);
detection_iteration_increase = getFloat("common", "detection_iteration_increase", 1.1); detection_iteration_increase = getFloat("common", "detection_iteration_increase", 1.1);
detectionStrictness = getInt("common", "detection_strictness", 3);
maxPlateWidthPercent = getFloat("common", "max_plate_width_percent", 100); maxPlateWidthPercent = getFloat("common", "max_plate_width_percent", 100);
maxPlateHeightPercent = getFloat("common", "max_plate_height_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);
maxPlateAngleDegrees = getInt("common", "max_plate_angle_degrees", 15); maxPlateAngleDegrees = getInt("common", "max_plate_angle_degrees", 15);

View File

@@ -48,8 +48,11 @@ class Config
int multithreading_cores; int multithreading_cores;
float detection_iteration_increase; float detection_iteration_increase;
int detectionStrictness;
float maxPlateWidthPercent; float maxPlateWidthPercent;
float maxPlateHeightPercent; float maxPlateHeightPercent;
int maxDetectionInputWidth;
int maxDetectionInputHeight;
int maxPlateAngleDegrees; int maxPlateAngleDegrees;

View File

@@ -25,7 +25,6 @@ using namespace std;
RegionDetector::RegionDetector(Config* config) RegionDetector::RegionDetector(Config* config)
{ {
this->config = config; this->config = config;
// Don't scale. Can change this in the future (i.e., maximum resolution preference, or some such).
this->scale_factor = 1.0f; this->scale_factor = 1.0f;
// Load either the regular or OpenCL version of the cascade classifier // Load either the regular or OpenCL version of the cascade classifier
@@ -59,7 +58,7 @@ vector<PlateRegion> RegionDetector::detect(Mat frame)
Mat frame_gray; Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY ); cvtColor( frame, frame_gray, CV_BGR2GRAY );
vector<PlateRegion> regionsOfInterest = doCascade(frame_gray); vector<PlateRegion> regionsOfInterest = doCascade(frame_gray);
return regionsOfInterest; return regionsOfInterest;
@@ -68,7 +67,25 @@ vector<PlateRegion> RegionDetector::detect(Mat frame)
/** @function detectAndDisplay */ /** @function detectAndDisplay */
vector<PlateRegion> RegionDetector::doCascade(Mat frame) vector<PlateRegion> RegionDetector::doCascade(Mat frame)
{ {
//float scale_factor = 1;
if (frame.cols > config->maxDetectionInputWidth)
{
// The frame is too wide
this->scale_factor = ((float) config->maxDetectionInputWidth) / ((float) frame.cols);
if (config->debugGeneral)
std::cout << "Input detection image is too wide. Resizing with scale: " << this->scale_factor << endl;
}
else if (frame.rows > config->maxDetectionInputHeight)
{
// The frame is too tall
this->scale_factor = ((float) config->maxDetectionInputHeight) / ((float) frame.rows);
if (config->debugGeneral)
std::cout << "Input detection image is too tall. Resizing with scale: " << this->scale_factor << endl;
}
int w = frame.size().width; int w = frame.size().width;
int h = frame.size().height; int h = frame.size().height;
@@ -84,8 +101,7 @@ vector<PlateRegion> RegionDetector::doCascade(Mat frame)
Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor); Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor);
Size maxSize(w * config->maxPlateWidthPercent * this->scale_factor, h * config->maxPlateHeightPercent * this->scale_factor); Size maxSize(w * config->maxPlateWidthPercent * this->scale_factor, h * config->maxPlateHeightPercent * this->scale_factor);
plate_cascade->detectMultiScale( frame, plates, config->detection_iteration_increase, config->detectionStrictness,
plate_cascade->detectMultiScale( frame, plates, config->detection_iteration_increase, 3,
0, 0,
//0|CV_HAAR_SCALE_IMAGE, //0|CV_HAAR_SCALE_IMAGE,
minSize, maxSize ); minSize, maxSize );