mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 07:06:54 +08:00
Fixed compiler warnings (signed/unsigned comparisons, unused variables)
This commit is contained in:
@@ -103,7 +103,7 @@ AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img, std::vector<cv::Rect
|
|||||||
response.plateRegions = plateDetector->detect(img, regionsOfInterest);
|
response.plateRegions = plateDetector->detect(img, regionsOfInterest);
|
||||||
|
|
||||||
// Get the number of threads specified and make sure the value is sane (cannot be greater than CPU cores or less than 1)
|
// Get the number of threads specified and make sure the value is sane (cannot be greater than CPU cores or less than 1)
|
||||||
int numThreads = config->multithreading_cores;
|
uint numThreads = config->multithreading_cores;
|
||||||
if (numThreads > tthread::thread::hardware_concurrency())
|
if (numThreads > tthread::thread::hardware_concurrency())
|
||||||
numThreads = tthread::thread::hardware_concurrency();
|
numThreads = tthread::thread::hardware_concurrency();
|
||||||
if (numThreads <= 0)
|
if (numThreads <= 0)
|
||||||
@@ -116,7 +116,7 @@ AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img, std::vector<cv::Rect
|
|||||||
|
|
||||||
// Spawn n threads to process all of the candidate regions and recognize
|
// Spawn n threads to process all of the candidate regions and recognize
|
||||||
list<tthread::thread*> threads;
|
list<tthread::thread*> threads;
|
||||||
for (int i = 0; i < numThreads; i++)
|
for (uint i = 0; i < numThreads; i++)
|
||||||
{
|
{
|
||||||
tthread::thread * t = new tthread::thread(plateAnalysisThread, (void *) &dispatcher);
|
tthread::thread * t = new tthread::thread(plateAnalysisThread, (void *) &dispatcher);
|
||||||
threads.push_back(t);
|
threads.push_back(t);
|
||||||
@@ -139,12 +139,12 @@ AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img, std::vector<cv::Rect
|
|||||||
|
|
||||||
if (config->debugGeneral && config->debugShowImages)
|
if (config->debugGeneral && config->debugShowImages)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < response.plateRegions.size(); i++)
|
for (uint i = 0; i < response.plateRegions.size(); i++)
|
||||||
{
|
{
|
||||||
rectangle(img, response.plateRegions[i].rect, Scalar(0, 0, 255), 2);
|
rectangle(img, response.plateRegions[i].rect, Scalar(0, 0, 255), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < dispatcher.getRecognitionResults().size(); i++)
|
for (uint i = 0; i < dispatcher.getRecognitionResults().size(); i++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < 4; z++)
|
for (int z = 0; z < 4; z++)
|
||||||
{
|
{
|
||||||
@@ -228,7 +228,7 @@ void plateAnalysisThread(void* arg)
|
|||||||
{
|
{
|
||||||
// Not a valid plate
|
// Not a valid plate
|
||||||
// Check if this plate has any children, if so, send them back up to the dispatcher for processing
|
// Check if this plate has any children, if so, send them back up to the dispatcher for processing
|
||||||
for (int childidx = 0; childidx < plateRegion.children.size(); childidx++)
|
for (uint childidx = 0; childidx < plateRegion.children.size(); childidx++)
|
||||||
{
|
{
|
||||||
dispatcher->appendPlate(plateRegion.children[childidx]);
|
dispatcher->appendPlate(plateRegion.children[childidx]);
|
||||||
}
|
}
|
||||||
@@ -265,7 +265,7 @@ void plateAnalysisThread(void* arg)
|
|||||||
|
|
||||||
int bestPlateIndex = 0;
|
int bestPlateIndex = 0;
|
||||||
|
|
||||||
for (int pp = 0; pp < ppResults.size(); pp++)
|
for (uint pp = 0; pp < ppResults.size(); pp++)
|
||||||
{
|
{
|
||||||
if (pp >= dispatcher->topN)
|
if (pp >= dispatcher->topN)
|
||||||
break;
|
break;
|
||||||
@@ -321,7 +321,7 @@ void plateAnalysisThread(void* arg)
|
|||||||
std::vector<cv::Rect> AlprImpl::convertRects(std::vector<AlprRegionOfInterest> regionsOfInterest)
|
std::vector<cv::Rect> AlprImpl::convertRects(std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||||
{
|
{
|
||||||
std::vector<cv::Rect> rectRegions;
|
std::vector<cv::Rect> rectRegions;
|
||||||
for (int i = 0; i < regionsOfInterest.size(); i++)
|
for (uint i = 0; i < regionsOfInterest.size(); i++)
|
||||||
{
|
{
|
||||||
rectRegions.push_back(cv::Rect(regionsOfInterest[i].x, regionsOfInterest[i].y, regionsOfInterest[i].width, regionsOfInterest[i].height));
|
rectRegions.push_back(cv::Rect(regionsOfInterest[i].x, regionsOfInterest[i].y, regionsOfInterest[i].width, regionsOfInterest[i].height));
|
||||||
}
|
}
|
||||||
@@ -341,7 +341,7 @@ string AlprImpl::toJson(const vector< AlprResult > results, double processing_ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
cJSON_AddItemToObject(root, "results", jsonResults=cJSON_CreateArray());
|
cJSON_AddItemToObject(root, "results", jsonResults=cJSON_CreateArray());
|
||||||
for (int i = 0; i < results.size(); i++)
|
for (uint i = 0; i < results.size(); i++)
|
||||||
{
|
{
|
||||||
cJSON *resultObj = createJsonObj( &results[i] );
|
cJSON *resultObj = createJsonObj( &results[i] );
|
||||||
cJSON_AddItemToArray(jsonResults, resultObj);
|
cJSON_AddItemToArray(jsonResults, resultObj);
|
||||||
@@ -389,7 +389,7 @@ cJSON* AlprImpl::createJsonObj(const AlprResult* result)
|
|||||||
|
|
||||||
|
|
||||||
cJSON_AddItemToObject(root, "candidates", candidates=cJSON_CreateArray());
|
cJSON_AddItemToObject(root, "candidates", candidates=cJSON_CreateArray());
|
||||||
for (int i = 0; i < result->topNPlates.size(); i++)
|
for (uint i = 0; i < result->topNPlates.size(); i++)
|
||||||
{
|
{
|
||||||
cJSON *candidate_object;
|
cJSON *candidate_object;
|
||||||
candidate_object = cJSON_CreateObject();
|
candidate_object = cJSON_CreateObject();
|
||||||
|
@@ -167,7 +167,7 @@ class PlateDispatcher
|
|||||||
OCR* ocr;
|
OCR* ocr;
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
int topN;
|
uint topN;
|
||||||
bool detectRegion;
|
bool detectRegion;
|
||||||
std::string defaultRegion;
|
std::string defaultRegion;
|
||||||
|
|
||||||
|
@@ -122,7 +122,6 @@ void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
|
|||||||
int x_lastth = im.cols-wxh-1;
|
int x_lastth = im.cols-wxh-1;
|
||||||
int y_lastth = im.rows-wyh-1;
|
int y_lastth = im.rows-wyh-1;
|
||||||
int y_firstth= wyh;
|
int y_firstth= wyh;
|
||||||
int mx, my;
|
|
||||||
|
|
||||||
// Create local statistics and store them in a float matrices
|
// Create local statistics and store them in a float matrices
|
||||||
Mat map_m = Mat::zeros (im.rows, im.cols, CV_32F);
|
Mat map_m = Mat::zeros (im.rows, im.cols, CV_32F);
|
||||||
|
@@ -49,7 +49,7 @@ void CharacterAnalysis::analyze()
|
|||||||
timespec startTime;
|
timespec startTime;
|
||||||
getTime(&startTime);
|
getTime(&startTime);
|
||||||
|
|
||||||
for (int i = 0; i < pipeline_data->thresholds.size(); i++)
|
for (uint i = 0; i < pipeline_data->thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
vector<vector<Point> > contours;
|
vector<vector<Point> > contours;
|
||||||
vector<Vec4i> hierarchy;
|
vector<Vec4i> hierarchy;
|
||||||
@@ -76,7 +76,7 @@ void CharacterAnalysis::analyze()
|
|||||||
|
|
||||||
getTime(&startTime);
|
getTime(&startTime);
|
||||||
|
|
||||||
for (int i = 0; i < pipeline_data->thresholds.size(); i++)
|
for (uint i = 0; i < pipeline_data->thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
vector<bool> goodIndices = this->filter(pipeline_data->thresholds[i], allContours[i], allHierarchy[i]);
|
vector<bool> goodIndices = this->filter(pipeline_data->thresholds[i], allContours[i], allHierarchy[i]);
|
||||||
charSegments.push_back(goodIndices);
|
charSegments.push_back(goodIndices);
|
||||||
@@ -97,7 +97,7 @@ void CharacterAnalysis::analyze()
|
|||||||
if (hasPlateMask)
|
if (hasPlateMask)
|
||||||
{
|
{
|
||||||
// Filter out bad contours now that we have an outer box mask...
|
// Filter out bad contours now that we have an outer box mask...
|
||||||
for (int i = 0; i < pipeline_data->thresholds.size(); i++)
|
for (uint i = 0; i < pipeline_data->thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
charSegments[i] = filterByOuterMask(allContours[i], allHierarchy[i], charSegments[i]);
|
charSegments[i] = filterByOuterMask(allContours[i], allHierarchy[i], charSegments[i]);
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ void CharacterAnalysis::analyze()
|
|||||||
|
|
||||||
int bestFitScore = -1;
|
int bestFitScore = -1;
|
||||||
int bestFitIndex = -1;
|
int bestFitIndex = -1;
|
||||||
for (int i = 0; i < pipeline_data->thresholds.size(); i++)
|
for (uint i = 0; i < pipeline_data->thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
//vector<bool> goodIndices = this->filter(thresholds[i], allContours[i], allHierarchy[i]);
|
//vector<bool> goodIndices = this->filter(thresholds[i], allContours[i], allHierarchy[i]);
|
||||||
//charSegments.push_back(goodIndices);
|
//charSegments.push_back(goodIndices);
|
||||||
@@ -139,7 +139,7 @@ void CharacterAnalysis::analyze()
|
|||||||
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
||||||
|
|
||||||
vector<vector<Point> > allowedContours;
|
vector<vector<Point> > allowedContours;
|
||||||
for (int i = 0; i < bestContours.size(); i++)
|
for (uint i = 0; i < bestContours.size(); i++)
|
||||||
{
|
{
|
||||||
if (bestCharSegments[i])
|
if (bestCharSegments[i])
|
||||||
allowedContours.push_back(bestContours[i]);
|
allowedContours.push_back(bestContours[i]);
|
||||||
@@ -186,7 +186,7 @@ void CharacterAnalysis::analyze()
|
|||||||
int CharacterAnalysis::getGoodIndicesCount(vector<bool> goodIndices)
|
int CharacterAnalysis::getGoodIndicesCount(vector<bool> goodIndices)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < goodIndices.size(); i++)
|
for (uint i = 0; i < goodIndices.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i])
|
if (goodIndices[i])
|
||||||
count++;
|
count++;
|
||||||
@@ -207,14 +207,14 @@ Mat CharacterAnalysis::findOuterBoxMask()
|
|||||||
if (this->config->debugCharAnalysis)
|
if (this->config->debugCharAnalysis)
|
||||||
cout << "CharacterAnalysis::findOuterBoxMask" << endl;
|
cout << "CharacterAnalysis::findOuterBoxMask" << endl;
|
||||||
|
|
||||||
for (int imgIndex = 0; imgIndex < allContours.size(); imgIndex++)
|
for (uint imgIndex = 0; imgIndex < allContours.size(); imgIndex++)
|
||||||
{
|
{
|
||||||
//vector<bool> charContours = filter(thresholds[imgIndex], allContours[imgIndex], allHierarchy[imgIndex]);
|
//vector<bool> charContours = filter(thresholds[imgIndex], allContours[imgIndex], allHierarchy[imgIndex]);
|
||||||
|
|
||||||
int charsRecognized = 0;
|
int charsRecognized = 0;
|
||||||
int parentId = -1;
|
int parentId = -1;
|
||||||
bool hasParent = false;
|
bool hasParent = false;
|
||||||
for (int i = 0; i < charSegments[imgIndex].size(); i++)
|
for (uint i = 0; i < charSegments[imgIndex].size(); i++)
|
||||||
{
|
{
|
||||||
if (charSegments[imgIndex][i]) charsRecognized++;
|
if (charSegments[imgIndex][i]) charsRecognized++;
|
||||||
if (charSegments[imgIndex][i] && allHierarchy[imgIndex][i][3] != -1)
|
if (charSegments[imgIndex][i] && allHierarchy[imgIndex][i][3] != -1)
|
||||||
@@ -253,9 +253,9 @@ Mat CharacterAnalysis::findOuterBoxMask()
|
|||||||
int longestChildIndex = -1;
|
int longestChildIndex = -1;
|
||||||
double longestChildLength = 0;
|
double longestChildLength = 0;
|
||||||
// Find the child with the longest permiter/arc length ( just for kicks)
|
// Find the child with the longest permiter/arc length ( just for kicks)
|
||||||
for (int i = 0; i < allContours[winningIndex].size(); i++)
|
for (uint i = 0; i < allContours[winningIndex].size(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < allContours[winningIndex].size(); j++)
|
for (uint j = 0; j < allContours[winningIndex].size(); j++)
|
||||||
{
|
{
|
||||||
if (allHierarchy[winningIndex][j][3] == winningParentId)
|
if (allHierarchy[winningIndex][j][3] == winningParentId)
|
||||||
{
|
{
|
||||||
@@ -301,7 +301,7 @@ Mat CharacterAnalysis::findOuterBoxMask()
|
|||||||
findContours(mask, contoursSecondRound, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
|
findContours(mask, contoursSecondRound, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
|
||||||
int biggestContourIndex = -1;
|
int biggestContourIndex = -1;
|
||||||
double largestArea = 0;
|
double largestArea = 0;
|
||||||
for (int c = 0; c < contoursSecondRound.size(); c++)
|
for (uint c = 0; c < contoursSecondRound.size(); c++)
|
||||||
{
|
{
|
||||||
double area = contourArea(contoursSecondRound[c]);
|
double area = contourArea(contoursSecondRound[c]);
|
||||||
if (area > largestArea)
|
if (area > largestArea)
|
||||||
@@ -360,7 +360,7 @@ Mat CharacterAnalysis::getCharacterMask()
|
|||||||
{
|
{
|
||||||
Mat charMask = Mat::zeros(bestThreshold.size(), CV_8U);
|
Mat charMask = Mat::zeros(bestThreshold.size(), CV_8U);
|
||||||
|
|
||||||
for (int i = 0; i < bestContours.size(); i++)
|
for (uint i = 0; i < bestContours.size(); i++)
|
||||||
{
|
{
|
||||||
if (bestCharSegments[i] == false)
|
if (bestCharSegments[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -389,7 +389,7 @@ vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point>
|
|||||||
|
|
||||||
vector<Rect> charRegions;
|
vector<Rect> charRegions;
|
||||||
|
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i])
|
if (goodIndices[i])
|
||||||
charRegions.push_back(boundingRect(contours[i]));
|
charRegions.push_back(boundingRect(contours[i]));
|
||||||
@@ -405,9 +405,9 @@ vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point>
|
|||||||
vector<LineSegment> topLines;
|
vector<LineSegment> topLines;
|
||||||
vector<LineSegment> bottomLines;
|
vector<LineSegment> bottomLines;
|
||||||
// Iterate through each possible char and find all possible lines for the top and bottom of each char segment
|
// Iterate through each possible char and find all possible lines for the top and bottom of each char segment
|
||||||
for (int i = 0; i < charRegions.size() - 1; i++)
|
for (uint i = 0; i < charRegions.size() - 1; i++)
|
||||||
{
|
{
|
||||||
for (int k = i+1; k < charRegions.size(); k++)
|
for (uint k = i+1; k < charRegions.size(); k++)
|
||||||
{
|
{
|
||||||
//Mat tempImg;
|
//Mat tempImg;
|
||||||
//result.copyTo(tempImg);
|
//result.copyTo(tempImg);
|
||||||
@@ -471,13 +471,13 @@ vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point>
|
|||||||
int bestScoreDistance = -1; // Line segment distance is used as a tie breaker
|
int bestScoreDistance = -1; // Line segment distance is used as a tie breaker
|
||||||
|
|
||||||
// Now, among all possible lines, find the one that is the best fit
|
// Now, among all possible lines, find the one that is the best fit
|
||||||
for (int i = 0; i < topLines.size(); i++)
|
for (uint i = 0; i < topLines.size(); i++)
|
||||||
{
|
{
|
||||||
float SCORING_MIN_THRESHOLD = 0.97;
|
float SCORING_MIN_THRESHOLD = 0.97;
|
||||||
float SCORING_MAX_THRESHOLD = 1.03;
|
float SCORING_MAX_THRESHOLD = 1.03;
|
||||||
|
|
||||||
int curScore = 0;
|
int curScore = 0;
|
||||||
for (int charidx = 0; charidx < charRegions.size(); charidx++)
|
for (uint charidx = 0; charidx < charRegions.size(); charidx++)
|
||||||
{
|
{
|
||||||
float topYPos = topLines[i].getPointAt(charRegions[charidx].x);
|
float topYPos = topLines[i].getPointAt(charRegions[charidx].x);
|
||||||
float botYPos = bottomLines[i].getPointAt(charRegions[charidx].x);
|
float botYPos = bottomLines[i].getPointAt(charRegions[charidx].x);
|
||||||
@@ -550,7 +550,7 @@ vector<bool> CharacterAnalysis::filter(Mat img, vector<vector<Point> > contours,
|
|||||||
int goodIndicesCount;
|
int goodIndicesCount;
|
||||||
|
|
||||||
vector<bool> goodIndices(contours.size());
|
vector<bool> goodIndices(contours.size());
|
||||||
for (int z = 0; z < goodIndices.size(); z++) goodIndices[z] = true;
|
for (uint z = 0; z < goodIndices.size(); z++) goodIndices[z] = true;
|
||||||
|
|
||||||
goodIndices = this->filterByBoxSize(contours, goodIndices, STARTING_MIN_HEIGHT + (i * HEIGHT_STEP), STARTING_MAX_HEIGHT + (i * HEIGHT_STEP));
|
goodIndices = this->filterByBoxSize(contours, goodIndices, STARTING_MIN_HEIGHT + (i * HEIGHT_STEP), STARTING_MAX_HEIGHT + (i * HEIGHT_STEP));
|
||||||
|
|
||||||
@@ -585,10 +585,10 @@ vector<bool> CharacterAnalysis::filterByBoxSize(vector< vector< Point> > contour
|
|||||||
float aspecttolerance=0.25;
|
float aspecttolerance=0.25;
|
||||||
|
|
||||||
vector<bool> includedIndices(contours.size());
|
vector<bool> includedIndices(contours.size());
|
||||||
for (int j = 0; j < contours.size(); j++)
|
for (uint j = 0; j < contours.size(); j++)
|
||||||
includedIndices.push_back(false);
|
includedIndices.push_back(false);
|
||||||
|
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i] == false)
|
if (goodIndices[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -614,10 +614,10 @@ vector<bool> CharacterAnalysis::filterByBoxSize(vector< vector< Point> > contour
|
|||||||
vector< bool > CharacterAnalysis::filterContourHoles(vector< vector< Point > > contours, vector< Vec4i > hierarchy, vector< bool > goodIndices)
|
vector< bool > CharacterAnalysis::filterContourHoles(vector< vector< Point > > contours, vector< Vec4i > hierarchy, vector< bool > goodIndices)
|
||||||
{
|
{
|
||||||
vector<bool> includedIndices(contours.size());
|
vector<bool> includedIndices(contours.size());
|
||||||
for (int j = 0; j < contours.size(); j++)
|
for (uint j = 0; j < contours.size(); j++)
|
||||||
includedIndices.push_back(false);
|
includedIndices.push_back(false);
|
||||||
|
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i] == false)
|
if (goodIndices[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -646,13 +646,13 @@ vector< bool > CharacterAnalysis::filterContourHoles(vector< vector< Point > > c
|
|||||||
vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices)
|
vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices)
|
||||||
{
|
{
|
||||||
vector<bool> includedIndices(contours.size());
|
vector<bool> includedIndices(contours.size());
|
||||||
for (int j = 0; j < contours.size(); j++)
|
for (uint j = 0; j < contours.size(); j++)
|
||||||
includedIndices[j] = false;
|
includedIndices[j] = false;
|
||||||
|
|
||||||
vector<int> parentIDs;
|
vector<int> parentIDs;
|
||||||
vector<int> votes;
|
vector<int> votes;
|
||||||
|
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i] == false)
|
if (goodIndices[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -660,7 +660,7 @@ vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> >
|
|||||||
int voteIndex = -1;
|
int voteIndex = -1;
|
||||||
int parentID = hierarchy[i][3];
|
int parentID = hierarchy[i][3];
|
||||||
// check if parentID is already in the lsit
|
// check if parentID is already in the lsit
|
||||||
for (int j = 0; j < parentIDs.size(); j++)
|
for (uint j = 0; j < parentIDs.size(); j++)
|
||||||
{
|
{
|
||||||
if (parentIDs[j] == parentID)
|
if (parentIDs[j] == parentID)
|
||||||
{
|
{
|
||||||
@@ -683,7 +683,7 @@ vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> >
|
|||||||
int totalVotes = 0;
|
int totalVotes = 0;
|
||||||
int winningParentId = 0;
|
int winningParentId = 0;
|
||||||
int highestVotes = 0;
|
int highestVotes = 0;
|
||||||
for (int i = 0; i < parentIDs.size(); i++)
|
for (uint i = 0; i < parentIDs.size(); i++)
|
||||||
{
|
{
|
||||||
if (votes[i] > highestVotes)
|
if (votes[i] > highestVotes)
|
||||||
{
|
{
|
||||||
@@ -694,7 +694,7 @@ vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> >
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now filter out all the contours with a different parent ID (assuming the totalVotes > 2)
|
// Now filter out all the contours with a different parent ID (assuming the totalVotes > 2)
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i] == false)
|
if (goodIndices[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -718,7 +718,7 @@ vector<bool> CharacterAnalysis::filterBetweenLines(Mat img, vector<vector<Point>
|
|||||||
static float MAX_DISTANCE_PERCENT_FROM_LINES = 0.15;
|
static float MAX_DISTANCE_PERCENT_FROM_LINES = 0.15;
|
||||||
|
|
||||||
vector<bool> includedIndices(contours.size());
|
vector<bool> includedIndices(contours.size());
|
||||||
for (int j = 0; j < contours.size(); j++)
|
for (uint j = 0; j < contours.size(); j++)
|
||||||
includedIndices[j] = false;
|
includedIndices[j] = false;
|
||||||
|
|
||||||
if (outerPolygon.size() == 0)
|
if (outerPolygon.size() == 0)
|
||||||
@@ -741,7 +741,7 @@ vector<bool> CharacterAnalysis::filterBetweenLines(Mat img, vector<vector<Point>
|
|||||||
fillConvexPoly(outerMask, outerPolygon.data(), outerPolygon.size(), Scalar(255,255,255));
|
fillConvexPoly(outerMask, outerPolygon.data(), outerPolygon.size(), Scalar(255,255,255));
|
||||||
|
|
||||||
// For each contour, determine if enough of it is between the lines to qualify
|
// For each contour, determine if enough of it is between the lines to qualify
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i] == false)
|
if (goodIndices[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -767,7 +767,7 @@ vector<bool> CharacterAnalysis::filterBetweenLines(Mat img, vector<vector<Point>
|
|||||||
double totalArea = contourArea(contours[i]);
|
double totalArea = contourArea(contours[i]);
|
||||||
double areaBetweenLines = 0;
|
double areaBetweenLines = 0;
|
||||||
|
|
||||||
for (int tempContourIdx = 0; tempContourIdx < tempContours.size(); tempContourIdx++)
|
for (uint tempContourIdx = 0; tempContourIdx < tempContours.size(); tempContourIdx++)
|
||||||
{
|
{
|
||||||
areaBetweenLines += contourArea(tempContours[tempContourIdx]);
|
areaBetweenLines += contourArea(tempContours[tempContourIdx]);
|
||||||
}
|
}
|
||||||
@@ -789,7 +789,7 @@ vector<bool> CharacterAnalysis::filterBetweenLines(Mat img, vector<vector<Point>
|
|||||||
int highPointValue = 999999999;
|
int highPointValue = 999999999;
|
||||||
int lowPointIndex = 0;
|
int lowPointIndex = 0;
|
||||||
int lowPointValue = 0;
|
int lowPointValue = 0;
|
||||||
for (int cidx = 0; cidx < contours[i].size(); cidx++)
|
for (uint cidx = 0; cidx < contours[i].size(); cidx++)
|
||||||
{
|
{
|
||||||
if (contours[i][cidx].y < highPointValue)
|
if (contours[i][cidx].y < highPointValue)
|
||||||
{
|
{
|
||||||
@@ -831,7 +831,7 @@ std::vector< bool > CharacterAnalysis::filterByOuterMask(vector< vector< Point >
|
|||||||
return goodIndices;
|
return goodIndices;
|
||||||
|
|
||||||
vector<bool> passingIndices;
|
vector<bool> passingIndices;
|
||||||
for (int i = 0; i < goodIndices.size(); i++)
|
for (uint i = 0; i < goodIndices.size(); i++)
|
||||||
passingIndices.push_back(false);
|
passingIndices.push_back(false);
|
||||||
|
|
||||||
Mat tempMaskedContour = Mat::zeros(plateMask.size(), CV_8U);
|
Mat tempMaskedContour = Mat::zeros(plateMask.size(), CV_8U);
|
||||||
@@ -840,7 +840,7 @@ std::vector< bool > CharacterAnalysis::filterByOuterMask(vector< vector< Point >
|
|||||||
int charsInsideMask = 0;
|
int charsInsideMask = 0;
|
||||||
int totalChars = 0;
|
int totalChars = 0;
|
||||||
|
|
||||||
for (int i=0; i < goodIndices.size(); i++)
|
for (uint i=0; i < goodIndices.size(); i++)
|
||||||
{
|
{
|
||||||
if (goodIndices[i] == false)
|
if (goodIndices[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -921,12 +921,12 @@ vector<Point> CharacterAnalysis::getCharArea()
|
|||||||
int leftX = MAX;
|
int leftX = MAX;
|
||||||
int rightX = MIN;
|
int rightX = MIN;
|
||||||
|
|
||||||
for (int i = 0; i < bestContours.size(); i++)
|
for (uint i = 0; i < bestContours.size(); i++)
|
||||||
{
|
{
|
||||||
if (bestCharSegments[i] == false)
|
if (bestCharSegments[i] == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int z = 0; z < bestContours[i].size(); z++)
|
for (uint z = 0; z < bestContours[i].size(); z++)
|
||||||
{
|
{
|
||||||
if (bestContours[i][z].x < leftX)
|
if (bestContours[i][z].x < leftX)
|
||||||
leftX = bestContours[i][z].x;
|
leftX = bestContours[i][z].x;
|
||||||
|
@@ -43,7 +43,7 @@ CharacterRegion::CharacterRegion(PipelineData* pipeline_data)
|
|||||||
if (this->debug && charAnalysis->linePolygon.size() > 0)
|
if (this->debug && charAnalysis->linePolygon.size() > 0)
|
||||||
{
|
{
|
||||||
vector<Mat> tempDash;
|
vector<Mat> tempDash;
|
||||||
for (int z = 0; z < pipeline_data->thresholds.size(); z++)
|
for (uint z = 0; z < pipeline_data->thresholds.size(); z++)
|
||||||
{
|
{
|
||||||
Mat tmp(pipeline_data->thresholds[z].size(), pipeline_data->thresholds[z].type());
|
Mat tmp(pipeline_data->thresholds[z].size(), pipeline_data->thresholds[z].type());
|
||||||
pipeline_data->thresholds[z].copyTo(tmp);
|
pipeline_data->thresholds[z].copyTo(tmp);
|
||||||
@@ -56,7 +56,7 @@ CharacterRegion::CharacterRegion(PipelineData* pipeline_data)
|
|||||||
charAnalysis->bestThreshold.copyTo(bestVal);
|
charAnalysis->bestThreshold.copyTo(bestVal);
|
||||||
cvtColor(bestVal, bestVal, CV_GRAY2BGR);
|
cvtColor(bestVal, bestVal, CV_GRAY2BGR);
|
||||||
|
|
||||||
for (int z = 0; z < charAnalysis->bestContours.size(); z++)
|
for (uint z = 0; z < charAnalysis->bestContours.size(); z++)
|
||||||
{
|
{
|
||||||
Scalar dcolor(255,0,0);
|
Scalar dcolor(255,0,0);
|
||||||
if (charAnalysis->bestCharSegments[z])
|
if (charAnalysis->bestCharSegments[z])
|
||||||
|
@@ -119,7 +119,7 @@ void ColorFilter::findCharColors()
|
|||||||
vector<float> hMeans, sMeans, vMeans;
|
vector<float> hMeans, sMeans, vMeans;
|
||||||
vector<float> hStdDevs, sStdDevs, vStdDevs;
|
vector<float> hStdDevs, sStdDevs, vStdDevs;
|
||||||
|
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
if (hierarchy[i][3] != -1)
|
if (hierarchy[i][3] != -1)
|
||||||
continue;
|
continue;
|
||||||
@@ -372,11 +372,11 @@ int ColorFilter::getMajorityOpinion(vector<float> values, float minPercentAgreem
|
|||||||
float lowestOverallDiff = 1000000000;
|
float lowestOverallDiff = 1000000000;
|
||||||
int bestPercentAgreementIndex = -1;
|
int bestPercentAgreementIndex = -1;
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); i++)
|
for (uint i = 0; i < values.size(); i++)
|
||||||
{
|
{
|
||||||
int valuesInRange = 0;
|
int valuesInRange = 0;
|
||||||
float overallDiff = 0;
|
float overallDiff = 0;
|
||||||
for (int j = 0; j < values.size(); j++)
|
for (uint j = 0; j < values.size(); j++)
|
||||||
{
|
{
|
||||||
float diff = abs(values[i] - values[j]);
|
float diff = abs(values[i] - values[j]);
|
||||||
if (diff < maxValDifference)
|
if (diff < maxValDifference)
|
||||||
|
@@ -93,9 +93,9 @@ class Config
|
|||||||
|
|
||||||
float postProcessMinConfidence;
|
float postProcessMinConfidence;
|
||||||
float postProcessConfidenceSkipLevel;
|
float postProcessConfidenceSkipLevel;
|
||||||
int postProcessMaxSubstitutions;
|
uint postProcessMaxSubstitutions;
|
||||||
int postProcessMinCharacters;
|
uint postProcessMinCharacters;
|
||||||
int postProcessMaxCharacters;
|
uint postProcessMaxCharacters;
|
||||||
|
|
||||||
|
|
||||||
bool debugGeneral;
|
bool debugGeneral;
|
||||||
|
@@ -70,17 +70,17 @@ vector<PlateRegion> Detector::aggregateRegions(vector<Rect> regions)
|
|||||||
std::sort(regions.begin(), regions.end(), rectHasLargerArea);
|
std::sort(regions.begin(), regions.end(), rectHasLargerArea);
|
||||||
|
|
||||||
// Create new PlateRegions and attach the rectangles to each
|
// Create new PlateRegions and attach the rectangles to each
|
||||||
for (int i = 0; i < regions.size(); i++)
|
for (uint i = 0; i < regions.size(); i++)
|
||||||
{
|
{
|
||||||
PlateRegion newRegion;
|
PlateRegion newRegion;
|
||||||
newRegion.rect = regions[i];
|
newRegion.rect = regions[i];
|
||||||
orderedRegions.push_back(newRegion);
|
orderedRegions.push_back(newRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < orderedRegions.size(); i++)
|
for (uint i = 0; i < orderedRegions.size(); i++)
|
||||||
{
|
{
|
||||||
bool foundParent = false;
|
bool foundParent = false;
|
||||||
for (int k = i + 1; k < orderedRegions.size(); k++)
|
for (uint k = i + 1; k < orderedRegions.size(); k++)
|
||||||
{
|
{
|
||||||
Point center( orderedRegions[i].rect.x + (orderedRegions[i].rect.width / 2),
|
Point center( orderedRegions[i].rect.x + (orderedRegions[i].rect.width / 2),
|
||||||
orderedRegions[i].rect.y + (orderedRegions[i].rect.height / 2));
|
orderedRegions[i].rect.y + (orderedRegions[i].rect.height / 2));
|
||||||
|
@@ -103,7 +103,7 @@ vector<PlateRegion> DetectorCPU::doCascade(Mat frame, std::vector<cv::Rect> regi
|
|||||||
cout << "LBP Time: " << diffclock(startTime, endTime) << "ms." << endl;
|
cout << "LBP Time: " << diffclock(startTime, endTime) << "ms." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i = 0; i < plates.size(); i++ )
|
for( uint i = 0; i < plates.size(); i++ )
|
||||||
{
|
{
|
||||||
plates[i].x = plates[i].x / scale_factor;
|
plates[i].x = plates[i].x / scale_factor;
|
||||||
plates[i].y = plates[i].y / scale_factor;
|
plates[i].y = plates[i].y / scale_factor;
|
||||||
|
@@ -41,7 +41,7 @@ FeatureMatcher::FeatureMatcher(Config* config)
|
|||||||
|
|
||||||
FeatureMatcher::~FeatureMatcher()
|
FeatureMatcher::~FeatureMatcher()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < trainingImgKeypoints.size(); i++)
|
for (uint i = 0; i < trainingImgKeypoints.size(); i++)
|
||||||
trainingImgKeypoints[i].clear();
|
trainingImgKeypoints[i].clear();
|
||||||
trainingImgKeypoints.clear();
|
trainingImgKeypoints.clear();
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vect
|
|||||||
//cout << "starting matcher" << matchesKnn.size() << endl;
|
//cout << "starting matcher" << matchesKnn.size() << endl;
|
||||||
for (int descInd = 0; descInd < queryDescriptors.rows; descInd++)
|
for (int descInd = 0; descInd < queryDescriptors.rows; descInd++)
|
||||||
{
|
{
|
||||||
const std::vector<DMatch> & matches = matchesKnn[descInd];
|
//const std::vector<DMatch> & matches = matchesKnn[descInd];
|
||||||
//cout << "two: " << descInd << ":" << matches.size() << endl;
|
//cout << "two: " << descInd << ":" << matches.size() << endl;
|
||||||
|
|
||||||
// Check to make sure we have 2 matches. I think this is always the case, but it doesn't hurt to be sure
|
// Check to make sure we have 2 matches. I think this is always the case, but it doesn't hurt to be sure
|
||||||
@@ -107,7 +107,7 @@ void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vect
|
|||||||
{
|
{
|
||||||
bool already_exists = false;
|
bool already_exists = false;
|
||||||
// Quickly run through the matches we've already added and make sure it's not a duplicate...
|
// Quickly run through the matches we've already added and make sure it's not a duplicate...
|
||||||
for (int q = 0; q < matches12.size(); q++)
|
for (uint q = 0; q < matches12.size(); q++)
|
||||||
{
|
{
|
||||||
if (matchesKnn[descInd][0].queryIdx == matches12[q].queryIdx)
|
if (matchesKnn[descInd][0].queryIdx == matches12[q].queryIdx)
|
||||||
{
|
{
|
||||||
@@ -152,12 +152,12 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
|
|||||||
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
|
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
|
||||||
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
|
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
|
||||||
|
|
||||||
for (int i = 0; i < billMapping.size(); i++)
|
for (uint i = 0; i < billMapping.size(); i++)
|
||||||
{
|
{
|
||||||
vector<DMatch> matchesForOnePlate;
|
vector<DMatch> matchesForOnePlate;
|
||||||
for (int j = 0; j < inputMatches.size(); j++)
|
for (uint j = 0; j < inputMatches.size(); j++)
|
||||||
{
|
{
|
||||||
if (inputMatches[j].imgIdx == i)
|
if (inputMatches[j].imgIdx == (int) i)
|
||||||
matchesForOnePlate.push_back(inputMatches[j]);
|
matchesForOnePlate.push_back(inputMatches[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
|
|||||||
vector<LineSegment> hlines;
|
vector<LineSegment> hlines;
|
||||||
vector<int> matchIdx;
|
vector<int> matchIdx;
|
||||||
|
|
||||||
for (int j = 0; j < matchesForOnePlate.size(); j++)
|
for (uint j = 0; j < matchesForOnePlate.size(); j++)
|
||||||
{
|
{
|
||||||
KeyPoint tkp = trainingImgKeypoints[i][matchesForOnePlate[j].trainIdx];
|
KeyPoint tkp = trainingImgKeypoints[i][matchesForOnePlate[j].trainIdx];
|
||||||
KeyPoint qkp = queryKeypoints[matchesForOnePlate[j].queryIdx];
|
KeyPoint qkp = queryKeypoints[matchesForOnePlate[j].queryIdx];
|
||||||
@@ -184,10 +184,10 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
|
|||||||
int mostIntersectionsIndex = -1;
|
int mostIntersectionsIndex = -1;
|
||||||
mostIntersections = 0;
|
mostIntersections = 0;
|
||||||
|
|
||||||
for (int j = 0; j < vlines.size(); j++)
|
for (uint j = 0; j < vlines.size(); j++)
|
||||||
{
|
{
|
||||||
int intrCount = 0;
|
int intrCount = 0;
|
||||||
for (int q = 0; q < vlines.size(); q++)
|
for (uint q = 0; q < vlines.size(); q++)
|
||||||
{
|
{
|
||||||
Point vintr = vlines[j].intersection(vlines[q]);
|
Point vintr = vlines[j].intersection(vlines[q]);
|
||||||
Point hintr = hlines[j].intersection(hlines[q]);
|
Point hintr = hlines[j].intersection(hlines[q]);
|
||||||
@@ -221,7 +221,7 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push the non-crisscrosses back on the list
|
// Push the non-crisscrosses back on the list
|
||||||
for (int j = 0; j < matchIdx.size(); j++)
|
for (uint j = 0; j < matchIdx.size(); j++)
|
||||||
{
|
{
|
||||||
outputMatches.push_back(matchesForOnePlate[matchIdx[j]]);
|
outputMatches.push_back(matchesForOnePlate[matchIdx[j]]);
|
||||||
}
|
}
|
||||||
@@ -240,7 +240,7 @@ bool FeatureMatcher::loadRecognitionSet(string country)
|
|||||||
vector<Mat> trainImages;
|
vector<Mat> trainImages;
|
||||||
vector<string> plateFiles = getFilesInDir(country_dir.c_str());
|
vector<string> plateFiles = getFilesInDir(country_dir.c_str());
|
||||||
|
|
||||||
for (int i = 0; i < plateFiles.size(); i++)
|
for (uint i = 0; i < plateFiles.size(); i++)
|
||||||
{
|
{
|
||||||
if (hasEnding(plateFiles[i], ".jpg") == false)
|
if (hasEnding(plateFiles[i], ".jpg") == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -312,12 +312,12 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
|
|||||||
// Create and initialize the counts to 0
|
// Create and initialize the counts to 0
|
||||||
std::vector<int> bill_match_counts( billMapping.size() );
|
std::vector<int> bill_match_counts( billMapping.size() );
|
||||||
|
|
||||||
for (int i = 0; i < billMapping.size(); i++)
|
for (uint i = 0; i < billMapping.size(); i++)
|
||||||
{
|
{
|
||||||
bill_match_counts[i] = 0;
|
bill_match_counts[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < filteredMatches.size(); i++)
|
for (uint i = 0; i < filteredMatches.size(); i++)
|
||||||
{
|
{
|
||||||
bill_match_counts[filteredMatches[i].imgIdx]++;
|
bill_match_counts[filteredMatches[i].imgIdx]++;
|
||||||
//if (filteredMatches[i].imgIdx
|
//if (filteredMatches[i].imgIdx
|
||||||
@@ -326,7 +326,7 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
|
|||||||
float max_count = 0; // represented as a percent (0 to 100)
|
float max_count = 0; // represented as a percent (0 to 100)
|
||||||
int secondmost_count = 0;
|
int secondmost_count = 0;
|
||||||
int maxcount_index = -1;
|
int maxcount_index = -1;
|
||||||
for (int i = 0; i < billMapping.size(); i++)
|
for (uint i = 0; i < billMapping.size(); i++)
|
||||||
{
|
{
|
||||||
if (bill_match_counts[i] > max_count && bill_match_counts[i] >= 4)
|
if (bill_match_counts[i] > max_count && bill_match_counts[i] >= 4)
|
||||||
{
|
{
|
||||||
@@ -354,7 +354,7 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
|
|||||||
if (drawOnImage)
|
if (drawOnImage)
|
||||||
{
|
{
|
||||||
vector<KeyPoint> positiveMatches;
|
vector<KeyPoint> positiveMatches;
|
||||||
for (int i = 0; i < filteredMatches.size(); i++)
|
for (uint i = 0; i < filteredMatches.size(); i++)
|
||||||
{
|
{
|
||||||
if (filteredMatches[i].imgIdx == maxcount_index)
|
if (filteredMatches[i].imgIdx == maxcount_index)
|
||||||
{
|
{
|
||||||
@@ -379,7 +379,7 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
|
|||||||
|
|
||||||
if (this->config->debugStateId)
|
if (this->config->debugStateId)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < billMapping.size(); i++)
|
for (uint i = 0; i < billMapping.size(); i++)
|
||||||
{
|
{
|
||||||
cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
|
cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
|
||||||
}
|
}
|
||||||
|
@@ -83,7 +83,7 @@ void LicensePlateCandidate::recognize()
|
|||||||
vector<Point2f> LicensePlateCandidate::transformPointsToOriginalImage(Mat bigImage, Mat smallImage, Rect region, vector<Point> corners)
|
vector<Point2f> LicensePlateCandidate::transformPointsToOriginalImage(Mat bigImage, Mat smallImage, Rect region, vector<Point> corners)
|
||||||
{
|
{
|
||||||
vector<Point2f> cornerPoints;
|
vector<Point2f> cornerPoints;
|
||||||
for (int i = 0; i < corners.size(); i++)
|
for (uint i = 0; i < corners.size(); i++)
|
||||||
{
|
{
|
||||||
float bigX = (corners[i].x * ((float) region.width / smallImage.cols));
|
float bigX = (corners[i].x * ((float) region.width / smallImage.cols));
|
||||||
float bigY = (corners[i].y * ((float) region.height / smallImage.rows));
|
float bigY = (corners[i].y * ((float) region.height / smallImage.rows));
|
||||||
|
@@ -63,7 +63,7 @@ void OCR::performOCR(PipelineData* pipeline_data)
|
|||||||
if (pipeline_data->charRegions.size() < config->postProcessMinCharacters)
|
if (pipeline_data->charRegions.size() < config->postProcessMinCharacters)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < pipeline_data->thresholds.size(); i++)
|
for (uint i = 0; i < pipeline_data->thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
// Make it black text on white background
|
// Make it black text on white background
|
||||||
bitwise_not(pipeline_data->thresholds[i], pipeline_data->thresholds[i]);
|
bitwise_not(pipeline_data->thresholds[i], pipeline_data->thresholds[i]);
|
||||||
@@ -71,7 +71,7 @@ void OCR::performOCR(PipelineData* pipeline_data)
|
|||||||
pipeline_data->thresholds[i].size().width, pipeline_data->thresholds[i].size().height,
|
pipeline_data->thresholds[i].size().width, pipeline_data->thresholds[i].size().height,
|
||||||
pipeline_data->thresholds[i].channels(), pipeline_data->thresholds[i].step1());
|
pipeline_data->thresholds[i].channels(), pipeline_data->thresholds[i].step1());
|
||||||
|
|
||||||
for (int j = 0; j < pipeline_data->charRegions.size(); j++)
|
for (uint j = 0; j < pipeline_data->charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
Rect expandedRegion = expandRect( pipeline_data->charRegions[j], 2, 2, pipeline_data->thresholds[i].cols, pipeline_data->thresholds[i].rows) ;
|
Rect expandedRegion = expandRect( pipeline_data->charRegions[j], 2, 2, pipeline_data->thresholds[i].cols, pipeline_data->thresholds[i].rows) ;
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ PipelineData::~PipelineData()
|
|||||||
|
|
||||||
void PipelineData::clearThresholds()
|
void PipelineData::clearThresholds()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
thresholds[i].release();
|
thresholds[i].release();
|
||||||
}
|
}
|
||||||
|
@@ -84,9 +84,9 @@ void PlateLines::processImage(Mat inputImage, CharacterRegion* charRegion, float
|
|||||||
|
|
||||||
vector<PlateLine> hlines = this->getLines(edges, sensitivity, false);
|
vector<PlateLine> hlines = this->getLines(edges, sensitivity, false);
|
||||||
vector<PlateLine> vlines = this->getLines(edges, sensitivity, true);
|
vector<PlateLine> vlines = this->getLines(edges, sensitivity, true);
|
||||||
for (int i = 0; i < hlines.size(); i++)
|
for (uint i = 0; i < hlines.size(); i++)
|
||||||
this->horizontalLines.push_back(hlines[i]);
|
this->horizontalLines.push_back(hlines[i]);
|
||||||
for (int i = 0; i < vlines.size(); i++)
|
for (uint i = 0; i < vlines.size(); i++)
|
||||||
this->verticalLines.push_back(vlines[i]);
|
this->verticalLines.push_back(vlines[i]);
|
||||||
|
|
||||||
// if debug is enabled, draw the image
|
// if debug is enabled, draw the image
|
||||||
@@ -227,7 +227,7 @@ Mat PlateLines::customGrayscaleConversion(Mat src)
|
|||||||
for (int col = 0; col < img_hsv.cols; col++)
|
for (int col = 0; col < img_hsv.cols; col++)
|
||||||
{
|
{
|
||||||
int h = (int) img_hsv.at<Vec3b>(row, col)[0];
|
int h = (int) img_hsv.at<Vec3b>(row, col)[0];
|
||||||
int s = (int) img_hsv.at<Vec3b>(row, col)[1];
|
//int s = (int) img_hsv.at<Vec3b>(row, col)[1];
|
||||||
int v = (int) img_hsv.at<Vec3b>(row, col)[2];
|
int v = (int) img_hsv.at<Vec3b>(row, col)[2];
|
||||||
|
|
||||||
int pixval = pow(v, 1.05);
|
int pixval = pow(v, 1.05);
|
||||||
|
@@ -58,7 +58,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
||||||
|
|
||||||
vector<vector<Point> > allowedContours;
|
vector<vector<Point> > allowedContours;
|
||||||
for (int i = 0; i < charAnalysis->bestContours.size(); i++)
|
for (uint i = 0; i < charAnalysis->bestContours.size(); i++)
|
||||||
{
|
{
|
||||||
if (charAnalysis->bestCharSegments[i])
|
if (charAnalysis->bestCharSegments[i])
|
||||||
allowedContours.push_back(charAnalysis->bestContours[i]);
|
allowedContours.push_back(charAnalysis->bestContours[i]);
|
||||||
@@ -92,7 +92,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
vector<int> charWidths;
|
vector<int> charWidths;
|
||||||
vector<int> charHeights;
|
vector<int> charHeights;
|
||||||
|
|
||||||
for (int i = 0; i < charAnalysis->bestContours.size(); i++)
|
for (uint i = 0; i < charAnalysis->bestContours.size(); i++)
|
||||||
{
|
{
|
||||||
if (charAnalysis->bestCharSegments[i] == false)
|
if (charAnalysis->bestCharSegments[i] == false)
|
||||||
continue;
|
continue;
|
||||||
@@ -116,7 +116,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
vector<Mat> allHistograms;
|
vector<Mat> allHistograms;
|
||||||
|
|
||||||
vector<Rect> allBoxes;
|
vector<Rect> allBoxes;
|
||||||
for (int i = 0; i < charAnalysis->allContours.size(); i++)
|
for (uint i = 0; i < charAnalysis->allContours.size(); i++)
|
||||||
{
|
{
|
||||||
Mat histogramMask = Mat::zeros(pipeline_data->thresholds[i].size(), CV_8U);
|
Mat histogramMask = Mat::zeros(pipeline_data->thresholds[i].size(), CV_8U);
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
|
|
||||||
if (this->config->debugCharSegmenter)
|
if (this->config->debugCharSegmenter)
|
||||||
{
|
{
|
||||||
for (int cboxIdx = 0; cboxIdx < charBoxes.size(); cboxIdx++)
|
for (uint cboxIdx = 0; cboxIdx < charBoxes.size(); cboxIdx++)
|
||||||
{
|
{
|
||||||
rectangle(allHistograms[i], charBoxes[cboxIdx], Scalar(0, 255, 0));
|
rectangle(allHistograms[i], charBoxes[cboxIdx], Scalar(0, 255, 0));
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
displayImage(config, "Char seg histograms", histDashboard);
|
displayImage(config, "Char seg histograms", histDashboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int z = 0; z < charBoxes.size(); z++)
|
for (uint z = 0; z < charBoxes.size(); z++)
|
||||||
allBoxes.push_back(charBoxes[z]);
|
allBoxes.push_back(charBoxes[z]);
|
||||||
//drawAndWait(&histogramMask);
|
//drawAndWait(&histogramMask);
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
float medianCharWidth = avgCharWidth;
|
float medianCharWidth = avgCharWidth;
|
||||||
vector<int> widthValues;
|
vector<int> widthValues;
|
||||||
// Compute largest char width
|
// Compute largest char width
|
||||||
for (int i = 0; i < allBoxes.size(); i++)
|
for (uint i = 0; i < allBoxes.size(); i++)
|
||||||
{
|
{
|
||||||
widthValues.push_back(allBoxes[i].width);
|
widthValues.push_back(allBoxes[i].width);
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
if (this->config->debugCharSegmenter)
|
if (this->config->debugCharSegmenter)
|
||||||
{
|
{
|
||||||
// Setup the dashboard images to show the cleaning filters
|
// Setup the dashboard images to show the cleaning filters
|
||||||
for (int i = 0; i < pipeline_data->thresholds.size(); i++)
|
for (uint i = 0; i < pipeline_data->thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
Mat cleanImg = Mat::zeros(pipeline_data->thresholds[i].size(), pipeline_data->thresholds[i].type());
|
Mat cleanImg = Mat::zeros(pipeline_data->thresholds[i].size(), pipeline_data->thresholds[i].type());
|
||||||
Mat boxMask = getCharBoxMask(pipeline_data->thresholds[i], candidateBoxes);
|
Mat boxMask = getCharBoxMask(pipeline_data->thresholds[i], candidateBoxes);
|
||||||
@@ -185,7 +185,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data)
|
|||||||
bitwise_and(cleanImg, boxMask, cleanImg);
|
bitwise_and(cleanImg, boxMask, cleanImg);
|
||||||
cvtColor(cleanImg, cleanImg, CV_GRAY2BGR);
|
cvtColor(cleanImg, cleanImg, CV_GRAY2BGR);
|
||||||
|
|
||||||
for (int c = 0; c < candidateBoxes.size(); c++)
|
for (uint c = 0; c < candidateBoxes.size(); c++)
|
||||||
rectangle(cleanImg, candidateBoxes[c], Scalar(0, 255, 0), 1);
|
rectangle(cleanImg, candidateBoxes[c], Scalar(0, 255, 0), 1);
|
||||||
imgDbgCleanStages.push_back(cleanImg);
|
imgDbgCleanStages.push_back(cleanImg);
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,7 @@ vector<Rect> CharacterSegmenter::getHistogramBoxes(VerticalHistogram histogram,
|
|||||||
vector<Rect> charBoxes;
|
vector<Rect> charBoxes;
|
||||||
vector<Rect> allBoxes = get1DHits(histogram.histoImg, pxLeniency);
|
vector<Rect> allBoxes = get1DHits(histogram.histoImg, pxLeniency);
|
||||||
|
|
||||||
for (int i = 0; i < allBoxes.size(); i++)
|
for (uint i = 0; i < allBoxes.size(); i++)
|
||||||
{
|
{
|
||||||
if (allBoxes[i].width >= config->segmentationMinBoxWidthPx && allBoxes[i].width <= MAX_SEGMENT_WIDTH &&
|
if (allBoxes[i].width >= config->segmentationMinBoxWidthPx && allBoxes[i].width <= MAX_SEGMENT_WIDTH &&
|
||||||
allBoxes[i].height > MIN_HISTOGRAM_HEIGHT )
|
allBoxes[i].height > MIN_HISTOGRAM_HEIGHT )
|
||||||
@@ -311,7 +311,7 @@ vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxe
|
|||||||
{
|
{
|
||||||
columnCount = 0;
|
columnCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < charBoxes.size(); i++)
|
for (uint i = 0; i < charBoxes.size(); i++)
|
||||||
{
|
{
|
||||||
if (col >= charBoxes[i].x && col < (charBoxes[i].x + charBoxes[i].width))
|
if (col >= charBoxes[i].x && col < (charBoxes[i].x + charBoxes[i].width))
|
||||||
columnCount++;
|
columnCount++;
|
||||||
@@ -343,7 +343,7 @@ vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxe
|
|||||||
|
|
||||||
float rowScore = 0;
|
float rowScore = 0;
|
||||||
|
|
||||||
for (int boxidx = 0; boxidx < allBoxes.size(); boxidx++)
|
for (uint boxidx = 0; boxidx < allBoxes.size(); boxidx++)
|
||||||
{
|
{
|
||||||
int w = allBoxes[boxidx].width;
|
int w = allBoxes[boxidx].width;
|
||||||
if (w >= config->segmentationMinBoxWidthPx && w <= MAX_SEGMENT_WIDTH)
|
if (w >= config->segmentationMinBoxWidthPx && w <= MAX_SEGMENT_WIDTH)
|
||||||
@@ -402,7 +402,7 @@ vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxe
|
|||||||
Mat imgBestBoxes(img.size(), img.type());
|
Mat imgBestBoxes(img.size(), img.type());
|
||||||
img.copyTo(imgBestBoxes);
|
img.copyTo(imgBestBoxes);
|
||||||
cvtColor(imgBestBoxes, imgBestBoxes, CV_GRAY2BGR);
|
cvtColor(imgBestBoxes, imgBestBoxes, CV_GRAY2BGR);
|
||||||
for (int i = 0; i < bestBoxes.size(); i++)
|
for (uint i = 0; i < bestBoxes.size(); i++)
|
||||||
rectangle(imgBestBoxes, bestBoxes[i], Scalar(0, 255, 0));
|
rectangle(imgBestBoxes, bestBoxes[i], Scalar(0, 255, 0));
|
||||||
|
|
||||||
this->imgDbgGeneral.push_back(addLabel(histoImg, "All Histograms"));
|
this->imgDbgGeneral.push_back(addLabel(histoImg, "All Histograms"));
|
||||||
@@ -448,9 +448,9 @@ void CharacterSegmenter::removeSmallContours(vector<Mat> thresholds, vector<vect
|
|||||||
//const float MIN_CHAR_AREA = 0.02 * avgCharWidth * avgCharHeight; // To clear out the tiny specks
|
//const float MIN_CHAR_AREA = 0.02 * avgCharWidth * avgCharHeight; // To clear out the tiny specks
|
||||||
const float MIN_CONTOUR_HEIGHT = 0.3 * avgCharHeight;
|
const float MIN_CONTOUR_HEIGHT = 0.3 * avgCharHeight;
|
||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < allContours[i].size(); c++)
|
for (uint c = 0; c < allContours[i].size(); c++)
|
||||||
{
|
{
|
||||||
if (allContours[i][c].size() == 0)
|
if (allContours[i][c].size() == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -470,7 +470,7 @@ vector<Rect> CharacterSegmenter::combineCloseBoxes( vector<Rect> charBoxes, floa
|
|||||||
{
|
{
|
||||||
vector<Rect> newCharBoxes;
|
vector<Rect> newCharBoxes;
|
||||||
|
|
||||||
for (int i = 0; i < charBoxes.size(); i++)
|
for (uint i = 0; i < charBoxes.size(); i++)
|
||||||
{
|
{
|
||||||
if (i == charBoxes.size() - 1)
|
if (i == charBoxes.size() - 1)
|
||||||
{
|
{
|
||||||
@@ -490,7 +490,7 @@ vector<Rect> CharacterSegmenter::combineCloseBoxes( vector<Rect> charBoxes, floa
|
|||||||
newCharBoxes.push_back(bigRect);
|
newCharBoxes.push_back(bigRect);
|
||||||
if (this->config->debugCharSegmenter)
|
if (this->config->debugCharSegmenter)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < pipeline_data->thresholds.size(); z++)
|
for (uint z = 0; z < pipeline_data->thresholds.size(); z++)
|
||||||
{
|
{
|
||||||
Point center(bigRect.x + bigRect.width / 2, bigRect.y + bigRect.height / 2);
|
Point center(bigRect.x + bigRect.width / 2, bigRect.y + bigRect.height / 2);
|
||||||
RotatedRect rrect(center, Size2f(bigRect.width, bigRect.height + (bigRect.height / 2)), 0);
|
RotatedRect rrect(center, Size2f(bigRect.width, bigRect.height + (bigRect.height / 2)), 0);
|
||||||
@@ -519,7 +519,7 @@ void CharacterSegmenter::cleanCharRegions(vector<Mat> thresholds, vector<Rect> c
|
|||||||
|
|
||||||
Mat mask = getCharBoxMask(thresholds[0], charRegions);
|
Mat mask = getCharBoxMask(thresholds[0], charRegions);
|
||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
bitwise_and(thresholds[i], mask, thresholds[i]);
|
bitwise_and(thresholds[i], mask, thresholds[i]);
|
||||||
vector<vector<Point> > contours;
|
vector<vector<Point> > contours;
|
||||||
@@ -536,14 +536,14 @@ void CharacterSegmenter::cleanCharRegions(vector<Mat> thresholds, vector<Rect> c
|
|||||||
|
|
||||||
findContours(tempImg, contours, RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
|
findContours(tempImg, contours, RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
for (int j = 0; j < charRegions.size(); j++)
|
for (uint j = 0; j < charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
const float MIN_SPECKLE_HEIGHT = ((float)charRegions[j].height) * MIN_SPECKLE_HEIGHT_PERCENT;
|
const float MIN_SPECKLE_HEIGHT = ((float)charRegions[j].height) * MIN_SPECKLE_HEIGHT_PERCENT;
|
||||||
const float MIN_CONTOUR_AREA = ((float)charRegions[j].area()) * MIN_CONTOUR_AREA_PERCENT;
|
const float MIN_CONTOUR_AREA = ((float)charRegions[j].area()) * MIN_CONTOUR_AREA_PERCENT;
|
||||||
|
|
||||||
int tallestContourHeight = 0;
|
int tallestContourHeight = 0;
|
||||||
float totalArea = 0;
|
float totalArea = 0;
|
||||||
for (int c = 0; c < contours.size(); c++)
|
for (uint c = 0; c < contours.size(); c++)
|
||||||
{
|
{
|
||||||
if (contours[c].size() == 0)
|
if (contours[c].size() == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -615,7 +615,7 @@ void CharacterSegmenter::cleanCharRegions(vector<Mat> thresholds, vector<Rect> c
|
|||||||
morphologyEx(thresholds[i], thresholds[i], MORPH_CLOSE, closureElement);
|
morphologyEx(thresholds[i], thresholds[i], MORPH_CLOSE, closureElement);
|
||||||
|
|
||||||
// Lastly, draw a clipping line between each character boxes
|
// Lastly, draw a clipping line between each character boxes
|
||||||
for (int j = 0; j < charRegions.size(); j++)
|
for (uint j = 0; j < charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
line(thresholds[i], Point(charRegions[j].x - 1, charRegions[j].y), Point(charRegions[j].x - 1, charRegions[j].y + charRegions[j].height), Scalar(0, 0, 0));
|
line(thresholds[i], Point(charRegions[j].x - 1, charRegions[j].y), Point(charRegions[j].x - 1, charRegions[j].y + charRegions[j].height), Scalar(0, 0, 0));
|
||||||
line(thresholds[i], Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y), Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y + charRegions[j].height), Scalar(0, 0, 0));
|
line(thresholds[i], Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y), Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y + charRegions[j].height), Scalar(0, 0, 0));
|
||||||
@@ -629,9 +629,9 @@ void CharacterSegmenter::cleanBasedOnColor(vector<Mat> thresholds, Mat colorMask
|
|||||||
// Consider it a bad news bear. REmove the whole area.
|
// Consider it a bad news bear. REmove the whole area.
|
||||||
const float MIN_PERCENT_CHUNK_REMOVED = 0.6;
|
const float MIN_PERCENT_CHUNK_REMOVED = 0.6;
|
||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < charRegions.size(); j++)
|
for (uint j = 0; j < charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
Mat boxChar = Mat::zeros(thresholds[i].size(), CV_8U);
|
Mat boxChar = Mat::zeros(thresholds[i].size(), CV_8U);
|
||||||
rectangle(boxChar, charRegions[j], Scalar(255,255,255), CV_FILLED);
|
rectangle(boxChar, charRegions[j], Scalar(255,255,255), CV_FILLED);
|
||||||
@@ -679,12 +679,12 @@ void CharacterSegmenter::cleanMostlyFullBoxes(vector<Mat> thresholds, const vect
|
|||||||
{
|
{
|
||||||
float MAX_FILLED = 0.95 * 255;
|
float MAX_FILLED = 0.95 * 255;
|
||||||
|
|
||||||
for (int i = 0; i < charRegions.size(); i++)
|
for (uint i = 0; i < charRegions.size(); i++)
|
||||||
{
|
{
|
||||||
Mat mask = Mat::zeros(thresholds[0].size(), CV_8U);
|
Mat mask = Mat::zeros(thresholds[0].size(), CV_8U);
|
||||||
rectangle(mask, charRegions[i], Scalar(255,255,255), -1);
|
rectangle(mask, charRegions[i], Scalar(255,255,255), -1);
|
||||||
|
|
||||||
for (int j = 0; j < thresholds.size(); j++)
|
for (uint j = 0; j < thresholds.size(); j++)
|
||||||
{
|
{
|
||||||
if (mean(thresholds[j], mask)[0] > MAX_FILLED)
|
if (mean(thresholds[j], mask)[0] > MAX_FILLED)
|
||||||
{
|
{
|
||||||
@@ -713,12 +713,12 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
|
|
||||||
vector<int> boxScores(charRegions.size());
|
vector<int> boxScores(charRegions.size());
|
||||||
|
|
||||||
for (int i = 0; i < charRegions.size(); i++)
|
for (uint i = 0; i < charRegions.size(); i++)
|
||||||
boxScores[i] = 0;
|
boxScores[i] = 0;
|
||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < charRegions.size(); j++)
|
for (uint j = 0; j < charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
//float minArea = charRegions[j].area() * MIN_AREA_PERCENT;
|
//float minArea = charRegions[j].area() * MIN_AREA_PERCENT;
|
||||||
|
|
||||||
@@ -729,15 +729,13 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
vector<vector<Point> > contours;
|
vector<vector<Point> > contours;
|
||||||
findContours(tempImg, contours, RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
|
findContours(tempImg, contours, RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
float biggestContourHeight = 0;
|
|
||||||
|
|
||||||
vector<Point> allPointsInBox;
|
vector<Point> allPointsInBox;
|
||||||
for (int c = 0; c < contours.size(); c++)
|
for (uint c = 0; c < contours.size(); c++)
|
||||||
{
|
{
|
||||||
if (contours[c].size() == 0)
|
if (contours[c].size() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int z = 0; z < contours[c].size(); z++)
|
for (uint z = 0; z < contours[c].size(); z++)
|
||||||
allPointsInBox.push_back(contours[c][z]);
|
allPointsInBox.push_back(contours[c][z]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,7 +759,7 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
vector<Rect> newCharRegions;
|
vector<Rect> newCharRegions;
|
||||||
|
|
||||||
int maxBoxScore = 0;
|
int maxBoxScore = 0;
|
||||||
for (int i = 0; i < charRegions.size(); i++)
|
for (uint i = 0; i < charRegions.size(); i++)
|
||||||
{
|
{
|
||||||
if (boxScores[i] > maxBoxScore)
|
if (boxScores[i] > maxBoxScore)
|
||||||
maxBoxScore = boxScores[i];
|
maxBoxScore = boxScores[i];
|
||||||
@@ -771,7 +769,7 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
int MIN_FULL_BOXES = maxBoxScore * 0.49;
|
int MIN_FULL_BOXES = maxBoxScore * 0.49;
|
||||||
|
|
||||||
// Now check each score. If it's below the minimum, remove the charRegion
|
// Now check each score. If it's below the minimum, remove the charRegion
|
||||||
for (int i = 0; i < charRegions.size(); i++)
|
for (uint i = 0; i < charRegions.size(); i++)
|
||||||
{
|
{
|
||||||
if (boxScores[i] > MIN_FULL_BOXES)
|
if (boxScores[i] > MIN_FULL_BOXES)
|
||||||
newCharRegions.push_back(charRegions[i]);
|
newCharRegions.push_back(charRegions[i]);
|
||||||
@@ -784,7 +782,7 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
cout << " this box had a score of : " << boxScores[i];;
|
cout << " this box had a score of : " << boxScores[i];;
|
||||||
cout << " MIN_FULL_BOXES: " << MIN_FULL_BOXES << endl;;
|
cout << " MIN_FULL_BOXES: " << MIN_FULL_BOXES << endl;;
|
||||||
|
|
||||||
for (int z = 0; z < thresholds.size(); z++)
|
for (uint z = 0; z < thresholds.size(); z++)
|
||||||
{
|
{
|
||||||
rectangle(thresholds[z], charRegions[i], Scalar(0,0,0), -1);
|
rectangle(thresholds[z], charRegions[i], Scalar(0,0,0), -1);
|
||||||
|
|
||||||
@@ -834,7 +832,7 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
vector<int> leftEdges;
|
vector<int> leftEdges;
|
||||||
vector<int> rightEdges;
|
vector<int> rightEdges;
|
||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
Mat rotated;
|
Mat rotated;
|
||||||
|
|
||||||
@@ -940,7 +938,7 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
cout << "Edge Filter: Entire right region is erased" << endl;
|
cout << "Edge Filter: Entire right region is erased" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (uint i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
bitwise_and(thresholds[i], mask, thresholds[i]);
|
bitwise_and(thresholds[i], mask, thresholds[i]);
|
||||||
}
|
}
|
||||||
@@ -953,7 +951,7 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
|
|
||||||
Mat invertedMask(mask.size(), mask.type());
|
Mat invertedMask(mask.size(), mask.type());
|
||||||
bitwise_not(mask, invertedMask);
|
bitwise_not(mask, invertedMask);
|
||||||
for (int z = 0; z < imgDbgCleanStages.size(); z++)
|
for (uint z = 0; z < imgDbgCleanStages.size(); z++)
|
||||||
fillMask(imgDbgCleanStages[z], invertedMask, Scalar(0,0,255));
|
fillMask(imgDbgCleanStages[z], invertedMask, Scalar(0,0,255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1087,7 +1085,7 @@ int CharacterSegmenter::isSkinnyLineInsideBox(Mat threshold, Rect box, vector<ve
|
|||||||
Mat boxMask = Mat::zeros(threshold.size(), CV_8U);
|
Mat boxMask = Mat::zeros(threshold.size(), CV_8U);
|
||||||
rectangle(boxMask, slightlySmallerBox, Scalar(255, 255, 255), -1);
|
rectangle(boxMask, slightlySmallerBox, Scalar(255, 255, 255), -1);
|
||||||
|
|
||||||
for (int i = 0; i < contours.size(); i++)
|
for (uint i = 0; i < contours.size(); i++)
|
||||||
{
|
{
|
||||||
// Only bother with the big boxes
|
// Only bother with the big boxes
|
||||||
if (boundingRect(contours[i]).height < MIN_EDGE_CONTOUR_HEIGHT)
|
if (boundingRect(contours[i]).height < MIN_EDGE_CONTOUR_HEIGHT)
|
||||||
@@ -1103,7 +1101,7 @@ int CharacterSegmenter::isSkinnyLineInsideBox(Mat threshold, Rect box, vector<ve
|
|||||||
int tallestContourHeight = 0;
|
int tallestContourHeight = 0;
|
||||||
int tallestContourWidth = 0;
|
int tallestContourWidth = 0;
|
||||||
float tallestContourArea = 0;
|
float tallestContourArea = 0;
|
||||||
for (int s = 0; s < subContours.size(); s++)
|
for (uint s = 0; s < subContours.size(); s++)
|
||||||
{
|
{
|
||||||
Rect r = boundingRect(subContours[s]);
|
Rect r = boundingRect(subContours[s]);
|
||||||
if (r.height > tallestContourHeight)
|
if (r.height > tallestContourHeight)
|
||||||
@@ -1134,7 +1132,7 @@ int CharacterSegmenter::isSkinnyLineInsideBox(Mat threshold, Rect box, vector<ve
|
|||||||
Mat CharacterSegmenter::getCharBoxMask(Mat img_threshold, vector<Rect> charBoxes)
|
Mat CharacterSegmenter::getCharBoxMask(Mat img_threshold, vector<Rect> charBoxes)
|
||||||
{
|
{
|
||||||
Mat mask = Mat::zeros(img_threshold.size(), CV_8U);
|
Mat mask = Mat::zeros(img_threshold.size(), CV_8U);
|
||||||
for (int i = 0; i < charBoxes.size(); i++)
|
for (uint i = 0; i < charBoxes.size(); i++)
|
||||||
rectangle(mask, charBoxes[i], Scalar(255, 255, 255), -1);
|
rectangle(mask, charBoxes[i], Scalar(255, 255, 255), -1);
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
|
@@ -105,7 +105,7 @@ int VerticalHistogram::getHeightAt(int x)
|
|||||||
|
|
||||||
void VerticalHistogram::findValleys()
|
void VerticalHistogram::findValleys()
|
||||||
{
|
{
|
||||||
int MINIMUM_PEAK_HEIGHT = (int) (((float) highestPeak) * 0.75);
|
//int MINIMUM_PEAK_HEIGHT = (int) (((float) highestPeak) * 0.75);
|
||||||
|
|
||||||
int totalWidth = colHeights.size();
|
int totalWidth = colHeights.size();
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ void VerticalHistogram::findValleys()
|
|||||||
HistogramDirection prevDirection = FALLING;
|
HistogramDirection prevDirection = FALLING;
|
||||||
|
|
||||||
int relativePeakHeight = 0;
|
int relativePeakHeight = 0;
|
||||||
int valleyStart = 0;
|
//int valleyStart = 0;
|
||||||
|
|
||||||
for (int i = 0; i < totalWidth; i++)
|
for (int i = 0; i < totalWidth; i++)
|
||||||
{
|
{
|
||||||
@@ -143,7 +143,7 @@ void VerticalHistogram::findValleys()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistogramDirection VerticalHistogram::getHistogramDirection(int index)
|
HistogramDirection VerticalHistogram::getHistogramDirection(uint index)
|
||||||
{
|
{
|
||||||
int EXTRA_WIDTH_TO_AVERAGE = 2;
|
int EXTRA_WIDTH_TO_AVERAGE = 2;
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ HistogramDirection VerticalHistogram::getHistogramDirection(int index)
|
|||||||
int trailStartIndex = index - EXTRA_WIDTH_TO_AVERAGE;
|
int trailStartIndex = index - EXTRA_WIDTH_TO_AVERAGE;
|
||||||
if (trailStartIndex < 0)
|
if (trailStartIndex < 0)
|
||||||
trailStartIndex = 0;
|
trailStartIndex = 0;
|
||||||
int forwardEndIndex = index + EXTRA_WIDTH_TO_AVERAGE;
|
uint forwardEndIndex = index + EXTRA_WIDTH_TO_AVERAGE;
|
||||||
if (forwardEndIndex >= colHeights.size())
|
if (forwardEndIndex >= colHeights.size())
|
||||||
forwardEndIndex = colHeights.size() - 1;
|
forwardEndIndex = colHeights.size() - 1;
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ HistogramDirection VerticalHistogram::getHistogramDirection(int index)
|
|||||||
}
|
}
|
||||||
trailingAverage = trailingAverage / ((float) (1 + index - trailStartIndex));
|
trailingAverage = trailingAverage / ((float) (1 + index - trailStartIndex));
|
||||||
|
|
||||||
for (int i = index; i <= forwardEndIndex; i++)
|
for (uint i = index; i <= forwardEndIndex; i++)
|
||||||
{
|
{
|
||||||
forwardAverage += colHeights[i];
|
forwardAverage += colHeights[i];
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ class VerticalHistogram
|
|||||||
void analyzeImage(cv::Mat inputImage, cv::Mat mask);
|
void analyzeImage(cv::Mat inputImage, cv::Mat mask);
|
||||||
void findValleys();
|
void findValleys();
|
||||||
|
|
||||||
HistogramDirection getHistogramDirection(int index);
|
HistogramDirection getHistogramDirection(uint index);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OPENALPR_VERTICALHISTOGRAM_H
|
#endif // OPENALPR_VERTICALHISTOGRAM_H
|
||||||
|
@@ -45,13 +45,13 @@ Rect expandRect(Rect original, int expandXPixels, int expandYPixels, int maxX, i
|
|||||||
return expandedRegion;
|
return expandedRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat drawImageDashboard(vector<Mat> images, int imageType, int numColumns)
|
Mat drawImageDashboard(vector<Mat> images, int imageType, uint numColumns)
|
||||||
{
|
{
|
||||||
int numRows = ceil((float) images.size() / (float) numColumns);
|
uint numRows = ceil((float) images.size() / (float) numColumns);
|
||||||
|
|
||||||
Mat dashboard(Size(images[0].cols * numColumns, images[0].rows * numRows), imageType);
|
Mat dashboard(Size(images[0].cols * numColumns, images[0].rows * numRows), imageType);
|
||||||
|
|
||||||
for (int i = 0; i < numColumns * numRows; i++)
|
for (uint i = 0; i < numColumns * numRows; i++)
|
||||||
{
|
{
|
||||||
if (i < images.size())
|
if (i < images.size())
|
||||||
images[i].copyTo(dashboard(Rect((i%numColumns) * images[i].cols, floor((float) i/numColumns) * images[i].rows, images[i].cols, images[i].rows)));
|
images[i].copyTo(dashboard(Rect((i%numColumns) * images[i].cols, floor((float) i/numColumns) * images[i].rows, images[i].cols, images[i].rows)));
|
||||||
@@ -386,6 +386,10 @@ std::string toString(int value)
|
|||||||
ss << value;
|
ss << value;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
std::string toString(uint value)
|
||||||
|
{
|
||||||
|
return toString((int) value);
|
||||||
|
}
|
||||||
std::string toString(float value)
|
std::string toString(float value)
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
|
@@ -84,7 +84,7 @@ double median(int array[], int arraySize);
|
|||||||
|
|
||||||
std::vector<cv::Mat> produceThresholds(const cv::Mat img_gray, Config* config);
|
std::vector<cv::Mat> produceThresholds(const cv::Mat img_gray, Config* config);
|
||||||
|
|
||||||
cv::Mat drawImageDashboard(std::vector<cv::Mat> images, int imageType, int numColumns);
|
cv::Mat drawImageDashboard(std::vector<cv::Mat> images, int imageType, uint numColumns);
|
||||||
|
|
||||||
void displayImage(Config* config, std::string windowName, cv::Mat frame);
|
void displayImage(Config* config, std::string windowName, cv::Mat frame);
|
||||||
void drawAndWait(cv::Mat* frame);
|
void drawAndWait(cv::Mat* frame);
|
||||||
@@ -108,6 +108,7 @@ cv::Mat addLabel(cv::Mat input, std::string label);
|
|||||||
|
|
||||||
|
|
||||||
std::string toString(int value);
|
std::string toString(int value);
|
||||||
|
std::string toString(uint value);
|
||||||
std::string toString(float value);
|
std::string toString(float value);
|
||||||
std::string toString(double value);
|
std::string toString(double value);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user