diff --git a/src/misc_utilities/benchmark/benchmark.cpp b/src/misc_utilities/benchmark/benchmark.cpp index 51ead18..106689d 100644 --- a/src/misc_utilities/benchmark/benchmark.cpp +++ b/src/misc_utilities/benchmark/benchmark.cpp @@ -104,6 +104,8 @@ int main( int argc, const char** argv ) plateCoords.y = 0; plateCoords.width = frame.cols; plateCoords.height = frame.rows; + + PipelineData pipeline_data(frame, plateCoords, config); char statecode[3]; statecode[0] = files[i][0]; @@ -111,7 +113,7 @@ int main( int argc, const char** argv ) statecode[2] = '\0'; string statecodestr(statecode); - CharacterRegion charRegion(frame, config); + CharacterRegion charRegion(&pipeline_data); if (abs(charRegion.getTopLine().angle) > 4) { @@ -124,9 +126,10 @@ int main( int argc, const char** argv ) warpAffine( frame, rotated, rot_mat, frame.size() ); rotated.copyTo(frame); + pipeline_data.crop_gray = frame; } - CharacterSegmenter charSegmenter(frame, charRegion.thresholdsInverted(), config); + CharacterSegmenter charSegmenter(&pipeline_data); ocr->performOCR(charSegmenter.getThresholds(), charSegmenter.characters); ocr->postProcessor->analyze(statecode, 25); diff --git a/src/misc_utilities/classifychars.cpp b/src/misc_utilities/classifychars.cpp index e90e35d..b41041e 100644 --- a/src/misc_utilities/classifychars.cpp +++ b/src/misc_utilities/classifychars.cpp @@ -124,13 +124,14 @@ int main( int argc, const char** argv ) imshow ("Original", frame); + PipelineData pipeline_data(frame, Rect(0, 0, frame.cols, frame.rows), &config); char statecode[3]; statecode[0] = files[i][0]; statecode[1] = files[i][1]; statecode[2] = '\0'; string statecodestr(statecode); - CharacterRegion regionizer(frame, &config); + CharacterRegion regionizer(&pipeline_data); if (abs(regionizer.getTopLine().angle) > 4) { @@ -143,9 +144,10 @@ int main( int argc, const char** argv ) warpAffine( frame, rotated, rot_mat, frame.size() ); rotated.copyTo(frame); + pipeline_data.crop_gray = rotated; } - CharacterSegmenter charSegmenter(frame, regionizer.thresholdsInverted(), &config); + CharacterSegmenter charSegmenter(&pipeline_data); //ocr.cleanCharRegions(charSegmenter.thresholds, charSegmenter.characters); diff --git a/src/openalpr/alpr_impl.cpp b/src/openalpr/alpr_impl.cpp index 42d297b..ff63d1a 100644 --- a/src/openalpr/alpr_impl.cpp +++ b/src/openalpr/alpr_impl.cpp @@ -213,8 +213,8 @@ void plateAnalysisThread(void* arg) for (int pointidx = 0; pointidx < 4; pointidx++) { - plateResult.plate_points[pointidx].x = (int) lp.plateCorners[pointidx].x; - plateResult.plate_points[pointidx].y = (int) lp.plateCorners[pointidx].y; + plateResult.plate_points[pointidx].x = (int) pipeline_data.plate_corners[pointidx].x; + plateResult.plate_points[pointidx].y = (int) pipeline_data.plate_corners[pointidx].y; } if (dispatcher->detectRegion) diff --git a/src/openalpr/characteranalysis.cpp b/src/openalpr/characteranalysis.cpp index c146504..26d6403 100644 --- a/src/openalpr/characteranalysis.cpp +++ b/src/openalpr/characteranalysis.cpp @@ -22,22 +22,16 @@ using namespace cv; using namespace std; -CharacterAnalysis::CharacterAnalysis(Mat img, Config* config) +CharacterAnalysis::CharacterAnalysis(PipelineData* pipeline_data) { - this->config = config; + this->pipeline_data = pipeline_data; + this->config = pipeline_data->config; this->hasPlateMask = false; if (this->config->debugCharAnalysis) cout << "Starting CharacterAnalysis identification" << endl; - if (img.type() != CV_8U) - cvtColor( img, this->img_gray, CV_BGR2GRAY ); - else - { - img_gray = Mat(img.size(), img.type()); - img.copyTo(img_gray); - } } CharacterAnalysis::~CharacterAnalysis() @@ -51,21 +45,9 @@ CharacterAnalysis::~CharacterAnalysis() void CharacterAnalysis::analyze() { - thresholds = produceThresholds(img_gray, config); + thresholds = produceThresholds(pipeline_data->crop_gray, config); - /* - // Morph Close the gray image to make it easier to detect blobs - int morph_elem = 1; - int morph_size = 1; - Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) ); - for (int i = 0; i < thresholds.size(); i++) - { - //morphologyEx( mask, mask, MORPH_CLOSE, element ); - morphologyEx( thresholds[i], thresholds[i], MORPH_OPEN, element ); - //dilate( thresholds[i], thresholds[i], element ); - } - */ timespec startTime; getTime(&startTime); @@ -181,7 +163,7 @@ void CharacterAnalysis::analyze() //charsegments = this->getPossibleCharRegions(img_threshold, allContours, allHierarchy, STARTING_MIN_HEIGHT + (bestFitIndex * HEIGHT_STEP), STARTING_MAX_HEIGHT + (bestFitIndex * HEIGHT_STEP)); - this->linePolygon = getBestVotedLines(img_gray, bestContours, bestCharSegments); + this->linePolygon = getBestVotedLines(pipeline_data->crop_gray, bestContours, bestCharSegments); if (this->linePolygon.size() > 0) { diff --git a/src/openalpr/characteranalysis.h b/src/openalpr/characteranalysis.h index 588cb21..b9d66ad 100644 --- a/src/openalpr/characteranalysis.h +++ b/src/openalpr/characteranalysis.h @@ -24,13 +24,13 @@ #include "constants.h" #include "utility.h" #include "config.h" - +#include "pipeline_data.h" class CharacterAnalysis { public: - CharacterAnalysis(cv::Mat img, Config* config); + CharacterAnalysis(PipelineData* pipeline_data); virtual ~CharacterAnalysis(); bool hasPlateMask; @@ -64,10 +64,9 @@ class CharacterAnalysis cv::Mat getCharacterMask(); private: + PipelineData* pipeline_data; Config* config; - cv::Mat img_gray; - cv::Mat findOuterBoxMask( ); bool isPlateInverted(); diff --git a/src/openalpr/characterregion.cpp b/src/openalpr/characterregion.cpp index 6fc4af6..b6e2953 100644 --- a/src/openalpr/characterregion.cpp +++ b/src/openalpr/characterregion.cpp @@ -22,9 +22,9 @@ using namespace cv; using namespace std; -CharacterRegion::CharacterRegion(Mat img, Config* config) +CharacterRegion::CharacterRegion(PipelineData* pipeline_data) { - this->config = config; + this->config = pipeline_data->config; this->debug = config->debugCharRegions; this->confidence = 0; @@ -35,8 +35,10 @@ CharacterRegion::CharacterRegion(Mat img, Config* config) timespec startTime; getTime(&startTime); - charAnalysis = new CharacterAnalysis(img, config); + charAnalysis = new CharacterAnalysis(pipeline_data); charAnalysis->analyze(); + pipeline_data->plate_inverted = charAnalysis->thresholdsInverted; + pipeline_data->plate_mask = charAnalysis->plateMask; if (this->debug && charAnalysis->linePolygon.size() > 0) { @@ -100,10 +102,6 @@ CharacterRegion::~CharacterRegion() delete(charAnalysis); } -Mat CharacterRegion::getPlateMask() -{ - return charAnalysis->plateMask; -} LineSegment CharacterRegion::getTopLine() { @@ -140,7 +138,3 @@ LineSegment CharacterRegion::getCharBoxRight() return charAnalysis->charBoxRight; } -bool CharacterRegion::thresholdsInverted() -{ - return charAnalysis->thresholdsInverted; -} diff --git a/src/openalpr/characterregion.h b/src/openalpr/characterregion.h index 4826bae..a4eabe4 100644 --- a/src/openalpr/characterregion.h +++ b/src/openalpr/characterregion.h @@ -25,23 +25,21 @@ #include "utility.h" #include "characteranalysis.h" #include "config.h" - +#include "pipeline_data.h" class CharacterRegion { public: - CharacterRegion(cv::Mat img, Config* config); + CharacterRegion(PipelineData* pipeline_data); virtual ~CharacterRegion(); CharacterAnalysis *charAnalysis; int confidence; - cv::Mat getPlateMask(); LineSegment getTopLine(); LineSegment getBottomLine(); - //vector getLinePolygon(); std::vector getCharArea(); LineSegment getCharBoxTop(); @@ -49,7 +47,6 @@ class CharacterRegion LineSegment getCharBoxLeft(); LineSegment getCharBoxRight(); - bool thresholdsInverted(); protected: Config* config; diff --git a/src/openalpr/charactersegmenter.cpp b/src/openalpr/charactersegmenter.cpp index 87007a1..04cf417 100644 --- a/src/openalpr/charactersegmenter.cpp +++ b/src/openalpr/charactersegmenter.cpp @@ -22,9 +22,10 @@ using namespace cv; using namespace std; -CharacterSegmenter::CharacterSegmenter(Mat img_gray, bool invertedColors, Config* config) +CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data) { - this->config = config; + this->pipeline_data = pipeline_data; + this->config = pipeline_data->config; this->confidence = 0; @@ -37,12 +38,12 @@ CharacterSegmenter::CharacterSegmenter(Mat img_gray, bool invertedColors, Config getTime(&startTime); - medianBlur(img_gray, img_gray, 3); + medianBlur(pipeline_data->crop_gray, pipeline_data->crop_gray, 3); - if (invertedColors) - bitwise_not(img_gray, img_gray); + if (pipeline_data->plate_inverted) + bitwise_not(pipeline_data->crop_gray, pipeline_data->crop_gray); - charAnalysis = new CharacterAnalysis(img_gray, config); + charAnalysis = new CharacterAnalysis(pipeline_data); charAnalysis->analyze(); if (this->config->debugCharSegmenter) diff --git a/src/openalpr/charactersegmenter.h b/src/openalpr/charactersegmenter.h index bea17b2..6b958bd 100644 --- a/src/openalpr/charactersegmenter.h +++ b/src/openalpr/charactersegmenter.h @@ -44,7 +44,7 @@ class CharacterSegmenter { public: - CharacterSegmenter(cv::Mat img, bool invertedColors, Config* config); + CharacterSegmenter(PipelineData* pipeline_data); virtual ~CharacterSegmenter(); std::vector characters; @@ -54,7 +54,8 @@ class CharacterSegmenter private: Config* config; - + PipelineData* pipeline_data; + CharacterAnalysis* charAnalysis; LineSegment top; diff --git a/src/openalpr/licenseplatecandidate.cpp b/src/openalpr/licenseplatecandidate.cpp index 15a40c6..f318727 100644 --- a/src/openalpr/licenseplatecandidate.cpp +++ b/src/openalpr/licenseplatecandidate.cpp @@ -50,14 +50,14 @@ void LicensePlateCandidate::recognize() resize(pipeline_data->crop_gray, pipeline_data->crop_gray, Size(config->templateWidthPx, config->templateHeightPx)); - CharacterRegion charRegion(pipeline_data->crop_gray, config); + CharacterRegion charRegion(pipeline_data); if (charRegion.confidence > 10) { PlateLines plateLines(config); //Mat boogedy = charRegion.getPlateMask(); - plateLines.processImage(charRegion.getPlateMask(), &charRegion, 1.10); + plateLines.processImage(pipeline_data->plate_mask, &charRegion, 1.10); plateLines.processImage(pipeline_data->crop_gray, &charRegion, 0.9); PlateCorners cornerFinder(pipeline_data->crop_gray, &plateLines, &charRegion, config); @@ -65,11 +65,11 @@ void LicensePlateCandidate::recognize() if (cornerFinder.confidence > 0) { - this->plateCorners = transformPointsToOriginalImage(this->pipeline_data->grayImg, pipeline_data->crop_gray, expandedRegion, smallPlateCorners); + pipeline_data->plate_corners = transformPointsToOriginalImage(this->pipeline_data->grayImg, pipeline_data->crop_gray, expandedRegion, smallPlateCorners); - this->deskewed = deSkewPlate(this->pipeline_data->grayImg, this->plateCorners); + pipeline_data->crop_gray = deSkewPlate(this->pipeline_data->grayImg, pipeline_data->plate_corners); - charSegmenter = new CharacterSegmenter(deskewed, charRegion.thresholdsInverted(), config); + charSegmenter = new CharacterSegmenter(pipeline_data); //this->recognizedText = ocr->recognizedText; //strcpy(this->recognizedText, ocr.recognizedText); diff --git a/src/openalpr/licenseplatecandidate.h b/src/openalpr/licenseplatecandidate.h index 1e71b62..f63375e 100644 --- a/src/openalpr/licenseplatecandidate.h +++ b/src/openalpr/licenseplatecandidate.h @@ -48,11 +48,9 @@ class LicensePlateCandidate float confidence; // 0-100 //vector points; // top-left, top-right, bottom-right, bottom-left - std::vector plateCorners; void recognize(); - cv::Mat deskewed; CharacterSegmenter* charSegmenter; private: diff --git a/src/openalpr/pipeline_data.cpp b/src/openalpr/pipeline_data.cpp index 0d8ab04..d0ccb71 100644 --- a/src/openalpr/pipeline_data.cpp +++ b/src/openalpr/pipeline_data.cpp @@ -10,6 +10,8 @@ PipelineData::PipelineData(Mat colorImage, Rect regionOfInterest, Config* config this->regionOfInterest = regionOfInterest; this->config = config; + + plate_inverted = false; } PipelineData::~PipelineData() diff --git a/src/openalpr/pipeline_data.h b/src/openalpr/pipeline_data.h index 39e6c52..b4853ab 100644 --- a/src/openalpr/pipeline_data.h +++ b/src/openalpr/pipeline_data.h @@ -20,18 +20,21 @@ class PipelineData cv::Mat grayImg; cv::Rect regionOfInterest; - cv::Mat crop_gray; cv::Mat plate_mask; + std::vector thresholds; + + std::vector plate_corners; + // Outputs + bool plate_inverted; + std::string region_code; float region_confidence; float overall_confidence; - std::vector thresholds; - // Plate Lines std::vector horizontalLines;