From d1d83fe4043922b719344f1fb303e469820cf911 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 10 Jun 2014 18:03:42 -0400 Subject: [PATCH] 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 --- config/openalpr.conf | 16 +++++++++++++++- src/openalpr/config.cpp | 3 +++ src/openalpr/config.h | 3 +++ src/openalpr/regiondetector.cpp | 26 +++++++++++++++++++++----- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/config/openalpr.conf b/config/openalpr.conf index 597b071..9fb15cf 100644 --- a/config/openalpr.conf +++ b/config/openalpr.conf @@ -7,16 +7,30 @@ runtime_dir = /usr/share/openalpr/runtime_data ocr_img_size_percent = 1.33333333 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_height_percent = 100 - ; 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. ; 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 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 multithreading_cores = 1 diff --git a/src/openalpr/config.cpp b/src/openalpr/config.cpp index 3401623..b592eb7 100644 --- a/src/openalpr/config.cpp +++ b/src/openalpr/config.cpp @@ -118,8 +118,11 @@ void Config::loadValues(string country) multithreading_cores = getInt("common", "multithreading_cores", 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); 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); diff --git a/src/openalpr/config.h b/src/openalpr/config.h index d09f1e0..1d439dd 100644 --- a/src/openalpr/config.h +++ b/src/openalpr/config.h @@ -48,8 +48,11 @@ class Config int multithreading_cores; float detection_iteration_increase; + int detectionStrictness; float maxPlateWidthPercent; float maxPlateHeightPercent; + int maxDetectionInputWidth; + int maxDetectionInputHeight; int maxPlateAngleDegrees; diff --git a/src/openalpr/regiondetector.cpp b/src/openalpr/regiondetector.cpp index 5c78070..c0aeb1f 100644 --- a/src/openalpr/regiondetector.cpp +++ b/src/openalpr/regiondetector.cpp @@ -25,7 +25,6 @@ using namespace std; RegionDetector::RegionDetector(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; // Load either the regular or OpenCL version of the cascade classifier @@ -59,7 +58,7 @@ vector RegionDetector::detect(Mat frame) Mat frame_gray; cvtColor( frame, frame_gray, CV_BGR2GRAY ); - + vector regionsOfInterest = doCascade(frame_gray); return regionsOfInterest; @@ -68,7 +67,25 @@ vector RegionDetector::detect(Mat frame) /** @function detectAndDisplay */ vector 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 h = frame.size().height; @@ -84,8 +101,7 @@ vector RegionDetector::doCascade(Mat frame) 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); - - plate_cascade->detectMultiScale( frame, plates, config->detection_iteration_increase, 3, + plate_cascade->detectMultiScale( frame, plates, config->detection_iteration_increase, config->detectionStrictness, 0, //0|CV_HAAR_SCALE_IMAGE, minSize, maxSize );