Added pipeline_data to character analaysis and character segmentation

This commit is contained in:
Matt Hill
2014-07-01 18:26:01 -04:00
parent b9422dc063
commit a0af4093d6
13 changed files with 49 additions and 67 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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);

View File

@@ -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:

View File

@@ -10,6 +10,8 @@ PipelineData::PipelineData(Mat colorImage, Rect regionOfInterest, Config* config
this->regionOfInterest = regionOfInterest;
this->config = config;
plate_inverted = false;
}
PipelineData::~PipelineData()

View File

@@ -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;