From e6d7226a0b13b417f6ca3eda3c23f916f3a0c20d Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sat, 25 Oct 2014 15:29:24 -0400 Subject: [PATCH] Removed characterregion class. This was just serving as a pass-through after recent changes --- config/openalpr.conf.in | 1 - src/misc_utilities/benchmarks/benchmark.cpp | 2 +- src/misc_utilities/classifychars.cpp | 2 +- src/openalpr/CMakeLists.txt | 1 - src/openalpr/characterregion.cpp | 109 ------------------ src/openalpr/characterregion.h | 54 --------- src/openalpr/config.cpp | 2 - src/openalpr/config.h | 1 - src/openalpr/licenseplatecandidate.cpp | 6 +- src/openalpr/licenseplatecandidate.h | 4 +- src/openalpr/platecorners.h | 1 - src/openalpr/platelines.h | 2 +- .../segmentation/charactersegmenter.h | 3 +- .../textdetection/characteranalysis.cpp | 66 ++++++++++- .../textdetection/characteranalysis.h | 2 +- 15 files changed, 75 insertions(+), 181 deletions(-) delete mode 100644 src/openalpr/characterregion.cpp delete mode 100644 src/openalpr/characterregion.h diff --git a/config/openalpr.conf.in b/config/openalpr.conf.in index b7761ff..d8db036 100644 --- a/config/openalpr.conf.in +++ b/config/openalpr.conf.in @@ -57,7 +57,6 @@ timing = 0 state_id = 0 plate_lines = 0 plate_corners = 0 -char_regions = 0 char_segment = 0 char_analysis = 0 color_filter = 0 diff --git a/src/misc_utilities/benchmarks/benchmark.cpp b/src/misc_utilities/benchmarks/benchmark.cpp index ccc24c3..35b3f7f 100644 --- a/src/misc_utilities/benchmarks/benchmark.cpp +++ b/src/misc_utilities/benchmarks/benchmark.cpp @@ -114,7 +114,7 @@ int main( int argc, const char** argv ) statecode[2] = '\0'; string statecodestr(statecode); - CharacterRegion charRegion(&pipeline_data); + CharacterAnalysis charRegion(&pipeline_data); if (pipeline_data.textLines.size() > 0 && abs(pipeline_data.textLines[0].angle) > 4) diff --git a/src/misc_utilities/classifychars.cpp b/src/misc_utilities/classifychars.cpp index 27448aa..a92723a 100644 --- a/src/misc_utilities/classifychars.cpp +++ b/src/misc_utilities/classifychars.cpp @@ -132,7 +132,7 @@ int main( int argc, const char** argv ) statecode[2] = '\0'; string statecodestr(statecode); - CharacterRegion regionizer(&pipeline_data); + CharacterAnalysis regionizer(&pipeline_data); if (abs(pipeline_data.textLines[0].angle) > 4) { diff --git a/src/openalpr/CMakeLists.txt b/src/openalpr/CMakeLists.txt index 2467186..ec4ac95 100644 --- a/src/openalpr/CMakeLists.txt +++ b/src/openalpr/CMakeLists.txt @@ -16,7 +16,6 @@ set(lpr_source_files postprocess.cpp binarize_wolf.cpp platelines.cpp - characterregion.cpp segmentation/charactersegmenter.cpp segmentation/verticalhistogram.cpp platecorners.cpp diff --git a/src/openalpr/characterregion.cpp b/src/openalpr/characterregion.cpp deleted file mode 100644 index e3e3e1c..0000000 --- a/src/openalpr/characterregion.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014 New Designs Unlimited, LLC - * Opensource 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 . -*/ - -#include "characterregion.h" - -using namespace cv; -using namespace std; - -CharacterRegion::CharacterRegion(PipelineData* pipeline_data) -{ - this->config = pipeline_data->config; - this->debug = config->debugCharRegions; - - this->confidence = 0; - - if (this->debug) - cout << "Starting CharacterRegion identification" << endl; - - timespec startTime; - getTime(&startTime); - - charAnalysis = new CharacterAnalysis(pipeline_data); - charAnalysis->analyze(); - pipeline_data->plate_inverted = charAnalysis->thresholdsInverted; - - if (this->debug && pipeline_data->textLines.size() > 0) - { - vector tempDash; - for (uint z = 0; z < pipeline_data->thresholds.size(); z++) - { - Mat tmp(pipeline_data->thresholds[z].size(), pipeline_data->thresholds[z].type()); - pipeline_data->thresholds[z].copyTo(tmp); - cvtColor(tmp, tmp, CV_GRAY2BGR); - - tempDash.push_back(tmp); - } - - Mat bestVal(charAnalysis->bestThreshold.size(), charAnalysis->bestThreshold.type()); - charAnalysis->bestThreshold.copyTo(bestVal); - cvtColor(bestVal, bestVal, CV_GRAY2BGR); - - for (uint z = 0; z < charAnalysis->bestContours.size(); z++) - { - Scalar dcolor(255,0,0); - if (charAnalysis->bestContours.goodIndices[z]) - dcolor = Scalar(0,255,0); - drawContours(bestVal, charAnalysis->bestContours.contours, z, dcolor, 1); - } - tempDash.push_back(bestVal); - displayImage(config, "Character Region Step 1 Thresholds", drawImageDashboard(tempDash, bestVal.type(), 3)); - } - - - if (pipeline_data->textLines.size() > 0) - { - int confidenceDrainers = 0; - int charSegmentCount = charAnalysis->bestContours.getGoodIndicesCount(); - if (charSegmentCount == 1) - confidenceDrainers += 91; - else if (charSegmentCount < 5) - confidenceDrainers += (5 - charSegmentCount) * 10; - - // Use the angle for the first line -- assume they'll always be parallel for multi-line plates - int absangle = abs(pipeline_data->textLines[0].topLine.angle); - if (absangle > config->maxPlateAngleDegrees) - confidenceDrainers += 91; - else if (absangle > 1) - confidenceDrainers += (config->maxPlateAngleDegrees - absangle) ; - - // If a multiline plate has only one line, disqualify - if (pipeline_data->isMultiline && pipeline_data->textLines.size() < 2) - confidenceDrainers += 95; - - if (confidenceDrainers >= 100) - this->confidence=1; - else - this->confidence = 100 - confidenceDrainers; - } - - if (config->debugTiming) - { - timespec endTime; - getTime(&endTime); - cout << "Character Region Time: " << diffclock(startTime, endTime) << "ms." << endl; - } -} - -CharacterRegion::~CharacterRegion() -{ - delete(charAnalysis); -} - - diff --git a/src/openalpr/characterregion.h b/src/openalpr/characterregion.h deleted file mode 100644 index ba55624..0000000 --- a/src/openalpr/characterregion.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014 New Designs Unlimited, LLC - * Opensource 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 . -*/ - -#ifndef OPENALPR_CHARACTERREGION_H -#define OPENALPR_CHARACTERREGION_H - -#include "opencv2/imgproc/imgproc.hpp" -#include "constants.h" -#include "utility.h" -#include "textdetection/characteranalysis.h" -#include "config.h" -#include "pipeline_data.h" - -class CharacterRegion -{ - - public: - CharacterRegion(PipelineData* pipeline_data); - virtual ~CharacterRegion(); - - - int confidence; - - - - protected: - Config* config; - bool debug; - - CharacterAnalysis *charAnalysis; - cv::Mat findOuterBoxMask(std::vector thresholds, std::vector > > allContours, std::vector > allHierarchy); - - - bool isPlateInverted(cv::Mat threshold, std::vector > contours, std::vector hierarchy, std::vector goodIndices); - -}; - -#endif // OPENALPR_CHARACTERREGION_H diff --git a/src/openalpr/config.cpp b/src/openalpr/config.cpp index 2f30a29..81a1fe4 100644 --- a/src/openalpr/config.cpp +++ b/src/openalpr/config.cpp @@ -188,7 +188,6 @@ void Config::loadValues(string country) debugStateId = getBoolean("debug", "state_id", false); debugPlateLines = getBoolean("debug", "plate_lines", false); debugPlateCorners = getBoolean("debug", "plate_corners", false); - debugCharRegions = getBoolean("debug", "char_regions", false); debugCharSegmenter = getBoolean("debug", "char_segment", false); debugCharAnalysis = getBoolean("debug", "char_analysis", false); debugColorFiler = getBoolean("debug", "color_filter", false); @@ -206,7 +205,6 @@ void Config::debugOff() debugStateId = false; debugPlateLines = false; debugPlateCorners = false; - debugCharRegions = false; debugCharSegmenter = false; debugCharAnalysis = false; debugColorFiler = false; diff --git a/src/openalpr/config.h b/src/openalpr/config.h index 7477b79..a752441 100644 --- a/src/openalpr/config.h +++ b/src/openalpr/config.h @@ -103,7 +103,6 @@ class Config bool debugStateId; bool debugPlateLines; bool debugPlateCorners; - bool debugCharRegions; bool debugCharSegmenter; bool debugCharAnalysis; bool debugColorFiler; diff --git a/src/openalpr/licenseplatecandidate.cpp b/src/openalpr/licenseplatecandidate.cpp index 9adc533..c7fda6b 100644 --- a/src/openalpr/licenseplatecandidate.cpp +++ b/src/openalpr/licenseplatecandidate.cpp @@ -51,9 +51,9 @@ void LicensePlateCandidate::recognize() resize(pipeline_data->crop_gray, pipeline_data->crop_gray, Size(config->templateWidthPx, config->templateHeightPx)); - CharacterRegion charRegion(pipeline_data); + CharacterAnalysis textAnalysis(pipeline_data); - if (charRegion.confidence > 10) + if (textAnalysis.confidence > 10) { PlateLines plateLines(pipeline_data); @@ -119,7 +119,7 @@ void LicensePlateCandidate::recognize() pipeline_data->plate_area_confidence = 100; } - charRegion.confidence = 0; + } } diff --git a/src/openalpr/licenseplatecandidate.h b/src/openalpr/licenseplatecandidate.h index 63534f5..aeb76af 100644 --- a/src/openalpr/licenseplatecandidate.h +++ b/src/openalpr/licenseplatecandidate.h @@ -30,7 +30,7 @@ #include "utility.h" #include "constants.h" #include "platelines.h" -#include "characterregion.h" +#include "textdetection/characteranalysis.h" #include "segmentation/charactersegmenter.h" #include "platecorners.h" #include "config.h" @@ -57,7 +57,7 @@ class LicensePlateCandidate CharacterSegmenter* charSegmenter; cv::Mat filterByCharacterHue(std::vector > charRegionContours); - std::vector findPlateCorners(cv::Mat inputImage, PlateLines plateLines, CharacterRegion charRegion); // top-left, top-right, bottom-right, bottom-left + std::vector findPlateCorners(cv::Mat inputImage, PlateLines plateLines, CharacterAnalysis textAnalysis); // top-left, top-right, bottom-right, bottom-left cv::Size getOutputImageSize(std::vector corners); std::vector transformPointsToOriginalImage(cv::Mat bigImage, cv::Mat smallImage, cv::Rect region, std::vector corners); diff --git a/src/openalpr/platecorners.h b/src/openalpr/platecorners.h index 5fc06df..c297513 100644 --- a/src/openalpr/platecorners.h +++ b/src/openalpr/platecorners.h @@ -21,7 +21,6 @@ #define OPENALPR_PLATECORNERS_H #include "opencv2/imgproc/imgproc.hpp" -#include "characterregion.h" #include "platelines.h" #include "utility.h" #include "config.h" diff --git a/src/openalpr/platelines.h b/src/openalpr/platelines.h index 40a9016..f25be91 100644 --- a/src/openalpr/platelines.h +++ b/src/openalpr/platelines.h @@ -25,7 +25,7 @@ #include "utility.h" #include "binarize_wolf.h" #include "config.h" -#include "characterregion.h" +#include "pipeline_data.h" struct PlateLine { diff --git a/src/openalpr/segmentation/charactersegmenter.h b/src/openalpr/segmentation/charactersegmenter.h index b468e62..54b9c22 100644 --- a/src/openalpr/segmentation/charactersegmenter.h +++ b/src/openalpr/segmentation/charactersegmenter.h @@ -24,11 +24,10 @@ #include "constants.h" #include "binarize_wolf.h" #include "utility.h" -#include "characterregion.h" -#include "colorfilter.h" #include "verticalhistogram.h" #include "config.h" #include "textdetection/textcontours.h" +#include "pipeline_data.h" //const float MIN_BOX_WIDTH_PX = 4; // 4 pixels diff --git a/src/openalpr/textdetection/characteranalysis.cpp b/src/openalpr/textdetection/characteranalysis.cpp index d959ff5..1b9f25b 100644 --- a/src/openalpr/textdetection/characteranalysis.cpp +++ b/src/openalpr/textdetection/characteranalysis.cpp @@ -32,10 +32,12 @@ CharacterAnalysis::CharacterAnalysis(PipelineData* pipeline_data) this->pipeline_data = pipeline_data; this->config = pipeline_data->config; + this->confidence = 0; if (this->config->debugCharAnalysis) cout << "Starting CharacterAnalysis identification" << endl; + this->analyze(); } CharacterAnalysis::~CharacterAnalysis() @@ -168,8 +170,70 @@ void CharacterAnalysis::analyze() } + pipeline_data->plate_inverted = isPlateInverted(); - this->thresholdsInverted = isPlateInverted(); + + if (pipeline_data->textLines.size() > 0) + { + int confidenceDrainers = 0; + int charSegmentCount = this->bestContours.getGoodIndicesCount(); + if (charSegmentCount == 1) + confidenceDrainers += 91; + else if (charSegmentCount < 5) + confidenceDrainers += (5 - charSegmentCount) * 10; + + // Use the angle for the first line -- assume they'll always be parallel for multi-line plates + int absangle = abs(pipeline_data->textLines[0].topLine.angle); + if (absangle > config->maxPlateAngleDegrees) + confidenceDrainers += 91; + else if (absangle > 1) + confidenceDrainers += (config->maxPlateAngleDegrees - absangle) ; + + // If a multiline plate has only one line, disqualify + if (pipeline_data->isMultiline && pipeline_data->textLines.size() < 2) + confidenceDrainers += 95; + + if (confidenceDrainers >= 100) + this->confidence=1; + else + this->confidence = 100 - confidenceDrainers; + } + + + if (config->debugTiming) + { + timespec endTime; + getTime(&endTime); + cout << "Character Analysis Time: " << diffclock(startTime, endTime) << "ms." << endl; + } + + // Draw debug dashboard + if (this->pipeline_data->config->debugCharAnalysis && pipeline_data->textLines.size() > 0) + { + vector tempDash; + for (uint z = 0; z < pipeline_data->thresholds.size(); z++) + { + Mat tmp(pipeline_data->thresholds[z].size(), pipeline_data->thresholds[z].type()); + pipeline_data->thresholds[z].copyTo(tmp); + cvtColor(tmp, tmp, CV_GRAY2BGR); + + tempDash.push_back(tmp); + } + + Mat bestVal(this->bestThreshold.size(), this->bestThreshold.type()); + this->bestThreshold.copyTo(bestVal); + cvtColor(bestVal, bestVal, CV_GRAY2BGR); + + for (uint z = 0; z < this->bestContours.size(); z++) + { + Scalar dcolor(255,0,0); + if (this->bestContours.goodIndices[z]) + dcolor = Scalar(0,255,0); + drawContours(bestVal, this->bestContours.contours, z, dcolor, 1); + } + tempDash.push_back(bestVal); + displayImage(config, "Character Region Step 1 Thresholds", drawImageDashboard(tempDash, bestVal.type(), 3)); + } } diff --git a/src/openalpr/textdetection/characteranalysis.h b/src/openalpr/textdetection/characteranalysis.h index 6223cd8..830ea32 100644 --- a/src/openalpr/textdetection/characteranalysis.h +++ b/src/openalpr/textdetection/characteranalysis.h @@ -36,12 +36,12 @@ class CharacterAnalysis CharacterAnalysis(PipelineData* pipeline_data); virtual ~CharacterAnalysis(); + int confidence; cv::Mat bestThreshold; TextContours bestContours; - bool thresholdsInverted; std::vector allTextContours;