mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 07:16:56 +08:00
Revert "Using multiple instances of OCR and state recognizer for multiple threads"
This reverts commit 29cb8fab21
.
This commit is contained in:
@@ -26,17 +26,8 @@ AlprImpl::AlprImpl(const std::string country, const std::string runtimeDir)
|
|||||||
{
|
{
|
||||||
config = new Config(country, runtimeDir);
|
config = new Config(country, runtimeDir);
|
||||||
plateDetector = new RegionDetector(config);
|
plateDetector = new RegionDetector(config);
|
||||||
|
stateIdentifier = new StateIdentifier(config);
|
||||||
int numThreads = getNumThreads();
|
ocr = new OCR(config);
|
||||||
|
|
||||||
for (int i = 0; i < numThreads; i++)
|
|
||||||
{
|
|
||||||
StateIdentifier* stateIdentifier = new StateIdentifier(config);
|
|
||||||
OCR* ocr = new OCR(config);
|
|
||||||
|
|
||||||
stateIdentifiers.push_back(stateIdentifier);
|
|
||||||
ocrs.push_back(ocr);
|
|
||||||
}
|
|
||||||
|
|
||||||
setNumThreads(0);
|
setNumThreads(0);
|
||||||
|
|
||||||
@@ -77,28 +68,10 @@ AlprImpl::~AlprImpl()
|
|||||||
{
|
{
|
||||||
delete config;
|
delete config;
|
||||||
delete plateDetector;
|
delete plateDetector;
|
||||||
|
delete stateIdentifier;
|
||||||
for (int i = 0; i < stateIdentifiers.size(); i++)
|
delete ocr;
|
||||||
{
|
|
||||||
delete stateIdentifiers[i];
|
|
||||||
delete ocrs[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stateIdentifiers.clear();
|
|
||||||
ocrs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int AlprImpl::getNumThreads()
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
if (numThreads > tthread::thread::hardware_concurrency())
|
|
||||||
numThreads = tthread::thread::hardware_concurrency();
|
|
||||||
if (numThreads <= 0)
|
|
||||||
numThreads = 1;
|
|
||||||
|
|
||||||
return numThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
|
std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
|
||||||
{
|
{
|
||||||
@@ -110,11 +83,15 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
|
|||||||
vector<Rect> plateRegions = plateDetector->detect(img);
|
vector<Rect> plateRegions = plateDetector->detect(img);
|
||||||
|
|
||||||
// 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 = getNumThreads();
|
int numThreads = config->multithreading_cores;
|
||||||
|
if (numThreads > tthread::thread::hardware_concurrency())
|
||||||
|
numThreads = tthread::thread::hardware_concurrency();
|
||||||
|
if (numThreads <= 0)
|
||||||
|
numThreads = 1;
|
||||||
|
|
||||||
|
|
||||||
PlateDispatcher dispatcher(plateRegions, &img,
|
PlateDispatcher dispatcher(plateRegions, &img,
|
||||||
config, stateIdentifiers, ocrs,
|
config, stateIdentifier, ocr,
|
||||||
topN, detectRegion, defaultRegion);
|
topN, detectRegion, defaultRegion);
|
||||||
|
|
||||||
// Spawn n threads to process all of the candidate regions and recognize
|
// Spawn n threads to process all of the candidate regions and recognize
|
||||||
@@ -164,28 +141,13 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
|
|||||||
void plateAnalysisThread(void* arg)
|
void plateAnalysisThread(void* arg)
|
||||||
{
|
{
|
||||||
PlateDispatcher* dispatcher = (PlateDispatcher*) arg;
|
PlateDispatcher* dispatcher = (PlateDispatcher*) arg;
|
||||||
|
|
||||||
timespec syncstarttime;
|
|
||||||
getTime(&syncstarttime);
|
|
||||||
|
|
||||||
int threadID = dispatcher->getUniqueThreadId();
|
|
||||||
Mat img = dispatcher->getImageCopy();
|
|
||||||
|
|
||||||
if (dispatcher->config->debugGeneral)
|
if (dispatcher->config->debugGeneral)
|
||||||
cout << "Thread: " << tthread::this_thread::get_id() << " Initialized" << endl;
|
cout << "Thread: " << tthread::this_thread::get_id() << " Initialized" << endl;
|
||||||
|
|
||||||
if (dispatcher->config->debugTiming)
|
|
||||||
{
|
|
||||||
timespec syncendtime;
|
|
||||||
getTime(&syncendtime);
|
|
||||||
cout << "Thread: " << tthread::this_thread::get_id() << " Synchronized initialization time in " << diffclock(syncstarttime, syncendtime) << "ms." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int loop_count = 0;
|
int loop_count = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (dispatcher->hasPlate() == false)
|
if (dispatcher->hasPlate() == false)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -196,7 +158,7 @@ void plateAnalysisThread(void* arg)
|
|||||||
// Get a single plate region from the queue
|
// Get a single plate region from the queue
|
||||||
Rect plateRegion = dispatcher->nextPlate();
|
Rect plateRegion = dispatcher->nextPlate();
|
||||||
|
|
||||||
|
Mat img = dispatcher->getImageCopy();
|
||||||
|
|
||||||
|
|
||||||
// Parallel section
|
// Parallel section
|
||||||
@@ -204,9 +166,6 @@ void plateAnalysisThread(void* arg)
|
|||||||
timespec platestarttime;
|
timespec platestarttime;
|
||||||
getTime(&platestarttime);
|
getTime(&platestarttime);
|
||||||
|
|
||||||
StateIdentifier* stateIdentifier = dispatcher->stateIdentifiers[threadID];
|
|
||||||
OCR* ocr = dispatcher->ocrs[threadID];
|
|
||||||
|
|
||||||
LicensePlateCandidate lp(img, plateRegion, dispatcher->config);
|
LicensePlateCandidate lp(img, plateRegion, dispatcher->config);
|
||||||
|
|
||||||
lp.recognize();
|
lp.recognize();
|
||||||
@@ -227,7 +186,7 @@ void plateAnalysisThread(void* arg)
|
|||||||
if (dispatcher->detectRegion)
|
if (dispatcher->detectRegion)
|
||||||
{
|
{
|
||||||
char statecode[4];
|
char statecode[4];
|
||||||
plateResult.regionConfidence = stateIdentifier->recognize(img, plateRegion, statecode);
|
plateResult.regionConfidence = dispatcher->stateIdentifier->recognize(img, plateRegion, statecode);
|
||||||
if (plateResult.regionConfidence > 0)
|
if (plateResult.regionConfidence > 0)
|
||||||
{
|
{
|
||||||
plateResult.region = statecode;
|
plateResult.region = statecode;
|
||||||
@@ -235,12 +194,12 @@ void plateAnalysisThread(void* arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ocr->performOCR(lp.charSegmenter->getThresholds(), lp.charSegmenter->characters);
|
dispatcher->ocr->performOCR(lp.charSegmenter->getThresholds(), lp.charSegmenter->characters);
|
||||||
|
|
||||||
ocr->postProcessor->analyze(plateResult.region, dispatcher->topN);
|
dispatcher->ocr->postProcessor->analyze(plateResult.region, dispatcher->topN);
|
||||||
|
|
||||||
//plateResult.characters = ocr->postProcessor->bestChars;
|
//plateResult.characters = ocr->postProcessor->bestChars;
|
||||||
const vector<PPResult> ppResults = ocr->postProcessor->getResults();
|
const vector<PPResult> ppResults = dispatcher->ocr->postProcessor->getResults();
|
||||||
|
|
||||||
int bestPlateIndex = 0;
|
int bestPlateIndex = 0;
|
||||||
|
|
||||||
|
@@ -63,17 +63,15 @@ class AlprImpl
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int getNumThreads();
|
|
||||||
cJSON* createJsonObj(const AlprResult* result);
|
|
||||||
|
|
||||||
RegionDetector* plateDetector;
|
RegionDetector* plateDetector;
|
||||||
vector<StateIdentifier*> stateIdentifiers;
|
StateIdentifier* stateIdentifier;
|
||||||
vector<OCR*> ocrs;
|
OCR* ocr;
|
||||||
|
|
||||||
int topN;
|
int topN;
|
||||||
bool detectRegion;
|
bool detectRegion;
|
||||||
std::string defaultRegion;
|
std::string defaultRegion;
|
||||||
|
|
||||||
|
cJSON* createJsonObj(const AlprResult* result);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -83,21 +81,19 @@ class PlateDispatcher
|
|||||||
public:
|
public:
|
||||||
PlateDispatcher(vector<Rect> plateRegions, cv::Mat* image,
|
PlateDispatcher(vector<Rect> plateRegions, cv::Mat* image,
|
||||||
Config* config,
|
Config* config,
|
||||||
vector<StateIdentifier*> stateIdentifiers,
|
StateIdentifier* stateIdentifier,
|
||||||
vector<OCR*> ocrs,
|
OCR* ocr,
|
||||||
int topN, bool detectRegion, std::string defaultRegion)
|
int topN, bool detectRegion, std::string defaultRegion)
|
||||||
{
|
{
|
||||||
this->plateRegions = plateRegions;
|
this->plateRegions = plateRegions;
|
||||||
this->frame = image;
|
this->frame = image;
|
||||||
|
|
||||||
this->config = config;
|
this->config = config;
|
||||||
this->stateIdentifiers = stateIdentifiers;
|
this->stateIdentifier = stateIdentifier;
|
||||||
this->ocrs = ocrs;
|
this->ocr = ocr;
|
||||||
this->topN = topN;
|
this->topN = topN;
|
||||||
this->detectRegion = detectRegion;
|
this->detectRegion = detectRegion;
|
||||||
this->defaultRegion = defaultRegion;
|
this->defaultRegion = defaultRegion;
|
||||||
|
|
||||||
this->threadCounter = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat getImageCopy()
|
cv::Mat getImageCopy()
|
||||||
@@ -110,13 +106,6 @@ class PlateDispatcher
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getUniqueThreadId()
|
|
||||||
{
|
|
||||||
tthread::lock_guard<tthread::mutex> guard(mMutex);
|
|
||||||
|
|
||||||
return threadCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasPlate()
|
bool hasPlate()
|
||||||
{
|
{
|
||||||
bool plateAvailable;
|
bool plateAvailable;
|
||||||
@@ -147,8 +136,8 @@ class PlateDispatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector<StateIdentifier*> stateIdentifiers;
|
StateIdentifier* stateIdentifier;
|
||||||
vector<OCR*> ocrs;
|
OCR* ocr;
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
int topN;
|
int topN;
|
||||||
@@ -157,7 +146,6 @@ class PlateDispatcher
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int threadCounter;
|
|
||||||
tthread::mutex mMutex;
|
tthread::mutex mMutex;
|
||||||
cv::Mat* frame;
|
cv::Mat* frame;
|
||||||
vector<Rect> plateRegions;
|
vector<Rect> plateRegions;
|
||||||
|
Reference in New Issue
Block a user