mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 02:16:49 +08:00
Remove useless empty lines
This commit is contained in:
@@ -51,7 +51,6 @@ int main( int argc, const char** argv )
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
TCLAP::CmdLine cmd("OpenAlpr Command Line Utility", ' ', OPENALPR_VERSION);
|
TCLAP::CmdLine cmd("OpenAlpr Command Line Utility", ' ', OPENALPR_VERSION);
|
||||||
|
|
||||||
TCLAP::UnlabeledValueArg<std::string> fileArg( "image_file", "Image containing license plates", true, "", "image_file_path" );
|
TCLAP::UnlabeledValueArg<std::string> fileArg( "image_file", "Image containing license plates", true, "", "image_file_path" );
|
||||||
@@ -85,7 +84,6 @@ int main( int argc, const char** argv )
|
|||||||
templateRegion = templateRegionArg.getValue();
|
templateRegion = templateRegionArg.getValue();
|
||||||
topn = topNArg.getValue();
|
topn = topNArg.getValue();
|
||||||
measureProcessingTime = clockSwitch.getValue();
|
measureProcessingTime = clockSwitch.getValue();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (TCLAP::ArgException &e) // catch any exceptions
|
catch (TCLAP::ArgException &e) // catch any exceptions
|
||||||
{
|
{
|
||||||
@@ -157,7 +155,6 @@ int main( int argc, const char** argv )
|
|||||||
{
|
{
|
||||||
std::cerr << "Video file not found: " << filename << std::endl;
|
std::cerr << "Video file not found: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (hasEnding(filename, ".png") || hasEnding(filename, ".jpg") || hasEnding(filename, ".gif"))
|
else if (hasEnding(filename, ".png") || hasEnding(filename, ".jpg") || hasEnding(filename, ".gif"))
|
||||||
{
|
{
|
||||||
@@ -171,7 +168,6 @@ int main( int argc, const char** argv )
|
|||||||
{
|
{
|
||||||
std::cerr << "Image file not found: " << filename << std::endl;
|
std::cerr << "Image file not found: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (DirectoryExists(filename.c_str()))
|
else if (DirectoryExists(filename.c_str()))
|
||||||
{
|
{
|
||||||
@@ -195,7 +191,6 @@ int main( int argc, const char** argv )
|
|||||||
//cv::waitKey(50);
|
//cv::waitKey(50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -209,7 +204,6 @@ int main( int argc, const char** argv )
|
|||||||
|
|
||||||
bool detectandshow( Alpr* alpr, cv::Mat frame, std::string region, bool writeJson)
|
bool detectandshow( Alpr* alpr, cv::Mat frame, std::string region, bool writeJson)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<uchar> buffer;
|
std::vector<uchar> buffer;
|
||||||
cv::imencode(".bmp", frame, buffer );
|
cv::imencode(".bmp", frame, buffer );
|
||||||
|
|
||||||
@@ -232,7 +226,6 @@ bool detectandshow( Alpr* alpr, cv::Mat frame, std::string region, bool writeJso
|
|||||||
{
|
{
|
||||||
std::cout << " - " << results[i].topNPlates[k].characters << "\t confidence: " << results[i].topNPlates[k].overall_confidence << "\t template_match: " << results[i].topNPlates[k].matches_template << std::endl;
|
std::cout << " - " << results[i].topNPlates[k].characters << "\t confidence: " << results[i].topNPlates[k].overall_confidence << "\t template_match: " << results[i].topNPlates[k].matches_template << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,5 +237,4 @@ bool detectandshow( Alpr* alpr, cv::Mat frame, std::string region, bool writeJso
|
|||||||
if (results.size() > 0)
|
if (results.size() > 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,6 @@ int main( int argc, const char** argv )
|
|||||||
benchmarkName = argv[2];
|
benchmarkName = argv[2];
|
||||||
inDir = argv[3];
|
inDir = argv[3];
|
||||||
outDir = argv[4];
|
outDir = argv[4];
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -133,9 +132,7 @@ int main( int argc, const char** argv )
|
|||||||
|
|
||||||
imshow("Current LP", frame);
|
imshow("Current LP", frame);
|
||||||
waitKey(5);
|
waitKey(5);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete config;
|
delete config;
|
||||||
@@ -157,9 +154,7 @@ int main( int argc, const char** argv )
|
|||||||
|
|
||||||
imshow("Current LP", frame);
|
imshow("Current LP", frame);
|
||||||
waitKey(5);
|
waitKey(5);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (benchmarkName.compare("speed") == 0)
|
else if (benchmarkName.compare("speed") == 0)
|
||||||
@@ -254,9 +249,7 @@ int main( int argc, const char** argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
waitKey(5);
|
waitKey(5);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl << "---------------------" << endl;
|
cout << endl << "---------------------" << endl;
|
||||||
@@ -319,14 +312,11 @@ int main( int argc, const char** argv )
|
|||||||
|
|
||||||
imshow("Current LP", frame);
|
imshow("Current LP", frame);
|
||||||
waitKey(5);
|
waitKey(5);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outputdatafile.close();
|
outputdatafile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputStats(vector<double> datapoints)
|
void outputStats(vector<double> datapoints)
|
||||||
@@ -341,5 +331,4 @@ void outputStats(vector<double> datapoints)
|
|||||||
double stdev = std::sqrt(sq_sum / datapoints.size());
|
double stdev = std::sqrt(sq_sum / datapoints.size());
|
||||||
|
|
||||||
cout << "\t" << datapoints.size() << " samples, avg: " << mean << "ms, stdev: " << stdev << endl;
|
cout << "\t" << datapoints.size() << " samples, avg: " << mean << "ms, stdev: " << stdev << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,6 @@ vector<char> showCharSelection(Mat image, vector<Rect> charRegions, string state
|
|||||||
|
|
||||||
int main( int argc, const char** argv )
|
int main( int argc, const char** argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
string inDir;
|
string inDir;
|
||||||
string outDir;
|
string outDir;
|
||||||
Mat frame;
|
Mat frame;
|
||||||
@@ -76,7 +75,6 @@ int main( int argc, const char** argv )
|
|||||||
{
|
{
|
||||||
inDir = argv[1];
|
inDir = argv[1];
|
||||||
outDir = argv[2];
|
outDir = argv[2];
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -227,7 +225,6 @@ int main( int argc, const char** argv )
|
|||||||
// Save
|
// Save
|
||||||
if (somethingSelected && chardataTagged)
|
if (somethingSelected && chardataTagged)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int c = 0; c < charSegmenter.characters.size(); c++)
|
for (int c = 0; c < charSegmenter.characters.size(); c++)
|
||||||
{
|
{
|
||||||
if (humanInputs[c] == ' ')
|
if (humanInputs[c] == ' ')
|
||||||
@@ -253,19 +250,15 @@ int main( int argc, const char** argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
waitkey = (char) waitKey(50);
|
waitkey = (char) waitKey(50);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitkey == 'p')
|
if (waitkey == 'p')
|
||||||
i = i - 2;
|
i = i - 2;
|
||||||
if (i < -1)
|
if (i < -1)
|
||||||
i = -1;
|
i = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void showDashboard(vector<Mat> images, vector<bool> selectedImages, int selectedIndex)
|
void showDashboard(vector<Mat> images, vector<bool> selectedImages, int selectedIndex)
|
||||||
@@ -351,7 +344,6 @@ vector<char> showCharSelection(Mat image, vector<Rect> charRegions, string state
|
|||||||
if (humanInputs[i] != (char) SPACE_KEY)
|
if (humanInputs[i] != (char) SPACE_KEY)
|
||||||
cout << "Tagged " << state << " char code: '" << humanInputs[i] << "' at char position: " << i << endl;
|
cout << "Tagged " << state << " char code: '" << humanInputs[i] << "' at char position: " << i << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyWindow("Character selector");
|
destroyWindow("Character selector");
|
||||||
|
@@ -33,14 +33,12 @@ using namespace cv;
|
|||||||
// Also creates a box file so Tesseract can recognize it
|
// Also creates a box file so Tesseract can recognize it
|
||||||
int main( int argc, const char** argv )
|
int main( int argc, const char** argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
string inDir;
|
string inDir;
|
||||||
|
|
||||||
//Check if user specify image to process
|
//Check if user specify image to process
|
||||||
if(argc == 2)
|
if(argc == 2)
|
||||||
{
|
{
|
||||||
inDir = argv[1];
|
inDir = argv[1];
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -149,15 +147,11 @@ int main( int argc, const char** argv )
|
|||||||
//imshow("characterImg", cropped);
|
//imshow("characterImg", cropped);
|
||||||
|
|
||||||
waitKey(2);
|
waitKey(2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imwrite("combined.tif", bigTif);
|
imwrite("combined.tif", bigTif);
|
||||||
ofstream boxFile("combined.box", std::ios::out);
|
ofstream boxFile("combined.box", std::ios::out);
|
||||||
boxFile << boxFileOut.str();
|
boxFile << boxFileOut.str();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,6 @@ bool detectPlate( StateIdentifier* identifier, Mat frame);
|
|||||||
|
|
||||||
int main( int argc, const char** argv )
|
int main( int argc, const char** argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
string inDir;
|
string inDir;
|
||||||
string outDir;
|
string outDir;
|
||||||
Mat frame;
|
Mat frame;
|
||||||
@@ -51,7 +50,6 @@ int main( int argc, const char** argv )
|
|||||||
inDir = argv[1];
|
inDir = argv[1];
|
||||||
outDir = argv[2];
|
outDir = argv[2];
|
||||||
outDir = outDir + "/";
|
outDir = outDir + "/";
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -107,10 +105,8 @@ int main( int argc, const char** argv )
|
|||||||
else
|
else
|
||||||
waitKey(50);
|
waitKey(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool detectPlate( StateIdentifier* identifier, Mat frame);
|
bool detectPlate( StateIdentifier* identifier, Mat frame);
|
||||||
|
@@ -34,7 +34,6 @@ std::vector<AlprResult> Alpr::recognize(std::string filepath)
|
|||||||
{
|
{
|
||||||
cv::Mat img = cv::imread(filepath, CV_LOAD_IMAGE_COLOR);
|
cv::Mat img = cv::imread(filepath, CV_LOAD_IMAGE_COLOR);
|
||||||
return impl->recognize(img);
|
return impl->recognize(img);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AlprResult> Alpr::recognize(std::vector<unsigned char> imageBuffer)
|
std::vector<AlprResult> Alpr::recognize(std::vector<unsigned char> imageBuffer)
|
||||||
@@ -72,9 +71,7 @@ bool Alpr::isLoaded()
|
|||||||
|
|
||||||
AlprResult::AlprResult()
|
AlprResult::AlprResult()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
AlprResult::~AlprResult()
|
AlprResult::~AlprResult()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ALPR_H
|
#ifndef ALPR_H
|
||||||
#define ALPR_H
|
#define ALPR_H
|
||||||
|
|
||||||
@@ -60,8 +59,6 @@ class AlprResult
|
|||||||
std::string region;
|
std::string region;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AlprImpl;
|
class AlprImpl;
|
||||||
class Alpr
|
class Alpr
|
||||||
{
|
{
|
||||||
|
@@ -32,7 +32,6 @@ AlprImpl::AlprImpl(const std::string country, const std::string runtimeDir)
|
|||||||
|
|
||||||
if (config->opencl_enabled)
|
if (config->opencl_enabled)
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::ocl::PlatformsInfo platinfo;
|
cv::ocl::PlatformsInfo platinfo;
|
||||||
cv::ocl::getOpenCLPlatforms(platinfo);
|
cv::ocl::getOpenCLPlatforms(platinfo);
|
||||||
|
|
||||||
@@ -155,14 +154,12 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
|
|||||||
for (int z = 0; z < 4; z++)
|
for (int z = 0; z < 4; z++)
|
||||||
line(img, lp.plateCorners[z], lp.plateCorners[(z + 1) % 4], Scalar(255,0,255), 2);
|
line(img, lp.plateCorners[z], lp.plateCorners[(z + 1) % 4], Scalar(255,0,255), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (config->debugGeneral)
|
if (config->debugGeneral)
|
||||||
rectangle(img, plateRegions[i], Scalar(0, 0, 255), 2);
|
rectangle(img, plateRegions[i], Scalar(0, 0, 255), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->debugTiming)
|
if (config->debugTiming)
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ALPRIMPL_H
|
#ifndef ALPRIMPL_H
|
||||||
#define ALPRIMPL_H
|
#define ALPRIMPL_H
|
||||||
|
|
||||||
@@ -35,8 +34,6 @@
|
|||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/core/core.hpp>
|
||||||
#include "opencv2/ocl/ocl.hpp"
|
#include "opencv2/ocl/ocl.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_TOPN 25
|
#define DEFAULT_TOPN 25
|
||||||
#define DEFAULT_DETECT_REGION false
|
#define DEFAULT_DETECT_REGION false
|
||||||
|
|
||||||
|
@@ -40,7 +40,6 @@
|
|||||||
|
|
||||||
float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy)
|
float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy)
|
||||||
{
|
{
|
||||||
|
|
||||||
float m,s,max_s;
|
float m,s,max_s;
|
||||||
long sum, sum_sq;
|
long sum, sum_sq;
|
||||||
uchar foo;
|
uchar foo;
|
||||||
@@ -73,7 +72,6 @@ float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy)
|
|||||||
// Shift the window, add and remove new/old values to the histogram
|
// Shift the window, add and remove new/old values to the histogram
|
||||||
for (int i=1 ; i <= im.cols-winx; i++)
|
for (int i=1 ; i <= im.cols-winx; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Remove the left old column and add the right new column
|
// Remove the left old column and add the right new column
|
||||||
for (int wy=0; wy<winy; ++wy)
|
for (int wy=0; wy<winy; ++wy)
|
||||||
{
|
{
|
||||||
@@ -103,7 +101,6 @@ float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy)
|
|||||||
void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
|
void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
|
||||||
int winx, int winy, float k)
|
int winx, int winy, float k)
|
||||||
{
|
{
|
||||||
|
|
||||||
float dR = BINARIZEWOLF_DEFAULTDR;
|
float dR = BINARIZEWOLF_DEFAULTDR;
|
||||||
|
|
||||||
float m, s, max_s;
|
float m, s, max_s;
|
||||||
@@ -131,18 +128,15 @@ void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
|
|||||||
|
|
||||||
for (int j = y_firstth ; j<=y_lastth; j++)
|
for (int j = y_firstth ; j<=y_lastth; j++)
|
||||||
{
|
{
|
||||||
|
|
||||||
// NORMAL, NON-BORDER AREA IN THE MIDDLE OF THE WINDOW:
|
// NORMAL, NON-BORDER AREA IN THE MIDDLE OF THE WINDOW:
|
||||||
for (int i=0 ; i <= im.cols-winx; i++)
|
for (int i=0 ; i <= im.cols-winx; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
m = map_m.fget(i+wxh, j);
|
m = map_m.fget(i+wxh, j);
|
||||||
s = map_s.fget(i+wxh, j);
|
s = map_s.fget(i+wxh, j);
|
||||||
|
|
||||||
// Calculate the threshold
|
// Calculate the threshold
|
||||||
switch (version)
|
switch (version)
|
||||||
{
|
{
|
||||||
|
|
||||||
case NIBLACK:
|
case NIBLACK:
|
||||||
th = m + k*s;
|
th = m + k*s;
|
||||||
break;
|
break;
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef BINARIZEWOLF_H
|
#ifndef BINARIZEWOLF_H
|
||||||
#define BINARIZEWOLF_H
|
#define BINARIZEWOLF_H
|
||||||
|
|
||||||
@@ -40,17 +39,12 @@ enum NiblackVersion
|
|||||||
#define BINARIZEWOLF_VERSION "2.3 (February 26th, 2013)"
|
#define BINARIZEWOLF_VERSION "2.3 (February 26th, 2013)"
|
||||||
#define BINARIZEWOLF_DEFAULTDR 128
|
#define BINARIZEWOLF_DEFAULTDR 128
|
||||||
|
|
||||||
|
|
||||||
#define uget(x,y) at<unsigned char>(y,x)
|
#define uget(x,y) at<unsigned char>(y,x)
|
||||||
#define uset(x,y,v) at<unsigned char>(y,x)=v;
|
#define uset(x,y,v) at<unsigned char>(y,x)=v;
|
||||||
#define fget(x,y) at<float>(y,x)
|
#define fget(x,y) at<float>(y,x)
|
||||||
#define fset(x,y,v) at<float>(y,x)=v;
|
#define fset(x,y,v) at<float>(y,x)=v;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
|
void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
|
||||||
int winx, int winy, float k);
|
int winx, int winy, float k);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BINARIZEWOLF_H
|
#endif // BINARIZEWOLF_H
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
CharacterAnalysis::CharacterAnalysis(Mat img, Config* config)
|
CharacterAnalysis::CharacterAnalysis(Mat img, Config* config)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->config = config;
|
this->config = config;
|
||||||
|
|
||||||
this->hasPlateMask = false;
|
this->hasPlateMask = false;
|
||||||
@@ -36,7 +35,6 @@ CharacterAnalysis::CharacterAnalysis(Mat img, Config* config)
|
|||||||
img_gray = Mat(img.size(), img.type());
|
img_gray = Mat(img.size(), img.type());
|
||||||
img.copyTo(img_gray);
|
img.copyTo(img_gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterAnalysis::~CharacterAnalysis()
|
CharacterAnalysis::~CharacterAnalysis()
|
||||||
@@ -50,7 +48,6 @@ CharacterAnalysis::~CharacterAnalysis()
|
|||||||
|
|
||||||
void CharacterAnalysis::analyze()
|
void CharacterAnalysis::analyze()
|
||||||
{
|
{
|
||||||
|
|
||||||
thresholds = produceThresholds(img_gray, config);
|
thresholds = produceThresholds(img_gray, config);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -64,7 +61,6 @@ void CharacterAnalysis::analyze()
|
|||||||
//morphologyEx( mask, mask, MORPH_CLOSE, element );
|
//morphologyEx( mask, mask, MORPH_CLOSE, element );
|
||||||
morphologyEx( thresholds[i], thresholds[i], MORPH_OPEN, element );
|
morphologyEx( thresholds[i], thresholds[i], MORPH_OPEN, element );
|
||||||
//dilate( thresholds[i], thresholds[i], element );
|
//dilate( thresholds[i], thresholds[i], element );
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -129,7 +125,6 @@ void CharacterAnalysis::analyze()
|
|||||||
int bestFitIndex = -1;
|
int bestFitIndex = -1;
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (int i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
//vector<bool> goodIndices = this->filter(thresholds[i], allContours[i], allHierarchy[i]);
|
//vector<bool> goodIndices = this->filter(thresholds[i], allContours[i], allHierarchy[i]);
|
||||||
//charSegments.push_back(goodIndices);
|
//charSegments.push_back(goodIndices);
|
||||||
|
|
||||||
@@ -157,7 +152,6 @@ void CharacterAnalysis::analyze()
|
|||||||
|
|
||||||
if (this->config->debugCharAnalysis)
|
if (this->config->debugCharAnalysis)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat img_contours(bestThreshold.size(), CV_8U);
|
Mat img_contours(bestThreshold.size(), CV_8U);
|
||||||
bestThreshold.copyTo(img_contours);
|
bestThreshold.copyTo(img_contours);
|
||||||
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
||||||
@@ -201,12 +195,10 @@ void CharacterAnalysis::analyze()
|
|||||||
this->charBoxBottom = LineSegment(this->charArea[3].x, this->charArea[3].y, this->charArea[2].x, this->charArea[2].y);
|
this->charBoxBottom = LineSegment(this->charArea[3].x, this->charArea[3].y, this->charArea[2].x, this->charArea[2].y);
|
||||||
this->charBoxLeft = LineSegment(this->charArea[3].x, this->charArea[3].y, this->charArea[0].x, this->charArea[0].y);
|
this->charBoxLeft = LineSegment(this->charArea[3].x, this->charArea[3].y, this->charArea[0].x, this->charArea[0].y);
|
||||||
this->charBoxRight = LineSegment(this->charArea[2].x, this->charArea[2].y, this->charArea[1].x, this->charArea[1].y);
|
this->charBoxRight = LineSegment(this->charArea[2].x, this->charArea[2].y, this->charArea[1].x, this->charArea[1].y);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->thresholdsInverted = isPlateInverted();
|
this->thresholdsInverted = isPlateInverted();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CharacterAnalysis::getGoodIndicesCount(vector<bool> goodIndices)
|
int CharacterAnalysis::getGoodIndicesCount(vector<bool> goodIndices)
|
||||||
@@ -269,7 +261,6 @@ Mat CharacterAnalysis::findOuterBoxMask()
|
|||||||
lowestArea = boxArea;
|
lowestArea = boxArea;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->config->debugCharAnalysis)
|
if (this->config->debugCharAnalysis)
|
||||||
@@ -356,7 +347,6 @@ Mat CharacterAnalysis::findOuterBoxMask()
|
|||||||
allHierarchy[winningIndex],
|
allHierarchy[winningIndex],
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->config->debugCharAnalysis)
|
if (this->config->debugCharAnalysis)
|
||||||
@@ -382,12 +372,10 @@ Mat CharacterAnalysis::findOuterBoxMask()
|
|||||||
Mat fullMask = Mat::zeros(thresholds[0].size(), CV_8U);
|
Mat fullMask = Mat::zeros(thresholds[0].size(), CV_8U);
|
||||||
bitwise_not(fullMask, fullMask);
|
bitwise_not(fullMask, fullMask);
|
||||||
return fullMask;
|
return fullMask;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat CharacterAnalysis::getCharacterMask()
|
Mat CharacterAnalysis::getCharacterMask()
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat charMask = Mat::zeros(bestThreshold.size(), CV_8U);
|
Mat charMask = Mat::zeros(bestThreshold.size(), CV_8U);
|
||||||
|
|
||||||
for (int i = 0; i < bestContours.size(); i++)
|
for (int i = 0; i < bestContours.size(); i++)
|
||||||
@@ -421,7 +409,6 @@ Mat CharacterAnalysis::getCharacterMask()
|
|||||||
// Returns a polygon "stripe" across the width of the character region. The lines are voted and the polygon starts at 0 and extends to image width
|
// Returns a polygon "stripe" across the width of the character region. The lines are voted and the polygon starts at 0 and extends to image width
|
||||||
vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices)
|
vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices)
|
||||||
{
|
{
|
||||||
|
|
||||||
//if (this->debug)
|
//if (this->debug)
|
||||||
// cout << "CharacterAnalysis::getBestVotedLines" << endl;
|
// cout << "CharacterAnalysis::getBestVotedLines" << endl;
|
||||||
|
|
||||||
@@ -519,7 +506,6 @@ vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point>
|
|||||||
int curScore = 0;
|
int curScore = 0;
|
||||||
for (int charidx = 0; charidx < charRegions.size(); charidx++)
|
for (int charidx = 0; charidx < charRegions.size(); charidx++)
|
||||||
{
|
{
|
||||||
|
|
||||||
float topYPos = topLines[i].getPointAt(charRegions[charidx].x);
|
float topYPos = topLines[i].getPointAt(charRegions[charidx].x);
|
||||||
float botYPos = bottomLines[i].getPointAt(charRegions[charidx].x);
|
float botYPos = bottomLines[i].getPointAt(charRegions[charidx].x);
|
||||||
|
|
||||||
@@ -535,7 +521,6 @@ vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point>
|
|||||||
|
|
||||||
//cout << "Slope: " << topslope << " yPos: " << topYPos << endl;
|
//cout << "Slope: " << topslope << " yPos: " << topYPos << endl;
|
||||||
//drawAndWait(&tempImg);
|
//drawAndWait(&tempImg);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tie goes to the one with longer line segments
|
// Tie goes to the one with longer line segments
|
||||||
@@ -573,7 +558,6 @@ vector<Point> CharacterAnalysis::getBestVotedLines(Mat img, vector<vector<Point>
|
|||||||
bestStripe.push_back(topRight);
|
bestStripe.push_back(topRight);
|
||||||
bestStripe.push_back(bottomRight);
|
bestStripe.push_back(bottomRight);
|
||||||
bestStripe.push_back(bottomLeft);
|
bestStripe.push_back(bottomLeft);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestStripe;
|
return bestStripe;
|
||||||
@@ -624,7 +608,6 @@ vector<bool> CharacterAnalysis::filter(Mat img, vector<vector<Point> > contours,
|
|||||||
// Goes through the contours for the plate and picks out possible char segments based on min/max height
|
// Goes through the contours for the plate and picks out possible char segments based on min/max height
|
||||||
vector<bool> CharacterAnalysis::filterByBoxSize(vector< vector< Point> > contours, vector<bool> goodIndices, int minHeightPx, int maxHeightPx)
|
vector<bool> CharacterAnalysis::filterByBoxSize(vector< vector< Point> > contours, vector<bool> goodIndices, int minHeightPx, int maxHeightPx)
|
||||||
{
|
{
|
||||||
|
|
||||||
float idealAspect=config->charWidthMM / config->charHeightMM;
|
float idealAspect=config->charWidthMM / config->charHeightMM;
|
||||||
float aspecttolerance=0.25;
|
float aspecttolerance=0.25;
|
||||||
|
|
||||||
@@ -645,7 +628,6 @@ vector<bool> CharacterAnalysis::filterByBoxSize(vector< vector< Point> > contour
|
|||||||
//Mat auxRoi(img, mr);
|
//Mat auxRoi(img, mr);
|
||||||
if(mr.height >= minHeightPx && mr.height <= maxHeightPx && mr.width > minWidth)
|
if(mr.height >= minHeightPx && mr.height <= maxHeightPx && mr.width > minWidth)
|
||||||
{
|
{
|
||||||
|
|
||||||
float charAspect= (float)mr.width/(float)mr.height;
|
float charAspect= (float)mr.width/(float)mr.height;
|
||||||
|
|
||||||
if (abs(charAspect - idealAspect) < aspecttolerance)
|
if (abs(charAspect - idealAspect) < aspecttolerance)
|
||||||
@@ -654,12 +636,10 @@ vector<bool> CharacterAnalysis::filterByBoxSize(vector< vector< Point> > contour
|
|||||||
}
|
}
|
||||||
|
|
||||||
return includedIndices;
|
return includedIndices;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector< bool > CharacterAnalysis::filterContourHoles(vector< vector< Point > > contours, vector< Vec4i > hierarchy, vector< bool > goodIndices)
|
vector< bool > CharacterAnalysis::filterContourHoles(vector< vector< Point > > contours, vector< Vec4i > hierarchy, vector< bool > goodIndices)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<bool> includedIndices(contours.size());
|
vector<bool> includedIndices(contours.size());
|
||||||
for (int j = 0; j < contours.size(); j++)
|
for (int j = 0; j < contours.size(); j++)
|
||||||
includedIndices.push_back(false);
|
includedIndices.push_back(false);
|
||||||
@@ -692,7 +672,6 @@ vector< bool > CharacterAnalysis::filterContourHoles(vector< vector< Point > > c
|
|||||||
// returns a vector of indices corresponding to valid contours
|
// returns a vector of indices corresponding to valid contours
|
||||||
vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices)
|
vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<bool> includedIndices(contours.size());
|
vector<bool> includedIndices(contours.size());
|
||||||
for (int j = 0; j < contours.size(); j++)
|
for (int j = 0; j < contours.size(); j++)
|
||||||
includedIndices[j] = false;
|
includedIndices[j] = false;
|
||||||
@@ -725,7 +704,6 @@ vector<bool> CharacterAnalysis::filterByParentContour( vector< vector< Point> >
|
|||||||
{
|
{
|
||||||
votes[voteIndex] = votes[voteIndex] + 1;
|
votes[voteIndex] = votes[voteIndex] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tally up the votes, pick the winner
|
// Tally up the votes, pick the winner
|
||||||
@@ -816,7 +794,6 @@ vector<bool> CharacterAnalysis::filterBetweenLines(Mat img, vector<vector<Point>
|
|||||||
for (int tempContourIdx = 0; tempContourIdx < tempContours.size(); tempContourIdx++)
|
for (int tempContourIdx = 0; tempContourIdx < tempContours.size(); tempContourIdx++)
|
||||||
{
|
{
|
||||||
areaBetweenLines += contourArea(tempContours[tempContourIdx]);
|
areaBetweenLines += contourArea(tempContours[tempContourIdx]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (areaBetweenLines / totalArea >= MIN_AREA_PERCENT_WITHIN_LINES)
|
if (areaBetweenLines / totalArea >= MIN_AREA_PERCENT_WITHIN_LINES)
|
||||||
@@ -882,7 +859,6 @@ std::vector< bool > CharacterAnalysis::filterByOuterMask(vector< vector< Point >
|
|||||||
|
|
||||||
bool CharacterAnalysis::isPlateInverted()
|
bool CharacterAnalysis::isPlateInverted()
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat charMask = getCharacterMask();
|
Mat charMask = getCharacterMask();
|
||||||
|
|
||||||
Scalar meanVal = mean(bestThreshold, charMask)[0];
|
Scalar meanVal = mean(bestThreshold, charMask)[0];
|
||||||
@@ -920,7 +896,6 @@ bool CharacterAnalysis::verifySize(Mat r, float minHeightPx, float maxHeightPx)
|
|||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Point> CharacterAnalysis::getCharArea()
|
vector<Point> CharacterAnalysis::getCharArea()
|
||||||
|
@@ -17,8 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CHARACTERANALYSIS_H
|
#ifndef CHARACTERANALYSIS_H
|
||||||
#define CHARACTERANALYSIS_H
|
#define CHARACTERANALYSIS_H
|
||||||
|
|
||||||
@@ -30,7 +28,6 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
class CharacterAnalysis
|
class CharacterAnalysis
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -68,8 +65,6 @@ class CharacterAnalysis
|
|||||||
|
|
||||||
Mat getCharacterMask();
|
Mat getCharacterMask();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
@@ -77,7 +72,6 @@ class CharacterAnalysis
|
|||||||
|
|
||||||
Mat findOuterBoxMask( );
|
Mat findOuterBoxMask( );
|
||||||
|
|
||||||
|
|
||||||
bool isPlateInverted();
|
bool isPlateInverted();
|
||||||
vector<bool> filter(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy);
|
vector<bool> filter(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy);
|
||||||
|
|
||||||
@@ -95,7 +89,6 @@ class CharacterAnalysis
|
|||||||
|
|
||||||
int getGoodIndicesCount(vector<bool> goodIndices);
|
int getGoodIndicesCount(vector<bool> goodIndices);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHARACTERANALYSIS_H
|
#endif // CHARACTERANALYSIS_H
|
||||||
|
@@ -96,7 +96,6 @@ CharacterRegion::CharacterRegion(Mat img, Config* config)
|
|||||||
|
|
||||||
if (charAnalysis->linePolygon.size() > 0)
|
if (charAnalysis->linePolygon.size() > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
int confidenceDrainers = 0;
|
int confidenceDrainers = 0;
|
||||||
int charSegmentCount = charAnalysis->bestCharSegmentsCount;
|
int charSegmentCount = charAnalysis->bestCharSegmentsCount;
|
||||||
if (charSegmentCount == 1)
|
if (charSegmentCount == 1)
|
||||||
@@ -114,7 +113,6 @@ CharacterRegion::CharacterRegion(Mat img, Config* config)
|
|||||||
this->confidence=1;
|
this->confidence=1;
|
||||||
else
|
else
|
||||||
this->confidence = 100 - confidenceDrainers;
|
this->confidence = 100 - confidenceDrainers;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->debugTiming)
|
if (config->debugTiming)
|
||||||
@@ -123,7 +121,6 @@ CharacterRegion::CharacterRegion(Mat img, Config* config)
|
|||||||
getTime(&endTime);
|
getTime(&endTime);
|
||||||
cout << "Character Region Time: " << diffclock(startTime, endTime) << "ms." << endl;
|
cout << "Character Region Time: " << diffclock(startTime, endTime) << "ms." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterRegion::~CharacterRegion()
|
CharacterRegion::~CharacterRegion()
|
||||||
|
@@ -17,8 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CHARACTERREGION_H
|
#ifndef CHARACTERREGION_H
|
||||||
#define CHARACTERREGION_H
|
#define CHARACTERREGION_H
|
||||||
|
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
class CharacterRegion
|
class CharacterRegion
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
CharacterSegmenter::CharacterSegmenter(Mat img, bool invertedColors, Config* config)
|
CharacterSegmenter::CharacterSegmenter(Mat img, bool invertedColors, Config* config)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->config = config;
|
this->config = config;
|
||||||
|
|
||||||
this->confidence = 0;
|
this->confidence = 0;
|
||||||
@@ -52,7 +51,6 @@ CharacterSegmenter::CharacterSegmenter(Mat img, bool invertedColors, Config* con
|
|||||||
|
|
||||||
if (this->config->debugCharSegmenter)
|
if (this->config->debugCharSegmenter)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat img_contours(charAnalysis->bestThreshold.size(), CV_8U);
|
Mat img_contours(charAnalysis->bestThreshold.size(), CV_8U);
|
||||||
charAnalysis->bestThreshold.copyTo(img_contours);
|
charAnalysis->bestThreshold.copyTo(img_contours);
|
||||||
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
|
||||||
@@ -118,7 +116,6 @@ CharacterSegmenter::CharacterSegmenter(Mat img, bool invertedColors, Config* con
|
|||||||
vector<Rect> allBoxes;
|
vector<Rect> allBoxes;
|
||||||
for (int i = 0; i < charAnalysis->allContours.size(); i++)
|
for (int i = 0; i < charAnalysis->allContours.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat histogramMask = Mat::zeros(charAnalysis->thresholds[i].size(), CV_8U);
|
Mat histogramMask = Mat::zeros(charAnalysis->thresholds[i].size(), CV_8U);
|
||||||
|
|
||||||
fillConvexPoly(histogramMask, charAnalysis->linePolygon.data(), charAnalysis->linePolygon.size(), Scalar(255,255,255));
|
fillConvexPoly(histogramMask, charAnalysis->linePolygon.data(), charAnalysis->linePolygon.size(), Scalar(255,255,255));
|
||||||
@@ -215,7 +212,6 @@ CharacterSegmenter::CharacterSegmenter(Mat img, bool invertedColors, Config* con
|
|||||||
|
|
||||||
if (this->config->debugCharSegmenter)
|
if (this->config->debugCharSegmenter)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat imgDash = drawImageDashboard(charAnalysis->thresholds, CV_8U, 3);
|
Mat imgDash = drawImageDashboard(charAnalysis->thresholds, CV_8U, 3);
|
||||||
displayImage(config, "Segmentation after cleaning", imgDash);
|
displayImage(config, "Segmentation after cleaning", imgDash);
|
||||||
|
|
||||||
@@ -257,7 +253,6 @@ vector<Rect> CharacterSegmenter::getHistogramBoxes(VerticalHistogram histogram,
|
|||||||
|
|
||||||
for (int i = 0; i < allBoxes.size(); i++)
|
for (int i = 0; i < allBoxes.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (allBoxes[i].width >= config->segmentationMinBoxWidthPx && allBoxes[i].width <= MAX_SEGMENT_WIDTH &&
|
if (allBoxes[i].width >= config->segmentationMinBoxWidthPx && allBoxes[i].width <= MAX_SEGMENT_WIDTH &&
|
||||||
allBoxes[i].height > MIN_HISTOGRAM_HEIGHT )
|
allBoxes[i].height > MIN_HISTOGRAM_HEIGHT )
|
||||||
{
|
{
|
||||||
@@ -292,7 +287,6 @@ vector<Rect> CharacterSegmenter::getHistogramBoxes(VerticalHistogram histogram,
|
|||||||
charBoxes.push_back(Rect(topLeft, allBoxes[i].br()) );
|
charBoxes.push_back(Rect(topLeft, allBoxes[i].br()) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return charBoxes;
|
return charBoxes;
|
||||||
@@ -300,7 +294,6 @@ vector<Rect> CharacterSegmenter::getHistogramBoxes(VerticalHistogram histogram,
|
|||||||
|
|
||||||
vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxes, float avgCharWidth)
|
vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxes, float avgCharWidth)
|
||||||
{
|
{
|
||||||
|
|
||||||
float MAX_SEGMENT_WIDTH = avgCharWidth * 1.55;
|
float MAX_SEGMENT_WIDTH = avgCharWidth * 1.55;
|
||||||
|
|
||||||
// This histogram is based on how many char boxes (from ALL of the many thresholded images) are covering each column
|
// This histogram is based on how many char boxes (from ALL of the many thresholded images) are covering each column
|
||||||
@@ -410,7 +403,6 @@ vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxe
|
|||||||
|
|
||||||
this->imgDbgGeneral.push_back(addLabel(histoImg, "All Histograms"));
|
this->imgDbgGeneral.push_back(addLabel(histoImg, "All Histograms"));
|
||||||
this->imgDbgGeneral.push_back(addLabel(imgBestBoxes, "Best Boxes"));
|
this->imgDbgGeneral.push_back(addLabel(imgBestBoxes, "Best Boxes"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestBoxes;
|
return bestBoxes;
|
||||||
@@ -443,7 +435,6 @@ vector<Rect> CharacterSegmenter::get1DHits(Mat img, int yOffset)
|
|||||||
onSegment = false;
|
onSegment = false;
|
||||||
curSegmentLength = 0;
|
curSegmentLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hits;
|
return hits;
|
||||||
@@ -456,7 +447,6 @@ void CharacterSegmenter::removeSmallContours(vector<Mat> thresholds, vector<vect
|
|||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (int i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int c = 0; c < allContours[i].size(); c++)
|
for (int c = 0; c < allContours[i].size(); c++)
|
||||||
{
|
{
|
||||||
if (allContours[i][c].size() == 0)
|
if (allContours[i][c].size() == 0)
|
||||||
@@ -469,7 +459,6 @@ void CharacterSegmenter::removeSmallContours(vector<Mat> thresholds, vector<vect
|
|||||||
drawContours(thresholds[i], allContours[i], c, Scalar(0, 0, 0), -1);
|
drawContours(thresholds[i], allContours[i], c, Scalar(0, 0, 0), -1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,7 +502,6 @@ vector<Rect> CharacterSegmenter::combineCloseBoxes( vector<Rect> charBoxes, floa
|
|||||||
{
|
{
|
||||||
newCharBoxes.push_back(charBoxes[i]);
|
newCharBoxes.push_back(charBoxes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newCharBoxes;
|
return newCharBoxes;
|
||||||
@@ -577,14 +565,12 @@ void CharacterSegmenter::cleanCharRegions(vector<Mat> thresholds, vector<Rect> c
|
|||||||
tallestContourHeight = r.height;
|
tallestContourHeight = r.height;
|
||||||
|
|
||||||
totalArea += contourArea(contours[c]);
|
totalArea += contourArea(contours[c]);
|
||||||
|
|
||||||
}
|
}
|
||||||
//else if (r.height > tallestContourHeight)
|
//else if (r.height > tallestContourHeight)
|
||||||
//{
|
//{
|
||||||
// tallestContourIndex = c;
|
// tallestContourIndex = c;
|
||||||
// tallestContourHeight = h;
|
// tallestContourHeight = h;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalArea < MIN_CONTOUR_AREA)
|
if (totalArea < MIN_CONTOUR_AREA)
|
||||||
@@ -612,7 +598,6 @@ void CharacterSegmenter::cleanCharRegions(vector<Mat> thresholds, vector<Rect> c
|
|||||||
}
|
}
|
||||||
rectangle(thresholds[i], charRegions[j], Scalar(0, 0, 0), -1);
|
rectangle(thresholds[i], charRegions[j], Scalar(0, 0, 0), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat closureElement = getStructuringElement( 1,
|
Mat closureElement = getStructuringElement( 1,
|
||||||
@@ -633,7 +618,6 @@ void CharacterSegmenter::cleanCharRegions(vector<Mat> thresholds, vector<Rect> c
|
|||||||
line(thresholds[i], Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y), Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y + charRegions[j].height), Scalar(0, 0, 0));
|
line(thresholds[i], Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y), Point(charRegions[j].x + charRegions[j].width + 1, charRegions[j].y + charRegions[j].height), Scalar(0, 0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterSegmenter::cleanBasedOnColor(vector<Mat> thresholds, Mat colorMask, vector<Rect> charRegions)
|
void CharacterSegmenter::cleanBasedOnColor(vector<Mat> thresholds, Mat colorMask, vector<Rect> charRegions)
|
||||||
@@ -644,10 +628,8 @@ void CharacterSegmenter::cleanBasedOnColor(vector<Mat> thresholds, Mat colorMask
|
|||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (int i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int j = 0; j < charRegions.size(); j++)
|
for (int j = 0; j < charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat boxChar = Mat::zeros(thresholds[i].size(), CV_8U);
|
Mat boxChar = Mat::zeros(thresholds[i].size(), CV_8U);
|
||||||
rectangle(boxChar, charRegions[j], Scalar(255,255,255), CV_FILLED);
|
rectangle(boxChar, charRegions[j], Scalar(255,255,255), CV_FILLED);
|
||||||
|
|
||||||
@@ -687,7 +669,6 @@ void CharacterSegmenter::cleanBasedOnColor(vector<Mat> thresholds, Mat colorMask
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,7 +714,6 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (int i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int j = 0; j < charRegions.size(); j++)
|
for (int j = 0; j < charRegions.size(); j++)
|
||||||
{
|
{
|
||||||
//float minArea = charRegions[j].area() * MIN_AREA_PERCENT;
|
//float minArea = charRegions[j].area() * MIN_AREA_PERCENT;
|
||||||
@@ -755,7 +735,6 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
|
|
||||||
for (int z = 0; z < contours[c].size(); z++)
|
for (int z = 0; z < contours[c].size(); z++)
|
||||||
allPointsInBox.push_back(contours[c][z]);
|
allPointsInBox.push_back(contours[c][z]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float height = 0;
|
float height = 0;
|
||||||
@@ -772,9 +751,7 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
{
|
{
|
||||||
drawX(imgDbgCleanStages[i], charRegions[j], COLOR_DEBUG_EMPTYFILTER, 3);
|
drawX(imgDbgCleanStages[i], charRegions[j], COLOR_DEBUG_EMPTYFILTER, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Rect> newCharRegions;
|
vector<Rect> newCharRegions;
|
||||||
@@ -809,7 +786,6 @@ vector<Rect> CharacterSegmenter::filterMostlyEmptyBoxes(vector<Mat> thresholds,
|
|||||||
|
|
||||||
drawX(imgDbgCleanStages[z], charRegions[i], COLOR_DEBUG_EMPTYFILTER, 1);
|
drawX(imgDbgCleanStages[z], charRegions[i], COLOR_DEBUG_EMPTYFILTER, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -879,7 +855,6 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
int col = charRegions[0].x + charRegions[0].width;
|
int col = charRegions[0].x + charRegions[0].width;
|
||||||
while (col >= 0)
|
while (col >= 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
int rowLength = getLongestBlobLengthBetweenLines(rotated, col);
|
int rowLength = getLongestBlobLengthBetweenLines(rotated, col);
|
||||||
|
|
||||||
if (rowLength > MIN_CONNECTED_EDGE_PIXELS)
|
if (rowLength > MIN_CONNECTED_EDGE_PIXELS)
|
||||||
@@ -894,7 +869,6 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
col = charRegions[charRegions.size() - 1].x;
|
col = charRegions[charRegions.size() - 1].x;
|
||||||
while (col < rotated.cols)
|
while (col < rotated.cols)
|
||||||
{
|
{
|
||||||
|
|
||||||
int rowLength = getLongestBlobLengthBetweenLines(rotated, col);
|
int rowLength = getLongestBlobLengthBetweenLines(rotated, col);
|
||||||
|
|
||||||
if (rowLength > MIN_CONNECTED_EDGE_PIXELS)
|
if (rowLength > MIN_CONNECTED_EDGE_PIXELS)
|
||||||
@@ -909,7 +883,6 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
leftEdges.push_back(leftEdgeX);
|
leftEdges.push_back(leftEdgeX);
|
||||||
if (rightEdgeX != thresholds[i].cols)
|
if (rightEdgeX != thresholds[i].cols)
|
||||||
rightEdges.push_back(rightEdgeX);
|
rightEdges.push_back(rightEdgeX);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int leftEdge = 0;
|
int leftEdge = 0;
|
||||||
@@ -1032,7 +1005,6 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
// for now, just mask the whole thing
|
// for now, just mask the whole thing
|
||||||
if (this->debug)
|
if (this->debug)
|
||||||
{
|
{
|
||||||
|
|
||||||
rectangle(imgDbgCleanStages[i], charRegions[boxidx], COLOR_DEBUG_EDGE, 2);
|
rectangle(imgDbgCleanStages[i], charRegions[boxidx], COLOR_DEBUG_EDGE, 2);
|
||||||
cout << "Edge Filter: threshold " << i << " box " << boxidx << endl;
|
cout << "Edge Filter: threshold " << i << " box " << boxidx << endl;
|
||||||
}
|
}
|
||||||
@@ -1045,12 +1017,10 @@ void CharacterSegmenter::filterEdgeBoxes(vector<Mat> thresholds, const vector<Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CharacterSegmenter::getLongestBlobLengthBetweenLines(Mat img, int col)
|
int CharacterSegmenter::getLongestBlobLengthBetweenLines(Mat img, int col)
|
||||||
{
|
{
|
||||||
|
|
||||||
int longestBlobLength = 0;
|
int longestBlobLength = 0;
|
||||||
|
|
||||||
bool onSegment = false;
|
bool onSegment = false;
|
||||||
@@ -1093,7 +1063,6 @@ int CharacterSegmenter::getLongestBlobLengthBetweenLines(Mat img, int col)
|
|||||||
isbetweenLines = false;
|
isbetweenLines = false;
|
||||||
curSegmentLength = 0;
|
curSegmentLength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return longestBlobLength;
|
return longestBlobLength;
|
||||||
@@ -1145,7 +1114,6 @@ int CharacterSegmenter::isSkinnyLineInsideBox(Mat threshold, Rect box, vector<ve
|
|||||||
|
|
||||||
if (tallestContourIdx != -1)
|
if (tallestContourIdx != -1)
|
||||||
{
|
{
|
||||||
|
|
||||||
//cout << "Edge Filter: " << tallestContourHeight << " -- " << avgCharHeight << endl;
|
//cout << "Edge Filter: " << tallestContourHeight << " -- " << avgCharHeight << endl;
|
||||||
if (tallestContourHeight >= avgCharHeight * 0.9 &&
|
if (tallestContourHeight >= avgCharHeight * 0.9 &&
|
||||||
((tallestContourWidth < config->segmentationMinBoxWidthPx) || (tallestContourArea < avgCharWidth * avgCharHeight * 0.1)))
|
((tallestContourWidth < config->segmentationMinBoxWidthPx) || (tallestContourArea < avgCharWidth * avgCharHeight * 0.1)))
|
||||||
@@ -1162,7 +1130,6 @@ int CharacterSegmenter::isSkinnyLineInsideBox(Mat threshold, Rect box, vector<ve
|
|||||||
|
|
||||||
Mat CharacterSegmenter::getCharBoxMask(Mat img_threshold, vector<Rect> charBoxes)
|
Mat CharacterSegmenter::getCharBoxMask(Mat img_threshold, vector<Rect> charBoxes)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat mask = Mat::zeros(img_threshold.size(), CV_8U);
|
Mat mask = Mat::zeros(img_threshold.size(), CV_8U);
|
||||||
for (int i = 0; i < charBoxes.size(); i++)
|
for (int i = 0; i < charBoxes.size(); i++)
|
||||||
rectangle(mask, charBoxes[i], Scalar(255, 255, 255), -1);
|
rectangle(mask, charBoxes[i], Scalar(255, 255, 255), -1);
|
||||||
|
@@ -17,8 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CHARACTERSEGMENTER_H
|
#ifndef CHARACTERSEGMENTER_H
|
||||||
#define CHARACTERSEGMENTER_H
|
#define CHARACTERSEGMENTER_H
|
||||||
|
|
||||||
|
@@ -62,7 +62,6 @@ typedef struct cJSON_Hooks
|
|||||||
/* Supply malloc, realloc and free functions to cJSON */
|
/* Supply malloc, realloc and free functions to cJSON */
|
||||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||||
|
|
||||||
|
|
||||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||||
extern cJSON *cJSON_Parse(const char *value);
|
extern cJSON *cJSON_Parse(const char *value);
|
||||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
ColorFilter::ColorFilter(Mat image, Mat characterMask, Config* config)
|
ColorFilter::ColorFilter(Mat image, Mat characterMask, Config* config)
|
||||||
{
|
{
|
||||||
|
|
||||||
timespec startTime;
|
timespec startTime;
|
||||||
getTime(&startTime);
|
getTime(&startTime);
|
||||||
|
|
||||||
@@ -54,7 +53,6 @@ ColorFilter::ColorFilter(Mat image, Mat characterMask, Config* config)
|
|||||||
|
|
||||||
ColorFilter::~ColorFilter()
|
ColorFilter::~ColorFilter()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ColorFilter::imageIsGrayscale(Mat image)
|
bool ColorFilter::imageIsGrayscale(Mat image)
|
||||||
@@ -163,7 +161,6 @@ void ColorFilter::findCharColors()
|
|||||||
hStdDevs.push_back(stddev[0]);
|
hStdDevs.push_back(stddev[0]);
|
||||||
sStdDevs.push_back(stddev[1]);
|
sStdDevs.push_back(stddev[1]);
|
||||||
vStdDevs.push_back(stddev[2]);
|
vStdDevs.push_back(stddev[2]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hMeans.size() == 0)
|
if (hMeans.size() == 0)
|
||||||
@@ -362,7 +359,6 @@ void ColorFilter::findCharColors()
|
|||||||
Mat dashboard = drawImageDashboard(debugImagesSet, imgDebugHueOnly.type(), 3);
|
Mat dashboard = drawImageDashboard(debugImagesSet, imgDebugHueOnly.type(), 3);
|
||||||
displayImage(config, "Color Filter Images", dashboard);
|
displayImage(config, "Color Filter Images", dashboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Goes through an array of values, picks the winner based on the highest percentage of other values that are within the maxValDifference
|
// Goes through an array of values, picks the winner based on the highest percentage of other values that are within the maxValDifference
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef COLORFILTER_H
|
#ifndef COLORFILTER_H
|
||||||
#define COLORFILTER_H
|
#define COLORFILTER_H
|
||||||
|
|
||||||
@@ -31,8 +30,6 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ColorFilter
|
class ColorFilter
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -42,8 +39,6 @@ class ColorFilter
|
|||||||
|
|
||||||
Mat colorMask;
|
Mat colorMask;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Config* config;
|
Config* config;
|
||||||
@@ -52,7 +47,6 @@ class ColorFilter
|
|||||||
Mat hsv;
|
Mat hsv;
|
||||||
Mat charMask;
|
Mat charMask;
|
||||||
|
|
||||||
|
|
||||||
bool grayscale;
|
bool grayscale;
|
||||||
|
|
||||||
void preprocessImage();
|
void preprocessImage();
|
||||||
|
@@ -30,7 +30,6 @@ Config::Config(const std::string country, const std::string runtimeBaseDir)
|
|||||||
if (runtimeBaseDir.compare("") != 0)
|
if (runtimeBaseDir.compare("") != 0)
|
||||||
{
|
{
|
||||||
// User has supplied a runtime directory. Use that.
|
// User has supplied a runtime directory. Use that.
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (envRuntimeDir!=NULL)
|
else if (envRuntimeDir!=NULL)
|
||||||
{
|
{
|
||||||
@@ -69,7 +68,6 @@ Config::~Config()
|
|||||||
|
|
||||||
void Config::loadValues(string country)
|
void Config::loadValues(string country)
|
||||||
{
|
{
|
||||||
|
|
||||||
opencl_enabled = getBoolean("common", "opencl_enabled", false);
|
opencl_enabled = getBoolean("common", "opencl_enabled", false);
|
||||||
maxPlateWidthPercent = getFloat("common", "max_plate_width_percent", 100);
|
maxPlateWidthPercent = getFloat("common", "max_plate_width_percent", 100);
|
||||||
maxPlateHeightPercent = getFloat("common", "max_plate_height_percent", 100);
|
maxPlateHeightPercent = getFloat("common", "max_plate_height_percent", 100);
|
||||||
@@ -129,7 +127,6 @@ void Config::loadValues(string country)
|
|||||||
debugOcr = getBoolean("debug", "ocr", false);
|
debugOcr = getBoolean("debug", "ocr", false);
|
||||||
debugPostProcess = getBoolean("debug", "postprocess", false);
|
debugPostProcess = getBoolean("debug", "postprocess", false);
|
||||||
debugShowImages = getBoolean("debug", "show_images", false);
|
debugShowImages = getBoolean("debug", "show_images", false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::debugOff()
|
void Config::debugOff()
|
||||||
|
@@ -17,11 +17,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
|
|
||||||
#include "simpleini/simpleini.h"
|
#include "simpleini/simpleini.h"
|
||||||
#include "support/filesystem.h"
|
#include "support/filesystem.h"
|
||||||
|
|
||||||
@@ -89,7 +87,6 @@ class Config
|
|||||||
int postProcessMinCharacters;
|
int postProcessMinCharacters;
|
||||||
int postProcessMaxCharacters;
|
int postProcessMaxCharacters;
|
||||||
|
|
||||||
|
|
||||||
bool debugGeneral;
|
bool debugGeneral;
|
||||||
bool debugTiming;
|
bool debugTiming;
|
||||||
bool debugStateId;
|
bool debugStateId;
|
||||||
@@ -123,5 +120,4 @@ class Config
|
|||||||
bool getBoolean(string section, string key, bool defaultValue);
|
bool getBoolean(string section, string key, bool defaultValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
@@ -45,7 +45,6 @@ FeatureMatcher::~FeatureMatcher()
|
|||||||
descriptorMatcher.release();
|
descriptorMatcher.release();
|
||||||
detector.release();
|
detector.release();
|
||||||
extractor.release();
|
extractor.release();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeatureMatcher::isLoaded()
|
bool FeatureMatcher::isLoaded()
|
||||||
@@ -78,7 +77,6 @@ void FeatureMatcher::surfStyleMatching( const Mat& queryDescriptors, vector<KeyP
|
|||||||
|
|
||||||
void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vector<DMatch> > matchesKnn, vector<DMatch>& matches12)
|
void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vector<DMatch> > matchesKnn, vector<DMatch>& matches12)
|
||||||
{
|
{
|
||||||
|
|
||||||
//objectMatches.clear();
|
//objectMatches.clear();
|
||||||
//objectMatches.resize(objectIds.size());
|
//objectMatches.resize(objectIds.size());
|
||||||
//cout << "starting matcher" << matchesKnn.size() << endl;
|
//cout << "starting matcher" << matchesKnn.size() << endl;
|
||||||
@@ -90,7 +88,6 @@ void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vect
|
|||||||
// Check to make sure we have 2 matches. I think this is always the case, but it doesn't hurt to be sure
|
// Check to make sure we have 2 matches. I think this is always the case, but it doesn't hurt to be sure
|
||||||
if (matchesKnn[descInd].size() > 1)
|
if (matchesKnn[descInd].size() > 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Next throw out matches with a crappy score
|
// Next throw out matches with a crappy score
|
||||||
// Ignore... already handled by the radiusMatch
|
// Ignore... already handled by the radiusMatch
|
||||||
//if (matchesKnn[descInd][0].distance < MAX_DISTANCE_TO_MATCH)
|
//if (matchesKnn[descInd][0].distance < MAX_DISTANCE_TO_MATCH)
|
||||||
@@ -140,19 +137,15 @@ void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vect
|
|||||||
|
|
||||||
//for (unsigned int first_index = 0; first_index < matches.size(); ++first_index)
|
//for (unsigned int first_index = 0; first_index < matches.size(); ++first_index)
|
||||||
//{
|
//{
|
||||||
|
|
||||||
//matches12.push_back(match);
|
//matches12.push_back(match);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compares the matches keypoints for parallel lines. Removes matches that are criss-crossing too much
|
// Compares the matches keypoints for parallel lines. Removes matches that are criss-crossing too much
|
||||||
// We assume that license plates won't be upside-down or backwards. So expect lines to be closely parallel
|
// We assume that license plates won't be upside-down or backwards. So expect lines to be closely parallel
|
||||||
void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches)
|
void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches)
|
||||||
{
|
{
|
||||||
|
|
||||||
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
|
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
|
||||||
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
|
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
|
||||||
|
|
||||||
@@ -222,7 +215,6 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
|
|||||||
hlines.erase(hlines.begin() + mostIntersectionsIndex);
|
hlines.erase(hlines.begin() + mostIntersectionsIndex);
|
||||||
matchIdx.erase(matchIdx.begin() + mostIntersectionsIndex);
|
matchIdx.erase(matchIdx.begin() + mostIntersectionsIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the non-crisscrosses back on the list
|
// Push the non-crisscrosses back on the list
|
||||||
@@ -231,7 +223,6 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
|
|||||||
outputMatches.push_back(matchesForOnePlate[matchIdx[j]]);
|
outputMatches.push_back(matchesForOnePlate[matchIdx[j]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if successful, false otherwise
|
// Returns true if successful, false otherwise
|
||||||
@@ -276,7 +267,6 @@ bool FeatureMatcher::loadRecognitionSet(string country)
|
|||||||
trainImages.push_back(descriptors);
|
trainImages.push_back(descriptors);
|
||||||
trainingImgKeypoints.push_back(keypoints);
|
trainingImgKeypoints.push_back(keypoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->descriptorMatcher->add(trainImages);
|
this->descriptorMatcher->add(trainImages);
|
||||||
@@ -286,7 +276,6 @@ bool FeatureMatcher::loadRecognitionSet(string country)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnImage, Mat* outputImage,
|
RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnImage, Mat* outputImage,
|
||||||
@@ -376,7 +365,6 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
|
|||||||
|
|
||||||
if (result.haswinner == true)
|
if (result.haswinner == true)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << result.winner << " (" << result.confidence << "%)";
|
out << result.winner << " (" << result.confidence << "%)";
|
||||||
|
|
||||||
@@ -384,19 +372,15 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
|
|||||||
//putText(*outputImage, out.str(), Point(15, 27), FONT_HERSHEY_DUPLEX, 1.1, CV_RGB(0, 0, 0), 2);
|
//putText(*outputImage, out.str(), Point(15, 27), FONT_HERSHEY_DUPLEX, 1.1, CV_RGB(0, 0, 0), 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->config->debugStateId)
|
if (this->config->debugStateId)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int i = 0; i < billMapping.size(); i++)
|
for (int i = 0; i < billMapping.size(); i++)
|
||||||
{
|
{
|
||||||
cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
|
cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef FEATUREMATCHER_H
|
#ifndef FEATUREMATCHER_H
|
||||||
#define FEATUREMATCHER_H
|
#define FEATUREMATCHER_H
|
||||||
|
|
||||||
@@ -36,8 +33,6 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct RecognitionResult
|
struct RecognitionResult
|
||||||
{
|
{
|
||||||
bool haswinner;
|
bool haswinner;
|
||||||
@@ -52,12 +47,9 @@ class FeatureMatcher
|
|||||||
FeatureMatcher(Config* config);
|
FeatureMatcher(Config* config);
|
||||||
virtual ~FeatureMatcher();
|
virtual ~FeatureMatcher();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RecognitionResult recognize( const Mat& queryImg, bool drawOnImage, Mat* outputImage,
|
RecognitionResult recognize( const Mat& queryImg, bool drawOnImage, Mat* outputImage,
|
||||||
bool debug_on, vector<int> debug_matches_array );
|
bool debug_on, vector<int> debug_matches_array );
|
||||||
|
|
||||||
|
|
||||||
bool loadRecognitionSet(string country);
|
bool loadRecognitionSet(string country);
|
||||||
|
|
||||||
bool isLoaded();
|
bool isLoaded();
|
||||||
@@ -71,18 +63,14 @@ class FeatureMatcher
|
|||||||
Ptr<FastFeatureDetector> detector;
|
Ptr<FastFeatureDetector> detector;
|
||||||
Ptr<BRISK> extractor;
|
Ptr<BRISK> extractor;
|
||||||
|
|
||||||
|
|
||||||
vector<vector<KeyPoint> > trainingImgKeypoints;
|
vector<vector<KeyPoint> > trainingImgKeypoints;
|
||||||
|
|
||||||
|
|
||||||
void _surfStyleMatching(const Mat& queryDescriptors, vector<vector<DMatch> > matchesKnn, vector<DMatch>& matches12);
|
void _surfStyleMatching(const Mat& queryDescriptors, vector<vector<DMatch> > matchesKnn, vector<DMatch>& matches12);
|
||||||
|
|
||||||
void crisscrossFiltering(const vector<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches);
|
void crisscrossFiltering(const vector<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches);
|
||||||
|
|
||||||
vector<string> billMapping;
|
vector<string> billMapping;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void surfStyleMatching( const Mat& queryDescriptors, vector<KeyPoint> queryKeypoints,
|
void surfStyleMatching( const Mat& queryDescriptors, vector<KeyPoint> queryKeypoints,
|
||||||
vector<DMatch>& matches12 );
|
vector<DMatch>& matches12 );
|
||||||
|
|
||||||
|
@@ -54,7 +54,6 @@ void LicensePlateCandidate::recognize()
|
|||||||
|
|
||||||
if (charRegion.confidence > 10)
|
if (charRegion.confidence > 10)
|
||||||
{
|
{
|
||||||
|
|
||||||
PlateLines plateLines(config);
|
PlateLines plateLines(config);
|
||||||
//Mat boogedy = charRegion.getPlateMask();
|
//Mat boogedy = charRegion.getPlateMask();
|
||||||
|
|
||||||
@@ -76,11 +75,9 @@ void LicensePlateCandidate::recognize()
|
|||||||
//strcpy(this->recognizedText, ocr.recognizedText);
|
//strcpy(this->recognizedText, ocr.recognizedText);
|
||||||
|
|
||||||
this->confidence = 100;
|
this->confidence = 100;
|
||||||
|
|
||||||
}
|
}
|
||||||
charRegion.confidence = 0;
|
charRegion.confidence = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-maps the coordinates from the smallImage to the coordinate space of the bigImage.
|
// Re-maps the coordinates from the smallImage to the coordinate space of the bigImage.
|
||||||
@@ -103,7 +100,6 @@ vector<Point2f> LicensePlateCandidate::transformPointsToOriginalImage(Mat bigIma
|
|||||||
|
|
||||||
Mat LicensePlateCandidate::deSkewPlate(Mat inputImage, vector<Point2f> corners)
|
Mat LicensePlateCandidate::deSkewPlate(Mat inputImage, vector<Point2f> corners)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Figure out the appoximate width/height of the license plate region, so we can maintain the aspect ratio.
|
// Figure out the appoximate width/height of the license plate region, so we can maintain the aspect ratio.
|
||||||
LineSegment leftEdge(round(corners[3].x), round(corners[3].y), round(corners[0].x), round(corners[0].y));
|
LineSegment leftEdge(round(corners[3].x), round(corners[3].y), round(corners[0].x), round(corners[0].y));
|
||||||
LineSegment rightEdge(round(corners[2].x), round(corners[2].y), round(corners[1].x), round(corners[1].y));
|
LineSegment rightEdge(round(corners[2].x), round(corners[2].y), round(corners[1].x), round(corners[1].y));
|
||||||
@@ -179,5 +175,4 @@ void LicensePlateCandidate::cleanupColors(Mat inputImage, Mat outputImage)
|
|||||||
{
|
{
|
||||||
displayImage(config, "After cleanup", outputImage);
|
displayImage(config, "After cleanup", outputImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef STAGE2_H
|
#ifndef STAGE2_H
|
||||||
#define STAGE2_H
|
#define STAGE2_H
|
||||||
|
|
||||||
@@ -39,8 +38,6 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//vector<Rect> getCharacterRegions(Mat frame, vector<Rect> regionsOfInterest);
|
//vector<Rect> getCharacterRegions(Mat frame, vector<Rect> regionsOfInterest);
|
||||||
//vector<RotatedRect> getCharSegmentsBetweenLines(Mat img, vector<vector<Point> > contours, LineSegment top, LineSegment bottom);
|
//vector<RotatedRect> getCharSegmentsBetweenLines(Mat img, vector<vector<Point> > contours, LineSegment top, LineSegment bottom);
|
||||||
|
|
||||||
@@ -64,7 +61,6 @@ class LicensePlateCandidate
|
|||||||
|
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
|
|
||||||
Mat frame;
|
Mat frame;
|
||||||
Rect plateRegion;
|
Rect plateRegion;
|
||||||
|
|
||||||
@@ -77,5 +73,4 @@ class LicensePlateCandidate
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // STAGE2_H
|
#endif // STAGE2_H
|
||||||
|
@@ -48,7 +48,6 @@ OCR::~OCR()
|
|||||||
|
|
||||||
void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
|
void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
|
||||||
{
|
{
|
||||||
|
|
||||||
timespec startTime;
|
timespec startTime;
|
||||||
getTime(&startTime);
|
getTime(&startTime);
|
||||||
|
|
||||||
@@ -56,7 +55,6 @@ void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
|
|||||||
|
|
||||||
for (int i = 0; i < thresholds.size(); i++)
|
for (int i = 0; i < thresholds.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Make it black text on white background
|
// Make it black text on white background
|
||||||
bitwise_not(thresholds[i], thresholds[i]);
|
bitwise_not(thresholds[i], thresholds[i]);
|
||||||
tesseract->SetImage((uchar*) thresholds[i].data, thresholds[i].size().width, thresholds[i].size().height, thresholds[i].channels(), thresholds[i].step1());
|
tesseract->SetImage((uchar*) thresholds[i].data, thresholds[i].size().width, thresholds[i].size().height, thresholds[i].channels(), thresholds[i].step1());
|
||||||
@@ -117,7 +115,6 @@ void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
|
|||||||
|
|
||||||
delete ri;
|
delete ri;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->debugTiming)
|
if (config->debugTiming)
|
||||||
@@ -126,5 +123,4 @@ void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
|
|||||||
getTime(&endTime);
|
getTime(&endTime);
|
||||||
cout << "OCR Time: " << diffclock(startTime, endTime) << "ms." << endl;
|
cout << "OCR Time: " << diffclock(startTime, endTime) << "ms." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef OCR_H
|
#ifndef OCR_H
|
||||||
#define OCR_H
|
#define OCR_H
|
||||||
|
|
||||||
@@ -38,7 +35,6 @@ using namespace tesseract;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
|
||||||
class OCR
|
class OCR
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -53,16 +49,11 @@ class OCR
|
|||||||
//float confidence;
|
//float confidence;
|
||||||
//float overallConfidence;
|
//float overallConfidence;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
TessBaseAPI *tesseract;
|
TessBaseAPI *tesseract;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // OCR_H
|
#endif // OCR_H
|
||||||
|
@@ -47,7 +47,6 @@ PlateCorners::PlateCorners(Mat inputImage, PlateLines* plateLines, CharacterRegi
|
|||||||
|
|
||||||
PlateCorners::~PlateCorners()
|
PlateCorners::~PlateCorners()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Point> PlateCorners::findPlateCorners()
|
vector<Point> PlateCorners::findPlateCorners()
|
||||||
@@ -69,7 +68,6 @@ vector<Point> PlateCorners::findPlateCorners()
|
|||||||
if (h1 == h2 && h1 != NO_LINE) continue;
|
if (h1 == h2 && h1 != NO_LINE) continue;
|
||||||
|
|
||||||
this->scoreHorizontals(h1, h2);
|
this->scoreHorizontals(h1, h2);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +84,6 @@ vector<Point> PlateCorners::findPlateCorners()
|
|||||||
|
|
||||||
if (this->config->debugPlateCorners)
|
if (this->config->debugPlateCorners)
|
||||||
{
|
{
|
||||||
|
|
||||||
cout << "Drawing debug stuff..." << endl;
|
cout << "Drawing debug stuff..." << endl;
|
||||||
|
|
||||||
Mat imgCorners = Mat(inputImage.size(), inputImage.type());
|
Mat imgCorners = Mat(inputImage.size(), inputImage.type());
|
||||||
@@ -100,7 +97,6 @@ vector<Point> PlateCorners::findPlateCorners()
|
|||||||
line(imgCorners, this->bestLeft.p1, this->bestLeft.p2, Scalar(255, 0, 0), 1, CV_AA);
|
line(imgCorners, this->bestLeft.p1, this->bestLeft.p2, Scalar(255, 0, 0), 1, CV_AA);
|
||||||
|
|
||||||
displayImage(config, "Winning top/bottom Boundaries", imgCorners);
|
displayImage(config, "Winning top/bottom Boundaries", imgCorners);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a left/right edge has been established.
|
// Check if a left/right edge has been established.
|
||||||
@@ -129,7 +125,6 @@ vector<Point> PlateCorners::findPlateCorners()
|
|||||||
|
|
||||||
void PlateCorners::scoreVerticals(int v1, int v2)
|
void PlateCorners::scoreVerticals(int v1, int v2)
|
||||||
{
|
{
|
||||||
|
|
||||||
float score = 0; // Lower is better
|
float score = 0; // Lower is better
|
||||||
|
|
||||||
LineSegment left;
|
LineSegment left;
|
||||||
@@ -237,13 +232,11 @@ void PlateCorners::scoreVerticals(int v1, int v2)
|
|||||||
bestLeft = LineSegment(left.p1.x, left.p1.y, left.p2.x, left.p2.y);
|
bestLeft = LineSegment(left.p1.x, left.p1.y, left.p2.x, left.p2.y);
|
||||||
bestRight = LineSegment(right.p1.x, right.p1.y, right.p2.x, right.p2.y);
|
bestRight = LineSegment(right.p1.x, right.p1.y, right.p2.x, right.p2.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Score a collection of lines as a possible license plate region.
|
// Score a collection of lines as a possible license plate region.
|
||||||
// If any segments are missing, extrapolate the missing pieces
|
// If any segments are missing, extrapolate the missing pieces
|
||||||
void PlateCorners::scoreHorizontals(int h1, int h2)
|
void PlateCorners::scoreHorizontals(int h1, int h2)
|
||||||
{
|
{
|
||||||
|
|
||||||
//if (this->debug)
|
//if (this->debug)
|
||||||
// cout << "PlateCorners::scorePlate" << endl;
|
// cout << "PlateCorners::scorePlate" << endl;
|
||||||
|
|
||||||
@@ -400,5 +393,4 @@ void PlateCorners::scoreHorizontals(int h1, int h2)
|
|||||||
bestTop = LineSegment(top.p1.x, top.p1.y, top.p2.x, top.p2.y);
|
bestTop = LineSegment(top.p1.x, top.p1.y, top.p2.x, top.p2.y);
|
||||||
bestBottom = LineSegment(bottom.p1.x, bottom.p1.y, bottom.p2.x, bottom.p2.y);
|
bestBottom = LineSegment(bottom.p1.x, bottom.p1.y, bottom.p2.x, bottom.p2.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef PLATECORNERS_H
|
#ifndef PLATECORNERS_H
|
||||||
#define PLATECORNERS_H
|
#define PLATECORNERS_H
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ using namespace std;
|
|||||||
|
|
||||||
#define NO_LINE -1
|
#define NO_LINE -1
|
||||||
|
|
||||||
|
|
||||||
#define SCORING_MISSING_SEGMENT_PENALTY_VERTICAL 10
|
#define SCORING_MISSING_SEGMENT_PENALTY_VERTICAL 10
|
||||||
#define SCORING_MISSING_SEGMENT_PENALTY_HORIZONTAL 15
|
#define SCORING_MISSING_SEGMENT_PENALTY_HORIZONTAL 15
|
||||||
|
|
||||||
|
@@ -26,12 +26,10 @@ PlateLines::PlateLines(Config* config)
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
cout << "PlateLines constructor" << endl;
|
cout << "PlateLines constructor" << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlateLines::~PlateLines()
|
PlateLines::~PlateLines()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlateLines::processImage(Mat inputImage, float sensitivity)
|
void PlateLines::processImage(Mat inputImage, float sensitivity)
|
||||||
@@ -150,13 +148,11 @@ void PlateLines::processImage(Mat inputImage, float sensitivity)
|
|||||||
//minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
|
//minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
|
vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<LineSegment> filteredLines;
|
vector<LineSegment> filteredLines;
|
||||||
|
|
||||||
int sensitivity;
|
int sensitivity;
|
||||||
@@ -169,7 +165,6 @@ vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
|
|||||||
|
|
||||||
for( size_t i = 0; i < lsegs.size(); i++ )
|
for( size_t i = 0; i < lsegs.size(); i++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
if (vertical)
|
if (vertical)
|
||||||
{
|
{
|
||||||
LineSegment candidate;
|
LineSegment candidate;
|
||||||
@@ -213,7 +208,6 @@ vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
|
|||||||
|
|
||||||
for( size_t i = 0; i < filteredLines.size(); i++ )
|
for( size_t i = 0; i < filteredLines.size(); i++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
line( debugImg, filteredLines[i].p1, filteredLines[i].p2, Scalar(0,0,255), 1, CV_AA);
|
line( debugImg, filteredLines[i].p1, filteredLines[i].p2, Scalar(0,0,255), 1, CV_AA);
|
||||||
}
|
}
|
||||||
if (vertical)
|
if (vertical)
|
||||||
@@ -281,7 +275,6 @@ vector<LineSegment> PlateLines::getLines(Mat edges, float sensitivityMultiplier,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( (angle > 70 && angle < 110) || (angle > 250 && angle < 290))
|
if ( (angle > 70 && angle < 110) || (angle > 250 && angle < 290))
|
||||||
{
|
{
|
||||||
// good horizontal
|
// good horizontal
|
||||||
|
@@ -17,8 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PLATELINES_H
|
#ifndef PLATELINES_H
|
||||||
#define PLATELINES_H
|
#define PLATELINES_H
|
||||||
|
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
class PlateLines
|
class PlateLines
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -50,7 +47,6 @@ class PlateLines
|
|||||||
Config* config;
|
Config* config;
|
||||||
bool debug;
|
bool debug;
|
||||||
|
|
||||||
|
|
||||||
Mat customGrayscaleConversion(Mat src);
|
Mat customGrayscaleConversion(Mat src);
|
||||||
void findLines(Mat inputImage);
|
void findLines(Mat inputImage);
|
||||||
vector<LineSegment> getLines(Mat edges, float sensitivityMultiplier, bool vertical);
|
vector<LineSegment> getLines(Mat edges, float sensitivityMultiplier, bool vertical);
|
||||||
|
@@ -51,7 +51,6 @@ PostProcess::PostProcess(Config* config)
|
|||||||
//vector<RegexRule> test = rules["base"];
|
//vector<RegexRule> test = rules["base"];
|
||||||
//for (int i = 0; i < test.size(); i++)
|
//for (int i = 0; i < test.size(); i++)
|
||||||
// cout << "Rule: " << test[i].regex << endl;
|
// cout << "Rule: " << test[i].regex << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostProcess::~PostProcess()
|
PostProcess::~PostProcess()
|
||||||
@@ -65,7 +64,6 @@ PostProcess::~PostProcess()
|
|||||||
{
|
{
|
||||||
delete iter->second[i];
|
delete iter->second[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,12 +84,10 @@ void PostProcess::addLetter(char letter, int charposition, float score)
|
|||||||
//{
|
//{
|
||||||
// insertLetter('O', charposition, score - 0.5);
|
// insertLetter('O', charposition, score - 0.5);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostProcess::insertLetter(char letter, int charposition, float score)
|
void PostProcess::insertLetter(char letter, int charposition, float score)
|
||||||
{
|
{
|
||||||
|
|
||||||
score = score - config->postProcessMinConfidence;
|
score = score - config->postProcessMinConfidence;
|
||||||
|
|
||||||
int existingIndex = -1;
|
int existingIndex = -1;
|
||||||
@@ -128,7 +124,6 @@ void PostProcess::insertLetter(char letter, int charposition, float score)
|
|||||||
letters[charposition][existingIndex].occurences = letters[charposition][existingIndex].occurences + 1;
|
letters[charposition][existingIndex].occurences = letters[charposition][existingIndex].occurences + 1;
|
||||||
letters[charposition][existingIndex].totalscore = letters[charposition][existingIndex].totalscore + score;
|
letters[charposition][existingIndex].totalscore = letters[charposition][existingIndex].totalscore + score;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostProcess::clear()
|
void PostProcess::clear()
|
||||||
@@ -149,7 +144,6 @@ void PostProcess::clear()
|
|||||||
}
|
}
|
||||||
void PostProcess::analyze(string templateregion, int topn)
|
void PostProcess::analyze(string templateregion, int topn)
|
||||||
{
|
{
|
||||||
|
|
||||||
timespec startTime;
|
timespec startTime;
|
||||||
getTime(&startTime);
|
getTime(&startTime);
|
||||||
|
|
||||||
@@ -174,14 +168,12 @@ void PostProcess::analyze(string templateregion, int topn)
|
|||||||
|
|
||||||
if (this->config->debugPostProcess)
|
if (this->config->debugPostProcess)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Print all letters
|
// Print all letters
|
||||||
for (int i = 0; i < letters.size(); i++)
|
for (int i = 0; i < letters.size(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < letters[i].size(); j++)
|
for (int j = 0; j < letters[i].size(); j++)
|
||||||
cout << "PostProcess Letter: " << letters[i][j].charposition << " " << letters[i][j].letter << " -- score: " << letters[i][j].totalscore << " -- occurences: " << letters[i][j].occurences << endl;
|
cout << "PostProcess Letter: " << letters[i][j].charposition << " " << letters[i][j].letter << " -- score: " << letters[i][j].totalscore << " -- occurences: " << letters[i][j].occurences << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prune the letters based on the topN value.
|
// Prune the letters based on the topN value.
|
||||||
@@ -270,12 +262,10 @@ void PostProcess::analyze(string templateregion, int topn)
|
|||||||
{
|
{
|
||||||
allPossibilities[i].totalscore = maxPercentScore * (allPossibilities[i].totalscore / highestRelativeScore);
|
allPossibilities[i].totalscore = maxPercentScore * (allPossibilities[i].totalscore / highestRelativeScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->config->debugPostProcess)
|
if (this->config->debugPostProcess)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Print top words
|
// Print top words
|
||||||
for (int i = 0; i < allPossibilities.size(); i++)
|
for (int i = 0; i < allPossibilities.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -335,7 +325,6 @@ float PostProcess::calculateMaxConfidenceScore()
|
|||||||
// Y-95 Z-90
|
// Y-95 Z-90
|
||||||
vector<int> PostProcess::getMaxDepth(int topn)
|
vector<int> PostProcess::getMaxDepth(int topn)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector<int> depth;
|
vector<int> depth;
|
||||||
for (int i = 0; i < letters.size(); i++)
|
for (int i = 0; i < letters.size(); i++)
|
||||||
depth.push_back(0);
|
depth.push_back(0);
|
||||||
@@ -394,14 +383,12 @@ const vector<PPResult> PostProcess::getResults()
|
|||||||
|
|
||||||
void PostProcess::findAllPermutations(vector<Letter> prevletters, int charPos, int substitutionsLeft)
|
void PostProcess::findAllPermutations(vector<Letter> prevletters, int charPos, int substitutionsLeft)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (substitutionsLeft < 0)
|
if (substitutionsLeft < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Add my letter to the chain and recurse
|
// Add my letter to the chain and recurse
|
||||||
for (int i = 0; i < letters[charPos].size(); i++)
|
for (int i = 0; i < letters[charPos].size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (charPos == letters.size() - 1)
|
if (charPos == letters.size() - 1)
|
||||||
{
|
{
|
||||||
// Last letter, add the word
|
// Last letter, add the word
|
||||||
@@ -442,7 +429,6 @@ void PostProcess::findAllPermutations(vector<Letter> prevletters, int charPos, i
|
|||||||
// Just pass it along
|
// Just pass it along
|
||||||
findAllPermutations(prevletters, charPos + 1, substitutionsLeft);
|
findAllPermutations(prevletters, charPos + 1, substitutionsLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wordCompare( const PPResult &left, const PPResult &right )
|
bool wordCompare( const PPResult &left, const PPResult &right )
|
||||||
@@ -450,7 +436,6 @@ bool wordCompare( const PPResult &left, const PPResult &right )
|
|||||||
if (left.totalscore < right.totalscore)
|
if (left.totalscore < right.totalscore)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool letterCompare( const Letter &left, const Letter &right )
|
bool letterCompare( const Letter &left, const Letter &right )
|
||||||
@@ -476,7 +461,6 @@ RegexRule::RegexRule(string region, string pattern)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
this->regex = this->regex + ']';
|
this->regex = this->regex + ']';
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (pattern.at(i) == '?')
|
else if (pattern.at(i) == '?')
|
||||||
{
|
{
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef POSTPROCESS_H
|
#ifndef POSTPROCESS_H
|
||||||
#define POSTPROCESS_H
|
#define POSTPROCESS_H
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
#define SKIP_CHAR '~'
|
#define SKIP_CHAR '~'
|
||||||
|
|
||||||
struct Letter
|
struct Letter
|
||||||
@@ -50,17 +48,14 @@ struct PPResult
|
|||||||
bool matchesTemplate;
|
bool matchesTemplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool wordCompare( const PPResult &left, const PPResult &right );
|
bool wordCompare( const PPResult &left, const PPResult &right );
|
||||||
bool letterCompare( const Letter &left, const Letter &right );
|
bool letterCompare( const Letter &left, const Letter &right );
|
||||||
|
|
||||||
|
|
||||||
class RegexRule
|
class RegexRule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RegexRule(string region, string pattern);
|
RegexRule(string region, string pattern);
|
||||||
|
|
||||||
|
|
||||||
bool match(string text);
|
bool match(string text);
|
||||||
string filterSkips(string text);
|
string filterSkips(string text);
|
||||||
|
|
||||||
@@ -73,7 +68,6 @@ class RegexRule
|
|||||||
vector<int> skipPositions;
|
vector<int> skipPositions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PostProcess
|
class PostProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -104,7 +98,6 @@ class PostProcess
|
|||||||
vector<vector<Letter> > letters;
|
vector<vector<Letter> > letters;
|
||||||
vector<int> unknownCharPositions;
|
vector<int> unknownCharPositions;
|
||||||
|
|
||||||
|
|
||||||
vector<PPResult> allPossibilities;
|
vector<PPResult> allPossibilities;
|
||||||
|
|
||||||
// Functions used to prune the list of letters (based on topn) to improve performance
|
// Functions used to prune the list of letters (based on topn) to improve performance
|
||||||
|
@@ -44,7 +44,6 @@ RegionDetector::RegionDetector(Config* config)
|
|||||||
this->loaded = false;
|
this->loaded = false;
|
||||||
printf("--(!)Error loading classifier\n");
|
printf("--(!)Error loading classifier\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionDetector::~RegionDetector()
|
RegionDetector::~RegionDetector()
|
||||||
@@ -59,7 +58,6 @@ bool RegionDetector::isLoaded()
|
|||||||
|
|
||||||
vector<Rect> RegionDetector::detect(Mat frame)
|
vector<Rect> RegionDetector::detect(Mat frame)
|
||||||
{
|
{
|
||||||
|
|
||||||
Mat frame_gray;
|
Mat frame_gray;
|
||||||
cvtColor( frame, frame_gray, CV_BGR2GRAY );
|
cvtColor( frame, frame_gray, CV_BGR2GRAY );
|
||||||
|
|
||||||
@@ -94,7 +92,6 @@ vector<Rect> RegionDetector::doCascade(Mat frame)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
plate_cascade->detectMultiScale( frame, plates, 1.1, 3,
|
plate_cascade->detectMultiScale( frame, plates, 1.1, 3,
|
||||||
0,
|
0,
|
||||||
//0|CV_HAAR_SCALE_IMAGE,
|
//0|CV_HAAR_SCALE_IMAGE,
|
||||||
@@ -117,5 +114,4 @@ vector<Rect> RegionDetector::doCascade(Mat frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return plates;
|
return plates;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef REGIONDETECTOR_H
|
#ifndef REGIONDETECTOR_H
|
||||||
#define REGIONDETECTOR_H
|
#define REGIONDETECTOR_H
|
||||||
|
|
||||||
@@ -36,10 +33,6 @@
|
|||||||
#include "support/timing.h"
|
#include "support/timing.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RegionDetector
|
class RegionDetector
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -62,7 +55,4 @@ class RegionDetector
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // REGIONDETECTOR_H
|
#endif // REGIONDETECTOR_H
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
Windows and Linux/Unix. It is fast, simple and source code using this
|
Windows and Linux/Unix. It is fast, simple and source code using this
|
||||||
component will compile unchanged on either OS.
|
component will compile unchanged on either OS.
|
||||||
|
|
||||||
|
|
||||||
@section features FEATURES
|
@section features FEATURES
|
||||||
|
|
||||||
- MIT Licence allows free use in all software (including GPL and commercial)
|
- MIT Licence allows free use in all software (including GPL and commercial)
|
||||||
@@ -44,7 +43,6 @@
|
|||||||
- Windows/VC 2005 (warning level 4)
|
- Windows/VC 2005 (warning level 4)
|
||||||
- Linux/gcc (-Wall)
|
- Linux/gcc (-Wall)
|
||||||
|
|
||||||
|
|
||||||
@section usage USAGE SUMMARY
|
@section usage USAGE SUMMARY
|
||||||
|
|
||||||
-# Define the appropriate symbol for the converter you wish to use and
|
-# Define the appropriate symbol for the converter you wish to use and
|
||||||
@@ -267,7 +265,6 @@ enum SI_Error
|
|||||||
# define SI_WCHAR_T UChar
|
# define SI_WCHAR_T UChar
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// MAIN TEMPLATE CLASS
|
// MAIN TEMPLATE CLASS
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -1226,7 +1223,6 @@ class CSimpleIniTempl
|
|||||||
return (ch == ';' || ch == '#');
|
return (ch == ';' || ch == '#');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Skip over a newline character (or characters) for either DOS or UNIX */
|
/** Skip over a newline character (or characters) for either DOS or UNIX */
|
||||||
inline void SkipNewLine(SI_CHAR *& a_pData) const
|
inline void SkipNewLine(SI_CHAR *& a_pData) const
|
||||||
{
|
{
|
||||||
@@ -2881,7 +2877,6 @@ class SI_ConvertA
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// SI_CONVERT_GENERIC
|
// SI_CONVERT_GENERIC
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -3103,7 +3098,6 @@ class SI_ConvertW
|
|||||||
|
|
||||||
#endif // SI_CONVERT_GENERIC
|
#endif // SI_CONVERT_GENERIC
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// SI_CONVERT_ICU
|
// SI_CONVERT_ICU
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -3299,7 +3293,6 @@ class SI_ConvertW
|
|||||||
|
|
||||||
#endif // SI_CONVERT_ICU
|
#endif // SI_CONVERT_ICU
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// SI_CONVERT_WIN32
|
// SI_CONVERT_WIN32
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -3475,7 +3468,6 @@ class SI_ConvertW
|
|||||||
|
|
||||||
#endif // SI_CONVERT_WIN32
|
#endif // SI_CONVERT_WIN32
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// TYPE DEFINITIONS
|
// TYPE DEFINITIONS
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@@ -49,7 +49,6 @@ int StateIdentifier::recognize(Mat img, Rect frame, char* stateCode)
|
|||||||
// with the value of the country/state
|
// with the value of the country/state
|
||||||
int StateIdentifier::recognize(Mat img, char* stateCode)
|
int StateIdentifier::recognize(Mat img, char* stateCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
timespec startTime;
|
timespec startTime;
|
||||||
getTime(&startTime);
|
getTime(&startTime);
|
||||||
|
|
||||||
@@ -69,7 +68,6 @@ int StateIdentifier::recognize(Mat img, char* stateCode)
|
|||||||
|
|
||||||
if (this->config->debugStateId)
|
if (this->config->debugStateId)
|
||||||
{
|
{
|
||||||
|
|
||||||
displayImage(config, "State Identifier1", plateImg);
|
displayImage(config, "State Identifier1", plateImg);
|
||||||
displayImage(config, "State Identifier", debugImg);
|
displayImage(config, "State Identifier", debugImg);
|
||||||
cout << result.haswinner << " : " << result.confidence << " : " << result.winner << endl;
|
cout << result.haswinner << " : " << result.confidence << " : " << result.winner << endl;
|
||||||
|
@@ -17,8 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef STATEIDENTIFIER_H
|
#ifndef STATEIDENTIFIER_H
|
||||||
#define STATEIDENTIFIER_H
|
#define STATEIDENTIFIER_H
|
||||||
|
|
||||||
@@ -28,8 +26,6 @@
|
|||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StateIdentifier
|
class StateIdentifier
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -45,10 +41,8 @@ class StateIdentifier
|
|||||||
protected:
|
protected:
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
FeatureMatcher* featureMatcher;
|
FeatureMatcher* featureMatcher;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
#ifndef FILESYSTEM_H
|
#ifndef FILESYSTEM_H
|
||||||
#define FILESYSTEM_H
|
#define FILESYSTEM_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
#include "windows/dirent.h"
|
#include "windows/dirent.h"
|
||||||
#include "windows/utils.h"
|
#include "windows/utils.h"
|
||||||
@@ -18,7 +17,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
bool hasEnding (std::string const &fullString, std::string const &ending);
|
bool hasEnding (std::string const &fullString, std::string const &ending);
|
||||||
bool DirectoryExists( const char* pzPath );
|
bool DirectoryExists( const char* pzPath );
|
||||||
bool fileExists( const char* pzPath );
|
bool fileExists( const char* pzPath );
|
||||||
@@ -26,5 +24,4 @@ std::vector<std::string> getFilesInDir(const char* dirPath);
|
|||||||
|
|
||||||
bool stringCompare( const std::string &left, const std::string &right );
|
bool stringCompare( const std::string &left, const std::string &right );
|
||||||
|
|
||||||
|
|
||||||
#endif // FILESYSTEM_H
|
#endif // FILESYSTEM_H
|
||||||
|
@@ -71,7 +71,6 @@ int clock_gettime(int X, timespec *tv)
|
|||||||
void getTime(timespec* time)
|
void getTime(timespec* time)
|
||||||
{
|
{
|
||||||
clock_gettime(0, time);
|
clock_gettime(0, time);
|
||||||
|
|
||||||
}
|
}
|
||||||
double diffclock(timespec time1,timespec time2)
|
double diffclock(timespec time1,timespec time2)
|
||||||
{
|
{
|
||||||
@@ -101,7 +100,6 @@ timespec diff(timespec start, timespec end)
|
|||||||
|
|
||||||
void getTime(timespec* time)
|
void getTime(timespec* time)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
|
#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
|
||||||
clock_serv_t cclock;
|
clock_serv_t cclock;
|
||||||
mach_timespec_t mts;
|
mach_timespec_t mts;
|
||||||
@@ -113,16 +111,13 @@ void getTime(timespec* time)
|
|||||||
#else
|
#else
|
||||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, time);
|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
double diffclock(timespec time1,timespec time2)
|
double diffclock(timespec time1,timespec time2)
|
||||||
{
|
{
|
||||||
|
|
||||||
timespec delta = diff(time1,time2);
|
timespec delta = diff(time1,time2);
|
||||||
double milliseconds = (delta.tv_sec * 1000) + (((double) delta.tv_nsec) / 1000000.0);
|
double milliseconds = (delta.tv_sec * 1000) + (((double) delta.tv_nsec) / 1000000.0);
|
||||||
|
|
||||||
return milliseconds;
|
return milliseconds;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timespec diff(timespec start, timespec end)
|
timespec diff(timespec start, timespec end)
|
||||||
|
@@ -19,5 +19,4 @@
|
|||||||
void getTime(timespec* time);
|
void getTime(timespec* time);
|
||||||
double diffclock(timespec time1,timespec time2);
|
double diffclock(timespec time1,timespec time2);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -37,7 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* types */
|
/* types */
|
||||||
|
|
||||||
#define _TINYDIR_PATH_MAX 4096
|
#define _TINYDIR_PATH_MAX 4096
|
||||||
@@ -88,7 +87,6 @@ typedef struct
|
|||||||
#endif
|
#endif
|
||||||
} tinydir_dir;
|
} tinydir_dir;
|
||||||
|
|
||||||
|
|
||||||
/* declarations */
|
/* declarations */
|
||||||
|
|
||||||
_TINYDIR_FUNC
|
_TINYDIR_FUNC
|
||||||
@@ -110,7 +108,6 @@ int tinydir_open_subdir_n(tinydir_dir *dir, int i);
|
|||||||
_TINYDIR_FUNC
|
_TINYDIR_FUNC
|
||||||
int _tinydir_file_cmp(const void *a, const void *b);
|
int _tinydir_file_cmp(const void *a, const void *b);
|
||||||
|
|
||||||
|
|
||||||
/* definitions*/
|
/* definitions*/
|
||||||
|
|
||||||
_TINYDIR_FUNC
|
_TINYDIR_FUNC
|
||||||
|
@@ -212,12 +212,10 @@
|
|||||||
/* Return number of bytes needed to store d_namlen */
|
/* Return number of bytes needed to store d_namlen */
|
||||||
#define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1)
|
#define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Wide-character version */
|
/* Wide-character version */
|
||||||
struct _wdirent
|
struct _wdirent
|
||||||
{
|
{
|
||||||
@@ -244,7 +242,6 @@ static struct _wdirent *_wreaddir (_WDIR *dirp);
|
|||||||
static int _wclosedir (_WDIR *dirp);
|
static int _wclosedir (_WDIR *dirp);
|
||||||
static void _wrewinddir (_WDIR* dirp);
|
static void _wrewinddir (_WDIR* dirp);
|
||||||
|
|
||||||
|
|
||||||
/* For compatibility with Symbian */
|
/* For compatibility with Symbian */
|
||||||
#define wdirent _wdirent
|
#define wdirent _wdirent
|
||||||
#define WDIR _WDIR
|
#define WDIR _WDIR
|
||||||
@@ -253,7 +250,6 @@ static void _wrewinddir (_WDIR* dirp);
|
|||||||
#define wclosedir _wclosedir
|
#define wclosedir _wclosedir
|
||||||
#define wrewinddir _wrewinddir
|
#define wrewinddir _wrewinddir
|
||||||
|
|
||||||
|
|
||||||
/* Multi-byte character versions */
|
/* Multi-byte character versions */
|
||||||
struct dirent
|
struct dirent
|
||||||
{
|
{
|
||||||
@@ -277,7 +273,6 @@ static struct dirent *readdir (DIR *dirp);
|
|||||||
static int closedir (DIR *dirp);
|
static int closedir (DIR *dirp);
|
||||||
static void rewinddir (DIR* dirp);
|
static void rewinddir (DIR* dirp);
|
||||||
|
|
||||||
|
|
||||||
/* Internal utility functions */
|
/* Internal utility functions */
|
||||||
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
|
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
|
||||||
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
|
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
|
||||||
@@ -873,7 +868,6 @@ dirent_set_errno(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -155,7 +155,6 @@ vector<Mat> produceThresholds(const Mat img_gray, Config* config)
|
|||||||
|
|
||||||
return thresholds;
|
return thresholds;
|
||||||
//threshold(img_equalized, img_threshold, 100, 255, THRESH_BINARY);
|
//threshold(img_equalized, img_threshold, 100, 255, THRESH_BINARY);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double median(int array[], int arraySize)
|
double median(int array[], int arraySize)
|
||||||
@@ -172,7 +171,6 @@ double median(int array[], int arraySize)
|
|||||||
|
|
||||||
Mat equalizeBrightness(Mat img)
|
Mat equalizeBrightness(Mat img)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Divide the image by its morphologically closed counterpart
|
// Divide the image by its morphologically closed counterpart
|
||||||
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
|
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
|
||||||
Mat closed;
|
Mat closed;
|
||||||
@@ -188,12 +186,10 @@ Mat equalizeBrightness(Mat img)
|
|||||||
|
|
||||||
void drawRotatedRect(Mat* img, RotatedRect rect, Scalar color, int thickness)
|
void drawRotatedRect(Mat* img, RotatedRect rect, Scalar color, int thickness)
|
||||||
{
|
{
|
||||||
|
|
||||||
Point2f rect_points[4];
|
Point2f rect_points[4];
|
||||||
rect.points( rect_points );
|
rect.points( rect_points );
|
||||||
for( int j = 0; j < 4; j++ )
|
for( int j = 0; j < 4; j++ )
|
||||||
line( *img, rect_points[j], rect_points[(j+1)%4], color, thickness, 8 );
|
line( *img, rect_points[j], rect_points[(j+1)%4], color, thickness, 8 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillMask(Mat img, const Mat mask, Scalar color)
|
void fillMask(Mat img, const Mat mask, Scalar color)
|
||||||
@@ -212,7 +208,6 @@ void fillMask(Mat img, const Mat mask, Scalar color)
|
|||||||
img.at<Vec3b>(row, col)[z] = ((int) color[z]) | prevVal;
|
img.at<Vec3b>(row, col)[z] = ((int) color[z]) | prevVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,11 +334,9 @@ Point LineSegment::intersection(LineSegment line)
|
|||||||
{
|
{
|
||||||
intersection_X = (c2 - c1) / (slope - line.slope);
|
intersection_X = (c2 - c1) / (slope - line.slope);
|
||||||
intersection_Y = slope * intersection_X + c1;
|
intersection_Y = slope * intersection_X + c1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Point(intersection_X, intersection_Y);
|
return Point(intersection_X, intersection_Y);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Point LineSegment::midpoint()
|
Point LineSegment::midpoint()
|
||||||
|
@@ -17,15 +17,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef UTILITY_H
|
#ifndef UTILITY_H
|
||||||
#define UTILITY_H
|
#define UTILITY_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -39,8 +33,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct LineSegment
|
struct LineSegment
|
||||||
{
|
{
|
||||||
@@ -51,7 +43,6 @@ struct LineSegment
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class LineSegment
|
class LineSegment
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -87,7 +78,6 @@ class LineSegment
|
|||||||
return ss.str() ;
|
return ss.str() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
double median(int array[], int arraySize);
|
double median(int array[], int arraySize);
|
||||||
|
@@ -22,7 +22,6 @@
|
|||||||
VerticalHistogram::VerticalHistogram(Mat inputImage, Mat mask)
|
VerticalHistogram::VerticalHistogram(Mat inputImage, Mat mask)
|
||||||
{
|
{
|
||||||
analyzeImage(inputImage, mask);
|
analyzeImage(inputImage, mask);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VerticalHistogram::~VerticalHistogram()
|
VerticalHistogram::~VerticalHistogram()
|
||||||
@@ -46,7 +45,6 @@ void VerticalHistogram::analyzeImage(Mat inputImage, Mat mask)
|
|||||||
|
|
||||||
for (int row = 0; row < inputImage.rows; row++)
|
for (int row = 0; row < inputImage.rows; row++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (inputImage.at<uchar>(row, col) > 0 && mask.at<uchar>(row, col) > 0)
|
if (inputImage.at<uchar>(row, col) > 0 && mask.at<uchar>(row, col) > 0)
|
||||||
columnCount++;
|
columnCount++;
|
||||||
}
|
}
|
||||||
@@ -60,9 +58,7 @@ void VerticalHistogram::analyzeImage(Mat inputImage, Mat mask)
|
|||||||
|
|
||||||
for (; columnCount > 0; columnCount--)
|
for (; columnCount > 0; columnCount--)
|
||||||
histoImg.at<uchar>(inputImage.rows - columnCount, col) = 255;
|
histoImg.at<uchar>(inputImage.rows - columnCount, col) = 255;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int VerticalHistogram::getLocalMinimum(int leftX, int rightX)
|
int VerticalHistogram::getLocalMinimum(int leftX, int rightX)
|
||||||
@@ -127,7 +123,6 @@ void VerticalHistogram::findValleys()
|
|||||||
relativePeakHeight = colHeights[i];
|
relativePeakHeight = colHeights[i];
|
||||||
|
|
||||||
prevDirection = FLAT;
|
prevDirection = FLAT;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -137,14 +132,11 @@ void VerticalHistogram::findValleys()
|
|||||||
|
|
||||||
if ((prevDirection == FALLING || prevDirection == FLAT) && direction == RISING)
|
if ((prevDirection == FALLING || prevDirection == FLAT) && direction == RISING)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ((prevDirection == FALLING || prevDirection == FLAT) && direction == RISING)
|
else if ((prevDirection == FALLING || prevDirection == FLAT) && direction == RISING)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef VERTICALHISTOGRAM_H
|
#ifndef VERTICALHISTOGRAM_H
|
||||||
#define VERTICALHISTOGRAM_H
|
#define VERTICALHISTOGRAM_H
|
||||||
|
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
struct Valley
|
struct Valley
|
||||||
{
|
{
|
||||||
int startIndex;
|
int startIndex;
|
||||||
|
Reference in New Issue
Block a user