mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 09:26:54 +08:00
Flesh out ALPR daemon
This commit is contained in:
141
src/daemon.cpp
141
src/daemon.cpp
@@ -1,18 +1,30 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "tclap/CmdLine.h"
|
||||||
#include "beanstalk.hpp"
|
#include "beanstalk.hpp"
|
||||||
#include "alpr.h"
|
#include "alpr.h"
|
||||||
#include "openalpr/simpleini/simpleini.h"
|
#include "openalpr/simpleini/simpleini.h"
|
||||||
|
#include "openalpr/cjson.h"
|
||||||
#include "support/tinythread.h"
|
#include "support/tinythread.h"
|
||||||
#include "videobuffer.h"
|
#include "videobuffer.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// prototypes
|
// prototypes
|
||||||
void streamRecognitionThread(void* arg);
|
void streamRecognitionThread(void* arg);
|
||||||
|
bool writeToQueue(std::string jsonResult);
|
||||||
|
|
||||||
struct ThreadData
|
struct ThreadData
|
||||||
{
|
{
|
||||||
std::string stream_url;
|
std::string stream_url;
|
||||||
|
int camera_id;
|
||||||
|
|
||||||
|
std::string config_file;
|
||||||
|
std::string country_code;
|
||||||
|
std::string output_image_folder;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool daemon_active;
|
bool daemon_active;
|
||||||
@@ -21,6 +33,59 @@ int main( int argc, const char** argv )
|
|||||||
{
|
{
|
||||||
daemon_active = true;
|
daemon_active = true;
|
||||||
|
|
||||||
|
bool noDaemon = false;
|
||||||
|
std::string logFile;
|
||||||
|
int topn;
|
||||||
|
|
||||||
|
std::string configFile;
|
||||||
|
std::string country;
|
||||||
|
|
||||||
|
TCLAP::CmdLine cmd("OpenAlpr Daemon", ' ', Alpr::getVersion());
|
||||||
|
|
||||||
|
TCLAP::ValueArg<std::string> countryCodeArg("c","country","Country code to identify (either us for USA or eu for Europe). Default=us",false, "us" ,"country_code");
|
||||||
|
TCLAP::ValueArg<std::string> configFileArg("","config","Path to the openalpr.conf file.",false, "" ,"config_file");
|
||||||
|
TCLAP::ValueArg<int> topNArg("n","topn","Max number of possible plate numbers to return. Default=10",false, 10 ,"topN");
|
||||||
|
TCLAP::ValueArg<std::string> logFileArg("l","log","Log file to write to. Default=/var/log/openalpr.log",false, "/var/log/openalpr.log" ,"topN");
|
||||||
|
|
||||||
|
TCLAP::SwitchArg daemonOffSwitch("f","foreground","Set this flag for debugging. Disables forking the process as a daemon and runs in the foreground. Default=off", cmd, false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
cmd.add( topNArg );
|
||||||
|
cmd.add( configFileArg );
|
||||||
|
cmd.add( logFileArg );
|
||||||
|
|
||||||
|
|
||||||
|
if (cmd.parse( argc, argv ) == false)
|
||||||
|
{
|
||||||
|
// Error occured while parsing. Exit now.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
country = countryCodeArg.getValue();
|
||||||
|
configFile = configFileArg.getValue();
|
||||||
|
logFile = logFileArg.getValue();
|
||||||
|
topn = topNArg.getValue();
|
||||||
|
noDaemon = daemonOffSwitch.getValue();
|
||||||
|
}
|
||||||
|
catch (TCLAP::ArgException &e) // catch any exceptions
|
||||||
|
{
|
||||||
|
std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noDaemon == false)
|
||||||
|
{
|
||||||
|
// Fork off into a separate daemon
|
||||||
|
daemon(0, 0);
|
||||||
|
std::cout << "Running OpenALPR daemon in daemon mode." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Running OpenALPR daemon in the foreground" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
CSimpleIniA ini;
|
CSimpleIniA ini;
|
||||||
ini.SetMultiKey();
|
ini.SetMultiKey();
|
||||||
|
|
||||||
@@ -48,15 +113,27 @@ int main( int argc, const char** argv )
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string imageFolder = ini.GetValue("daemon", "image_folder", "/tmp/");
|
||||||
|
|
||||||
|
std::cout << "Using: " << imageFolder << " for storing valid plate images" << std::endl;
|
||||||
|
|
||||||
for (int i = 0; i < stream_urls.size(); i++)
|
for (int i = 0; i < stream_urls.size(); i++)
|
||||||
{
|
{
|
||||||
ThreadData* tdata = new ThreadData();
|
ThreadData* tdata = new ThreadData();
|
||||||
tdata->stream_url = stream_urls[i];
|
tdata->stream_url = stream_urls[i];
|
||||||
|
tdata->camera_id = i + 1;
|
||||||
|
tdata->config_file = configFile;
|
||||||
|
tdata->output_image_folder = imageFolder;
|
||||||
|
tdata->country_code = country;
|
||||||
|
|
||||||
tthread::thread* t = new tthread::thread(streamRecognitionThread, (void*) tdata);
|
tthread::thread* t = new tthread::thread(streamRecognitionThread, (void*) tdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (daemon_active)
|
||||||
|
{
|
||||||
|
usleep(30000);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +142,14 @@ void streamRecognitionThread(void* arg)
|
|||||||
{
|
{
|
||||||
ThreadData* tdata = (ThreadData*) arg;
|
ThreadData* tdata = (ThreadData*) arg;
|
||||||
|
|
||||||
std::cout << "Stream: " << tdata->stream_url << std::endl;
|
std::cout << "country: " << tdata->country_code << " -- config file: " << tdata->config_file << std::endl;
|
||||||
|
std::cout << "Stream " << tdata->camera_id << ": " << tdata->stream_url << std::endl;
|
||||||
|
|
||||||
|
Alpr alpr(tdata->country_code, tdata->config_file);
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "asdf" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
int framenum = 0;
|
int framenum = 0;
|
||||||
|
|
||||||
@@ -75,19 +159,58 @@ void streamRecognitionThread(void* arg)
|
|||||||
|
|
||||||
cv::Mat latestFrame;
|
cv::Mat latestFrame;
|
||||||
|
|
||||||
/*
|
std::vector<uchar> buffer;
|
||||||
|
|
||||||
|
std::cout << "Daemon active: " << daemon_active << std::endl;
|
||||||
|
|
||||||
while (daemon_active)
|
while (daemon_active)
|
||||||
{
|
{
|
||||||
int response = videoBuffer.getLatestFrame(&latestFrame);
|
int response = videoBuffer.getLatestFrame(&latestFrame);
|
||||||
|
|
||||||
if (response != -1)
|
if (response != -1)
|
||||||
{
|
{
|
||||||
detectandshow( &alpr, latestFrame, "", outputJson);
|
cv::imencode(".bmp", latestFrame, buffer );
|
||||||
|
std::vector<AlprResult> results = alpr.recognize(buffer);
|
||||||
|
|
||||||
|
if (results.size() > 0)
|
||||||
|
{
|
||||||
|
// Create a UUID for the image
|
||||||
|
std::string uuid = newUUID();
|
||||||
|
|
||||||
|
// Save the image to disk (using the UUID)
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << tdata->output_image_folder << "/" << uuid << ".jpg";
|
||||||
|
|
||||||
|
cv::imwrite(ss.str(), latestFrame);
|
||||||
|
|
||||||
|
// Update the JSON content to include UUID and camera ID
|
||||||
|
cJSON *root;
|
||||||
|
|
||||||
|
root=cJSON_CreateObject();
|
||||||
|
|
||||||
|
std::string json = alpr.toJson(results);
|
||||||
|
|
||||||
|
cJSON *array = cJSON_Parse(json.c_str());
|
||||||
|
cJSON_AddStringToObject(root, "uuid", uuid.c_str());
|
||||||
|
cJSON_AddNumberToObject(root, "camera_id", tdata->camera_id);
|
||||||
|
cJSON_AddItemToObject(root, "results", array);
|
||||||
|
|
||||||
|
char *out;
|
||||||
|
out=cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
std::string response(out);
|
||||||
|
|
||||||
|
free(out);
|
||||||
|
|
||||||
|
// Push the results to the Beanstalk queue
|
||||||
|
writeToQueue(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//cv::waitKey(10);
|
usleep(10000);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
videoBuffer.disconnect();
|
videoBuffer.disconnect();
|
||||||
|
|
||||||
@@ -97,14 +220,14 @@ void streamRecognitionThread(void* arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool writeToQueue(AlprResult result)
|
bool writeToQueue(std::string jsonResult)
|
||||||
{
|
{
|
||||||
|
|
||||||
Beanstalk::Client client("127.0.0.1", 11300);
|
Beanstalk::Client client("127.0.0.1", 11300);
|
||||||
client.use("test");
|
client.use("test");
|
||||||
client.watch("test");
|
client.watch("test");
|
||||||
|
|
||||||
int id = client.put("hello");
|
int id = client.put(jsonResult);
|
||||||
|
|
||||||
if (id <= 0)
|
if (id <= 0)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -119,7 +242,7 @@ bool writeToQueue(AlprResult result)
|
|||||||
|
|
||||||
std::cout << "reserved job id: "
|
std::cout << "reserved job id: "
|
||||||
<< job.id()
|
<< job.id()
|
||||||
<< " with body {" << job.body() << "}"
|
<< " with body: " << job.body() << ""
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
client.del(job.id());
|
client.del(job.id());
|
||||||
|
Reference in New Issue
Block a user