mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 17:07:39 +08:00
Detecting regions hierarchically. Starting with the biggest boxes, and then moving into their children if the bigger box was not detected.
This commit is contained in:
@@ -159,7 +159,6 @@ void plateAnalysisThread(void* arg)
|
|||||||
if (dispatcher->hasPlate() == false)
|
if (dispatcher->hasPlate() == false)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Synchronized section
|
|
||||||
if (dispatcher->config->debugGeneral)
|
if (dispatcher->config->debugGeneral)
|
||||||
cout << "Thread: " << tthread::this_thread::get_id() << " loop " << ++loop_count << endl;
|
cout << "Thread: " << tthread::this_thread::get_id() << " loop " << ++loop_count << endl;
|
||||||
|
|
||||||
@@ -168,92 +167,101 @@ void plateAnalysisThread(void* arg)
|
|||||||
|
|
||||||
Mat img = dispatcher->getImageCopy();
|
Mat img = dispatcher->getImageCopy();
|
||||||
|
|
||||||
|
timespec platestarttime;
|
||||||
|
getTime(&platestarttime);
|
||||||
|
|
||||||
|
LicensePlateCandidate lp(img, plateRegion.rect, dispatcher->config);
|
||||||
|
|
||||||
|
lp.recognize();
|
||||||
|
|
||||||
|
|
||||||
|
if (lp.confidence <= 10)
|
||||||
|
{
|
||||||
|
// Not a valid plate
|
||||||
|
// 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++)
|
||||||
|
{
|
||||||
|
dispatcher->appendPlate(plateRegion.children[childidx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AlprResult plateResult;
|
||||||
|
plateResult.region = dispatcher->defaultRegion;
|
||||||
|
plateResult.regionConfidence = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispatcher->detectRegion)
|
||||||
|
{
|
||||||
|
char statecode[4];
|
||||||
|
plateResult.regionConfidence = dispatcher->stateIdentifier->recognize(img, plateRegion.rect, statecode);
|
||||||
|
if (plateResult.regionConfidence > 0)
|
||||||
|
{
|
||||||
|
plateResult.region = statecode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parallel section
|
|
||||||
timespec platestarttime;
|
dispatcher->ocr->performOCR(lp.charSegmenter->getThresholds(), lp.charSegmenter->characters);
|
||||||
getTime(&platestarttime);
|
|
||||||
|
|
||||||
LicensePlateCandidate lp(img, plateRegion.rect, dispatcher->config);
|
dispatcher->ocr->postProcessor->analyze(plateResult.region, dispatcher->topN);
|
||||||
|
|
||||||
lp.recognize();
|
|
||||||
|
|
||||||
|
//plateResult.characters = ocr->postProcessor->bestChars;
|
||||||
|
const vector<PPResult> ppResults = dispatcher->ocr->postProcessor->getResults();
|
||||||
|
|
||||||
if (lp.confidence > 10)
|
int bestPlateIndex = 0;
|
||||||
|
|
||||||
|
for (int pp = 0; pp < ppResults.size(); pp++)
|
||||||
{
|
{
|
||||||
AlprResult plateResult;
|
if (pp >= dispatcher->topN)
|
||||||
plateResult.region = dispatcher->defaultRegion;
|
break;
|
||||||
plateResult.regionConfidence = 0;
|
|
||||||
|
|
||||||
for (int pointidx = 0; pointidx < 4; pointidx++)
|
// Set our "best plate" match to either the first entry, or the first entry with a postprocessor template match
|
||||||
|
if (bestPlateIndex == 0 && ppResults[pp].matchesTemplate)
|
||||||
|
bestPlateIndex = pp;
|
||||||
|
|
||||||
|
if (ppResults[pp].letters.size() >= dispatcher->config->postProcessMinCharacters &&
|
||||||
|
ppResults[pp].letters.size() <= dispatcher->config->postProcessMaxCharacters)
|
||||||
{
|
{
|
||||||
plateResult.plate_points[pointidx].x = (int) lp.plateCorners[pointidx].x;
|
AlprPlate aplate;
|
||||||
plateResult.plate_points[pointidx].y = (int) lp.plateCorners[pointidx].y;
|
aplate.characters = ppResults[pp].letters;
|
||||||
|
aplate.overall_confidence = ppResults[pp].totalscore;
|
||||||
|
aplate.matches_template = ppResults[pp].matchesTemplate;
|
||||||
|
plateResult.topNPlates.push_back(aplate);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (dispatcher->detectRegion)
|
plateResult.result_count = plateResult.topNPlates.size();
|
||||||
{
|
|
||||||
char statecode[4];
|
if (plateResult.topNPlates.size() > 0)
|
||||||
plateResult.regionConfidence = dispatcher->stateIdentifier->recognize(img, plateRegion.rect, statecode);
|
plateResult.bestPlate = plateResult.topNPlates[bestPlateIndex];
|
||||||
if (plateResult.regionConfidence > 0)
|
|
||||||
{
|
timespec plateEndTime;
|
||||||
plateResult.region = statecode;
|
getTime(&plateEndTime);
|
||||||
}
|
plateResult.processing_time_ms = diffclock(platestarttime, plateEndTime);
|
||||||
}
|
|
||||||
|
if (plateResult.result_count > 0)
|
||||||
|
{
|
||||||
dispatcher->ocr->performOCR(lp.charSegmenter->getThresholds(), lp.charSegmenter->characters);
|
// Synchronized section
|
||||||
|
dispatcher->addResult(plateResult);
|
||||||
dispatcher->ocr->postProcessor->analyze(plateResult.region, dispatcher->topN);
|
|
||||||
|
|
||||||
//plateResult.characters = ocr->postProcessor->bestChars;
|
|
||||||
const vector<PPResult> ppResults = dispatcher->ocr->postProcessor->getResults();
|
|
||||||
|
|
||||||
int bestPlateIndex = 0;
|
|
||||||
|
|
||||||
for (int pp = 0; pp < ppResults.size(); pp++)
|
|
||||||
{
|
|
||||||
if (pp >= dispatcher->topN)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Set our "best plate" match to either the first entry, or the first entry with a postprocessor template match
|
|
||||||
if (bestPlateIndex == 0 && ppResults[pp].matchesTemplate)
|
|
||||||
bestPlateIndex = pp;
|
|
||||||
|
|
||||||
if (ppResults[pp].letters.size() >= dispatcher->config->postProcessMinCharacters &&
|
|
||||||
ppResults[pp].letters.size() <= dispatcher->config->postProcessMaxCharacters)
|
|
||||||
{
|
|
||||||
AlprPlate aplate;
|
|
||||||
aplate.characters = ppResults[pp].letters;
|
|
||||||
aplate.overall_confidence = ppResults[pp].totalscore;
|
|
||||||
aplate.matches_template = ppResults[pp].matchesTemplate;
|
|
||||||
plateResult.topNPlates.push_back(aplate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plateResult.result_count = plateResult.topNPlates.size();
|
|
||||||
|
|
||||||
if (plateResult.topNPlates.size() > 0)
|
|
||||||
plateResult.bestPlate = plateResult.topNPlates[bestPlateIndex];
|
|
||||||
|
|
||||||
timespec plateEndTime;
|
|
||||||
getTime(&plateEndTime);
|
|
||||||
plateResult.processing_time_ms = diffclock(platestarttime, plateEndTime);
|
|
||||||
|
|
||||||
if (plateResult.result_count > 0)
|
|
||||||
{
|
|
||||||
// Synchronized section
|
|
||||||
dispatcher->addResult(plateResult);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dispatcher->config->debugTiming)
|
}
|
||||||
{
|
|
||||||
timespec plateEndTime;
|
|
||||||
getTime(&plateEndTime);
|
|
||||||
cout << "Thread: " << tthread::this_thread::get_id() << " Finished loop " << loop_count << " in " << diffclock(platestarttime, plateEndTime) << "ms." << endl;
|
if (dispatcher->config->debugTiming)
|
||||||
}
|
{
|
||||||
|
timespec plateEndTime;
|
||||||
|
getTime(&plateEndTime);
|
||||||
|
cout << "Thread: " << tthread::this_thread::get_id() << " Finished loop " << loop_count << " in " << diffclock(platestarttime, plateEndTime) << "ms." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -123,6 +123,13 @@ class PlateDispatcher
|
|||||||
return plateRegion;
|
return plateRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void appendPlate(PlateRegion plate)
|
||||||
|
{
|
||||||
|
tthread::lock_guard<tthread::mutex> guard(mMutex);
|
||||||
|
|
||||||
|
plateRegions.push_back(plate);
|
||||||
|
}
|
||||||
|
|
||||||
void addResult(AlprResult recognitionResult)
|
void addResult(AlprResult recognitionResult)
|
||||||
{
|
{
|
||||||
tthread::lock_guard<tthread::mutex> guard(mMutex);
|
tthread::lock_guard<tthread::mutex> guard(mMutex);
|
||||||
|
Reference in New Issue
Block a user