mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 19:32:45 +08:00
Added pipeline_data to character analaysis and character segmentation
This commit is contained in:
@@ -105,13 +105,15 @@ int main( int argc, const char** argv )
|
||||
plateCoords.width = frame.cols;
|
||||
plateCoords.height = frame.rows;
|
||||
|
||||
PipelineData pipeline_data(frame, plateCoords, config);
|
||||
|
||||
char statecode[3];
|
||||
statecode[0] = files[i][0];
|
||||
statecode[1] = files[i][1];
|
||||
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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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<Point> getLinePolygon();
|
||||
std::vector<cv::Point> getCharArea();
|
||||
|
||||
LineSegment getCharBoxTop();
|
||||
@@ -49,7 +47,6 @@ class CharacterRegion
|
||||
LineSegment getCharBoxLeft();
|
||||
LineSegment getCharBoxRight();
|
||||
|
||||
bool thresholdsInverted();
|
||||
|
||||
protected:
|
||||
Config* config;
|
||||
|
@@ -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)
|
||||
|
@@ -44,7 +44,7 @@ class CharacterSegmenter
|
||||
{
|
||||
|
||||
public:
|
||||
CharacterSegmenter(cv::Mat img, bool invertedColors, Config* config);
|
||||
CharacterSegmenter(PipelineData* pipeline_data);
|
||||
virtual ~CharacterSegmenter();
|
||||
|
||||
std::vector<cv::Rect> characters;
|
||||
@@ -54,6 +54,7 @@ class CharacterSegmenter
|
||||
|
||||
private:
|
||||
Config* config;
|
||||
PipelineData* pipeline_data;
|
||||
|
||||
CharacterAnalysis* charAnalysis;
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -48,11 +48,9 @@ class LicensePlateCandidate
|
||||
|
||||
float confidence; // 0-100
|
||||
//vector<Point> points; // top-left, top-right, bottom-right, bottom-left
|
||||
std::vector<cv::Point2f> plateCorners;
|
||||
|
||||
void recognize();
|
||||
|
||||
cv::Mat deskewed;
|
||||
CharacterSegmenter* charSegmenter;
|
||||
|
||||
private:
|
||||
|
@@ -10,6 +10,8 @@ PipelineData::PipelineData(Mat colorImage, Rect regionOfInterest, Config* config
|
||||
|
||||
this->regionOfInterest = regionOfInterest;
|
||||
this->config = config;
|
||||
|
||||
plate_inverted = false;
|
||||
}
|
||||
|
||||
PipelineData::~PipelineData()
|
||||
|
@@ -20,18 +20,21 @@ class PipelineData
|
||||
cv::Mat grayImg;
|
||||
cv::Rect regionOfInterest;
|
||||
|
||||
|
||||
cv::Mat crop_gray;
|
||||
cv::Mat plate_mask;
|
||||
std::vector<cv::Mat> thresholds;
|
||||
|
||||
std::vector<cv::Point2f> plate_corners;
|
||||
|
||||
|
||||
// Outputs
|
||||
bool plate_inverted;
|
||||
|
||||
std::string region_code;
|
||||
float region_confidence;
|
||||
|
||||
float overall_confidence;
|
||||
|
||||
std::vector<cv::Mat> thresholds;
|
||||
|
||||
|
||||
// Plate Lines
|
||||
std::vector<LineSegment> horizontalLines;
|
||||
|
Reference in New Issue
Block a user