Added regions of interest to ALPR interface. Currently non-functional

This commit is contained in:
Matt Hill
2014-08-18 23:23:03 -04:00
parent d76f122ad6
commit aac6d61773
10 changed files with 102 additions and 24 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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