mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 05:46:51 +08:00
Added regions of interest to ALPR interface. Currently non-functional
This commit is contained in:
@@ -243,7 +243,8 @@ void streamRecognitionThread(void* arg)
|
||||
|
||||
while (daemon_active)
|
||||
{
|
||||
int response = videoBuffer.getLatestFrame(&latestFrame);
|
||||
std::vector<cv::Rect> regionsOfInterest;
|
||||
int response = videoBuffer.getLatestFrame(&latestFrame, regionsOfInterest);
|
||||
|
||||
if (response != -1)
|
||||
{
|
||||
|
@@ -170,7 +170,8 @@ int main( int argc, const char** argv )
|
||||
|
||||
while (program_active)
|
||||
{
|
||||
int response = videoBuffer.getLatestFrame(&latestFrame);
|
||||
std::vector<cv::Rect> regionsOfInterest;
|
||||
int response = videoBuffer.getLatestFrame(&latestFrame, regionsOfInterest);
|
||||
|
||||
if (response != -1)
|
||||
{
|
||||
|
@@ -34,16 +34,24 @@ Alpr::~Alpr()
|
||||
|
||||
std::vector<AlprResult> Alpr::recognize(std::string filepath)
|
||||
{
|
||||
cv::Mat img = cv::imread(filepath, CV_LOAD_IMAGE_COLOR);
|
||||
return impl->recognize(img);
|
||||
std::vector<AlprRegionOfInterest> regionsOfInterest;
|
||||
return this->recognize(filepath, regionsOfInterest);
|
||||
}
|
||||
|
||||
std::vector<AlprResult> Alpr::recognize(std::string filepath, std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||
{
|
||||
return impl->recognize(filepath, regionsOfInterest);
|
||||
}
|
||||
|
||||
std::vector<AlprResult> Alpr::recognize(std::vector<unsigned char> imageBuffer)
|
||||
{
|
||||
// Not sure if this actually works
|
||||
cv::Mat img = cv::imdecode(cv::Mat(imageBuffer), 1);
|
||||
std::vector<AlprRegionOfInterest> regionsOfInterest;
|
||||
return this->recognize(imageBuffer, regionsOfInterest);
|
||||
}
|
||||
|
||||
return impl->recognize(img);
|
||||
std::vector<AlprResult> Alpr::recognize(std::vector<unsigned char> imageBuffer, std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||
{
|
||||
return impl->recognize(imageBuffer, regionsOfInterest);
|
||||
}
|
||||
|
||||
std::string Alpr::toJson(const std::vector< AlprResult > results, double processing_time_ms)
|
||||
|
@@ -39,6 +39,14 @@ struct AlprCoordinate
|
||||
int y;
|
||||
};
|
||||
|
||||
struct AlprRegionOfInterest
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
class AlprResult
|
||||
{
|
||||
public:
|
||||
@@ -71,7 +79,9 @@ class Alpr
|
||||
void setDefaultRegion(std::string region);
|
||||
|
||||
std::vector<AlprResult> recognize(std::string filepath);
|
||||
std::vector<AlprResult> recognize(std::string filepath, std::vector<AlprRegionOfInterest> regionsOfInterest);
|
||||
std::vector<AlprResult> recognize(std::vector<unsigned char> imageBuffer);
|
||||
std::vector<AlprResult> recognize(std::vector<unsigned char> imageBuffer, std::vector<AlprRegionOfInterest> regionsOfInterest);
|
||||
|
||||
std::string toJson(const std::vector<AlprResult> results, double processing_time_ms = -1);
|
||||
|
||||
|
@@ -67,10 +67,21 @@ bool AlprImpl::isLoaded()
|
||||
}
|
||||
|
||||
AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img)
|
||||
{
|
||||
std::vector<cv::Rect> regionsOfInterest;
|
||||
regionsOfInterest.push_back(cv::Rect(0, 0, img.cols, img.rows));
|
||||
|
||||
return this->recognizeFullDetails(img, regionsOfInterest);
|
||||
}
|
||||
|
||||
AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img, std::vector<cv::Rect> regionsOfInterest)
|
||||
{
|
||||
timespec startTime;
|
||||
getTime(&startTime);
|
||||
|
||||
if (regionsOfInterest.size() == 0)
|
||||
regionsOfInterest.push_back(cv::Rect(0, 0, img.cols, img.rows));
|
||||
|
||||
AlprFullDetails response;
|
||||
|
||||
if (!img.data)
|
||||
@@ -89,7 +100,7 @@ AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img)
|
||||
}
|
||||
|
||||
// Find all the candidate regions
|
||||
response.plateRegions = plateDetector->detect(img);
|
||||
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)
|
||||
int numThreads = config->multithreading_cores;
|
||||
@@ -165,12 +176,27 @@ AlprFullDetails AlprImpl::recognizeFullDetails(cv::Mat img)
|
||||
return response;
|
||||
}
|
||||
|
||||
std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
|
||||
|
||||
std::vector<AlprResult> AlprImpl::recognize(std::string filepath, std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||
{
|
||||
AlprFullDetails fullDetails = recognizeFullDetails(img);
|
||||
return fullDetails.results;
|
||||
cv::Mat img = cv::imread(filepath, CV_LOAD_IMAGE_COLOR);
|
||||
|
||||
return this->recognize(img, this->convertRects(regionsOfInterest));
|
||||
}
|
||||
|
||||
std::vector<AlprResult> AlprImpl::recognize(std::vector<unsigned char> imageBuffer, std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||
{
|
||||
cv::Mat img = cv::imdecode(cv::Mat(imageBuffer), 1);
|
||||
|
||||
return this->recognize(img, this->convertRects(regionsOfInterest));
|
||||
}
|
||||
|
||||
std::vector<AlprResult> AlprImpl::recognize(cv::Mat img, std::vector<cv::Rect> regionsOfInterest)
|
||||
{
|
||||
|
||||
AlprFullDetails fullDetails = recognizeFullDetails(img, regionsOfInterest);
|
||||
return fullDetails.results;
|
||||
}
|
||||
void plateAnalysisThread(void* arg)
|
||||
{
|
||||
PlateDispatcher* dispatcher = (PlateDispatcher*) arg;
|
||||
@@ -292,6 +318,17 @@ void plateAnalysisThread(void* arg)
|
||||
cout << "Thread: " << tthread::this_thread::get_id() << " Complete" << endl;
|
||||
}
|
||||
|
||||
std::vector<cv::Rect> AlprImpl::convertRects(std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||
{
|
||||
std::vector<cv::Rect> rectRegions;
|
||||
for (int i = 0; i < regionsOfInterest.size(); i++)
|
||||
{
|
||||
rectRegions.push_back(cv::Rect(regionsOfInterest[i].x, regionsOfInterest[i].y, regionsOfInterest[i].width, regionsOfInterest[i].height));
|
||||
}
|
||||
|
||||
return rectRegions;
|
||||
}
|
||||
|
||||
string AlprImpl::toJson(const vector< AlprResult > results, double processing_time_ms)
|
||||
{
|
||||
cJSON *root, *jsonResults;
|
||||
|
@@ -64,7 +64,11 @@ class AlprImpl
|
||||
virtual ~AlprImpl();
|
||||
|
||||
AlprFullDetails recognizeFullDetails(cv::Mat img);
|
||||
std::vector<AlprResult> recognize(cv::Mat img);
|
||||
AlprFullDetails recognizeFullDetails(cv::Mat img, std::vector<cv::Rect> regionsOfInterest);
|
||||
|
||||
std::vector<AlprResult> recognize(std::string filepath, std::vector<AlprRegionOfInterest> regionsOfInterest);
|
||||
std::vector<AlprResult> recognize(std::vector<unsigned char> imageBuffer, std::vector<AlprRegionOfInterest> regionsOfInterest);
|
||||
std::vector<AlprResult> recognize(cv::Mat img, std::vector<cv::Rect> regionsOfInterest);
|
||||
|
||||
void applyRegionTemplate(AlprResult* result, std::string region);
|
||||
|
||||
@@ -89,6 +93,8 @@ class AlprImpl
|
||||
bool detectRegion;
|
||||
std::string defaultRegion;
|
||||
|
||||
std::vector<cv::Rect> convertRects(std::vector<AlprRegionOfInterest> regionsOfInterest);
|
||||
|
||||
cJSON* createJsonObj(const AlprResult* result);
|
||||
};
|
||||
|
||||
|
@@ -53,19 +53,18 @@ bool RegionDetector::isLoaded()
|
||||
return this->loaded;
|
||||
}
|
||||
|
||||
vector<PlateRegion> RegionDetector::detect(Mat frame)
|
||||
vector<PlateRegion> RegionDetector::detect(Mat frame, std::vector<cv::Rect> regionsOfInterest)
|
||||
{
|
||||
|
||||
Mat frame_gray;
|
||||
cvtColor( frame, frame_gray, CV_BGR2GRAY );
|
||||
|
||||
vector<PlateRegion> regionsOfInterest = doCascade(frame_gray);
|
||||
vector<PlateRegion> detectedRegions = doCascade(frame_gray, regionsOfInterest);
|
||||
|
||||
return regionsOfInterest;
|
||||
return detectedRegions;
|
||||
}
|
||||
|
||||
/** @function detectAndDisplay */
|
||||
vector<PlateRegion> RegionDetector::doCascade(Mat frame)
|
||||
vector<PlateRegion> RegionDetector::doCascade(Mat frame, std::vector<cv::Rect> regionsOfInterest)
|
||||
{
|
||||
|
||||
|
||||
|
@@ -46,7 +46,7 @@ class RegionDetector
|
||||
virtual ~RegionDetector();
|
||||
|
||||
bool isLoaded();
|
||||
std::vector<PlateRegion> detect(cv::Mat frame);
|
||||
std::vector<PlateRegion> detect(cv::Mat frame, std::vector<cv::Rect> regionsOfInterest);
|
||||
|
||||
private:
|
||||
Config* config;
|
||||
@@ -56,7 +56,7 @@ class RegionDetector
|
||||
|
||||
bool loaded;
|
||||
|
||||
std::vector<PlateRegion> doCascade(cv::Mat frame);
|
||||
std::vector<PlateRegion> doCascade(cv::Mat frame, std::vector<cv::Rect> regionsOfInterest);
|
||||
|
||||
std::vector<PlateRegion> aggregateRegions(std::vector<cv::Rect> regions);
|
||||
};
|
||||
|
@@ -72,12 +72,12 @@ void VideoBuffer::connect(std::string mjpeg_url, int fps)
|
||||
|
||||
}
|
||||
|
||||
int VideoBuffer::getLatestFrame(cv::Mat* frame)
|
||||
int VideoBuffer::getLatestFrame(cv::Mat* frame, std::vector<cv::Rect>& regionsOfInterest)
|
||||
{
|
||||
if (dispatcher == NULL)
|
||||
return -1;
|
||||
|
||||
return dispatcher->getLatestFrame(frame);
|
||||
return dispatcher->getLatestFrame(frame, regionsOfInterest);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -25,7 +25,7 @@ class VideoDispatcher
|
||||
}
|
||||
|
||||
|
||||
int getLatestFrame(cv::Mat* frame)
|
||||
int getLatestFrame(cv::Mat* frame, std::vector<cv::Rect>& regionsOfInterest)
|
||||
{
|
||||
tthread::lock_guard<tthread::mutex> guard(mMutex);
|
||||
|
||||
@@ -37,6 +37,10 @@ class VideoDispatcher
|
||||
|
||||
this->lastFrameRead = this->latestFrameNumber;
|
||||
|
||||
// Copy the regionsOfInterest array
|
||||
for (int i = 0; i < this->latestRegionsOfInterest.size(); i++)
|
||||
regionsOfInterest.push_back(this->latestRegionsOfInterest[i]);
|
||||
|
||||
return this->lastFrameRead;
|
||||
}
|
||||
|
||||
@@ -44,6 +48,7 @@ class VideoDispatcher
|
||||
{
|
||||
//tthread::lock_guard<tthread::mutex> guard(mMutex);
|
||||
this->latestFrame = frame;
|
||||
this->latestRegionsOfInterest = calculateRegionsOfInterest(frame);
|
||||
|
||||
this->latestFrameNumber++;
|
||||
}
|
||||
@@ -57,6 +62,16 @@ class VideoDispatcher
|
||||
std::cerr << error << std::endl;
|
||||
}
|
||||
|
||||
std::vector<cv::Rect> calculateRegionsOfInterest(cv::Mat* frame)
|
||||
{
|
||||
cv::Rect rect(0, 0, frame->cols, frame->rows);
|
||||
|
||||
std::vector<cv::Rect> rois;
|
||||
rois.push_back(rect);
|
||||
|
||||
return rois;
|
||||
}
|
||||
|
||||
bool active;
|
||||
|
||||
int latestFrameNumber;
|
||||
@@ -68,7 +83,7 @@ class VideoDispatcher
|
||||
|
||||
private:
|
||||
cv::Mat* latestFrame;
|
||||
|
||||
std::vector<cv::Rect> latestRegionsOfInterest;
|
||||
};
|
||||
|
||||
class VideoBuffer
|
||||
@@ -83,7 +98,8 @@ class VideoBuffer
|
||||
|
||||
// If a new frame is available, the function sets "frame" to it and returns the frame number
|
||||
// If no frames are available, or the latest has already been grabbed, returns -1.
|
||||
int getLatestFrame(cv::Mat* frame);
|
||||
// regionsOfInterest is set to a list of good regions to check for license plates. Default is one rectangle for the entire frame.
|
||||
int getLatestFrame(cv::Mat* frame, std::vector<cv::Rect>& regionsOfInterest);
|
||||
|
||||
void disconnect();
|
||||
|
||||
|
Reference in New Issue
Block a user