Remove trailing whitespace

This commit is contained in:
Philippe Vaucher
2014-03-17 10:35:09 +01:00
parent b86a6743de
commit bdc922c69a
90 changed files with 3466 additions and 3523 deletions

View File

@@ -11,7 +11,7 @@ User Guide
OpenALPR includes a command line utility. Simply typing "alpr [image file path]" is enough to get started recognizing license plate images.
For example, the following output is created by analyzing this image:
For example, the following output is created by analyzing this image:
![Plate Image](http://www.openalpr.com/images/demoscreenshots/plate3.png "Input image")
@@ -39,7 +39,7 @@ Detailed command line usage:
```
user@linux:~/openalpr$ alpr --help
USAGE:
USAGE:
alpr [-t <region code>] [-r <runtime_dir>] [-n <topN>]
[--seek <integer_ms>] [-c <country_code>]
@@ -47,7 +47,7 @@ USAGE:
<image_file_path>
Where:
Where:
-t <region code>, --template_region <region code>
Attempt to match the plate number against a region template (e.g., md
@@ -63,11 +63,11 @@ Where:
Seek to the specied millisecond in a video file. Default=0
-c <country_code>, --country <country_code>
Country code to identify (either us for USA or eu for Europe).
Country code to identify (either us for USA or eu for Europe).
Default=us
--clock
Measure/print the total time to process image and all plates.
Measure/print the total time to process image and all plates.
Default=off
-d, --detect_region
@@ -100,7 +100,7 @@ OpenALPR compiles and runs on Linux, Mac OSX and Windows.
OpenALPR requires the following additional libraries:
- Tesseract OCR v3.x (https://code.google.com/p/tesseract-ocr/)
- Tesseract OCR v3.x (https://code.google.com/p/tesseract-ocr/)
- OpenCV v2.4.x (http://opencv.org/)
After cloning this GitHub repository, you should download and extract Tesseract and OpenCV source code into their own directories. Compile both libraries.
@@ -127,5 +127,3 @@ License
Affero GPLv3
http://www.gnu.org/licenses/agpl-3.0.html

View File

@@ -14,7 +14,7 @@ ocr_min_font_point = 6
; Minimum OCR confidence percent to consider.
postprocess_min_confidence = 60
; Any OCR character lower than this will also add an equally likely
; Any OCR character lower than this will also add an equally likely
; chance that the character is incorrect and will be skipped. Value is a confidence percent
postprocess_confidence_skip_level = 75
@@ -110,7 +110,3 @@ min_plate_size_width_px = 100
min_plate_size_height_px = 20
ocr_language = leu

View File

@@ -1,8 +1,8 @@
base @@@####
base @@@####
base @@@###
base ###@@@
al #@##@##
al ##@##@#
al #@##@##
al ##@##@#
al @@#####
al #####@@
al #@####@

View File

@@ -1,26 +1,26 @@
project(src)
cmake_minimum_required (VERSION 2.6)
cmake_minimum_required (VERSION 2.6)
SET(OpenCV_DIR "${CMAKE_SOURCE_DIR}/../libraries/opencv/")
SET(Tesseract_DIR "${CMAKE_SOURCE_DIR}/../libraries/tesseract-ocr")
include_directories(
${Tesseract_DIR}/api
${Tesseract_DIR}/ccutil/
${Tesseract_DIR}/ccstruct/
${Tesseract_DIR}/ccmain/
)
IF (WIN32)
add_definitions( -DWINDOWS)
add_definitions( -DNOMINMAX)
link_directories( ${Tesseract_DIR}/vs2008/LIB_Release/ )
link_directories( ${Tesseract_DIR}/vs2008/LIB_Release/ )
ELSE()
link_directories( ${Tesseract_DIR}/api/.libs/ )
link_directories( ${Tesseract_DIR}/api/.libs/ )
ENDIF()
@@ -40,10 +40,10 @@ ADD_EXECUTABLE( alpr main.cpp )
IF (WIN32)
# Extra linker dependencies for Windows
TARGET_LINK_LIBRARIES(alpr
TARGET_LINK_LIBRARIES(alpr
openalpr
support
${OpenCV_LIBS}
${OpenCV_LIBS}
libtesseract302-static
liblept168
liblept168-static-mtdll
@@ -54,17 +54,16 @@ IF (WIN32)
zlib125-static-mtdll
ws2_32.lib
)
ELSE()
TARGET_LINK_LIBRARIES(alpr
TARGET_LINK_LIBRARIES(alpr
openalpr
support
${OpenCV_LIBS}
${OpenCV_LIBS}
tesseract
)
ENDIF()
add_subdirectory(openalpr)
add_subdirectory(misc_utilities)

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -32,20 +32,20 @@
#include "alpr.h"
const std::string MAIN_WINDOW_NAME = "ALPR main window";
const bool SAVE_LAST_VIDEO_STILL = false;
const std::string LAST_VIDEO_STILL_LOCATION = "/tmp/laststill.jpg";
/** Function Headers */
bool detectandshow(Alpr* alpr, cv::Mat frame, std::string region, bool writeJson);
bool measureProcessingTime = false;
int main( int argc, const char** argv )
{
std::string filename;
@@ -56,19 +56,19 @@
std::string templateRegion;
std::string country;
int topn;
try {
try {
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::ValueArg<std::string> countryCodeArg("c","country","Country code to identify (either us for USA or eu for Europe). Default=us",false, "us" ,"country_code");
TCLAP::ValueArg<int> seekToMsArg("","seek","Seek to the specied millisecond in a video file. Default=0",false, 0 ,"integer_ms");
TCLAP::ValueArg<std::string> runtimeDirArg("r","runtime_dir","Path to the OpenAlpr runtime data directory",false, "" ,"runtime_dir");
TCLAP::ValueArg<std::string> templateRegionArg("t","template_region","Attempt to match the plate number against a region template (e.g., md for Maryland, ca for California)",false, "" ,"region code");
TCLAP::ValueArg<int> topNArg("n","topn","Max number of possible plate numbers to return. Default=10",false, 10 ,"topN");
TCLAP::SwitchArg jsonSwitch("j","json","Output recognition results in JSON format. Default=off", cmd, false);
TCLAP::SwitchArg detectRegionSwitch("d","detect_region","Attempt to detect the region of the plate image. Default=off", cmd, false);
TCLAP::SwitchArg clockSwitch("","clock","Measure/print the total time to process image and all plates. Default=off", cmd, false);
@@ -78,12 +78,12 @@
cmd.add( seekToMsArg );
cmd.add( topNArg );
cmd.add( runtimeDirArg );
cmd.add( templateRegionArg );
cmd.add( templateRegionArg );
cmd.parse( argc, argv );
filename = fileArg.getValue();
country = countryCodeArg.getValue();
seektoms = seekToMsArg.getValue();
outputJson = jsonSwitch.getValue();
@@ -92,33 +92,33 @@
templateRegion = templateRegionArg.getValue();
topn = topNArg.getValue();
measureProcessingTime = clockSwitch.getValue();
} catch (TCLAP::ArgException &e) // catch any exceptions
{
std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
{
std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
return 1;
}
cv::Mat frame;
Alpr alpr(country, runtimePath);
alpr.setTopN(topn);
if (detectRegion)
alpr.setDetectRegion(detectRegion);
if (strcmp(templateRegion.c_str(), "") != 0)
{
alpr.setDefaultRegion(templateRegion);
}
if (alpr.isLoaded() == false)
{
std::cerr << "Error loading OpenAlpr" << std::endl;
return 1;
}
if (strcmp(filename.c_str(), "webcam") == 0)
{
int framenum = 0;
@@ -141,11 +141,11 @@
if (fileExists(filename.c_str()))
{
int framenum = 0;
cv::VideoCapture cap=cv::VideoCapture();
cap.open(filename);
cap.set(CV_CAP_PROP_POS_MSEC, seektoms);
while (cap.read(frame) == true)
{
if (SAVE_LAST_VIDEO_STILL == true)
@@ -153,7 +153,7 @@
cv::imwrite(LAST_VIDEO_STILL_LOCATION, frame);
}
std::cout << "Frame: " << framenum << std::endl;
detectandshow( &alpr, frame, "", outputJson);
//create a 1ms delay
cv::waitKey(1);
@@ -164,29 +164,29 @@
{
std::cerr << "Video file not found: " << filename << std::endl;
}
}
else if (hasEnding(filename, ".png") || hasEnding(filename, ".jpg") || hasEnding(filename, ".gif"))
{
if (fileExists(filename.c_str()))
{
frame = cv::imread( filename );
detectandshow( &alpr, frame, "", outputJson);
}
else
{
std::cerr << "Image file not found: " << filename << std::endl;
}
}
else if (DirectoryExists(filename.c_str()))
{
std::vector<std::string> files = getFilesInDir(filename.c_str());
std::sort( files.begin(), files.end(), stringCompare );
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".jpg") || hasEnding(files[i], ".png"))
@@ -203,7 +203,7 @@
//cv::waitKey(50);
}
}
}
}
else
@@ -211,28 +211,28 @@
std::cerr << "Unknown file type" << std::endl;
return 1;
}
return 0;
}
bool detectandshow( Alpr* alpr, cv::Mat frame, std::string region, bool writeJson)
{
std::vector<uchar> buffer;
cv::imencode(".bmp", frame, buffer );
timespec startTime;
getTime(&startTime);
std::vector<AlprResult> results = alpr->recognize(buffer);
if (writeJson)
{
std::cout << alpr->toJson(results) << std::endl;
@@ -242,12 +242,12 @@
for (int i = 0; i < results.size(); i++)
{
std::cout << "plate" << i << ": " << results[i].result_count << " results -- Processing Time = " << results[i].processing_time_ms << "ms." << std::endl;
for (int k = 0; k < results[i].topNPlates.size(); k++)
{
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;
}
}
}
@@ -255,14 +255,10 @@
getTime(&endTime);
if (measureProcessingTime)
std::cout << "Total Time to process image: " << diffclock(startTime, endTime) << "ms." << std::endl;
if (results.size() > 0)
return true;
return false;
}

View File

@@ -4,35 +4,33 @@ target_link_libraries(openalpr)
ADD_EXECUTABLE( sortstate sortstate.cpp )
TARGET_LINK_LIBRARIES(sortstate
TARGET_LINK_LIBRARIES(sortstate
openalpr
support
${OpenCV_LIBS}
${OpenCV_LIBS}
tesseract
)
ADD_EXECUTABLE( classifychars classifychars.cpp )
TARGET_LINK_LIBRARIES(classifychars
TARGET_LINK_LIBRARIES(classifychars
openalpr
support
${OpenCV_LIBS}
${OpenCV_LIBS}
tesseract
)
ADD_EXECUTABLE( benchmark benchmark.cpp )
TARGET_LINK_LIBRARIES(benchmark
TARGET_LINK_LIBRARIES(benchmark
openalpr
support
${OpenCV_LIBS}
${OpenCV_LIBS}
tesseract
)
ADD_EXECUTABLE( prepcharsfortraining prepcharsfortraining.cpp )
TARGET_LINK_LIBRARIES(prepcharsfortraining
TARGET_LINK_LIBRARIES(prepcharsfortraining
support
${OpenCV_LIBS}
${OpenCV_LIBS}
)

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -39,9 +39,9 @@
// Given a directory full of lp images (named [statecode]#.png) crop out the alphanumeric characters.
// These will be used to train the OCR
void outputStats(vector<double> datapoints);
int main( int argc, const char** argv )
{
string country;
@@ -49,8 +49,8 @@ int main( int argc, const char** argv )
string inDir;
string outDir;
Mat frame;
//Check if user specify image to process
if(argc == 5)
{
@@ -58,17 +58,17 @@ int main( int argc, const char** argv )
benchmarkName = argv[2];
inDir = argv[3];
outDir = argv[4];
}else{
printf("Use:\n\t%s [country] [benchmark name] [img input dir] [results output dir]\n",argv[0]);
printf("\tex: %s us speed ./speed/usimages ./speed\n",argv[0]);
printf("\n");
printf("\ttest names are: speed, segocr, detection\n\n" );
return 0;
}
}
if (DirectoryExists(inDir.c_str()) == false)
{
printf("Input dir does not exist\n");
@@ -79,20 +79,20 @@ int main( int argc, const char** argv )
printf("Output dir does not exist\n");
return 0;
}
vector<string> files = getFilesInDir(inDir.c_str());
sort( files.begin(), files.end(), stringCompare );
if (benchmarkName.compare("segocr") == 0)
{
Config* config = new Config(country);
Config* config = new Config(country);
config->debugOff();
OCR* ocr = new OCR(config);
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".png"))
@@ -101,51 +101,51 @@ int main( int argc, const char** argv )
frame = imread( fullpath.c_str() );
resize(frame, frame, Size(config->ocrImageWidthPx, config->ocrImageHeightPx));
Rect plateCoords;
plateCoords.x = 0;
plateCoords.y = 0;
plateCoords.width = frame.cols;
plateCoords.height = frame.rows;
char statecode[3];
statecode[0] = files[i][0];
statecode[1] = files[i][1];
statecode[2] = '\0';
string statecodestr(statecode);
CharacterRegion charRegion(frame, config);
if (abs(charRegion.getTopLine().angle) > 4)
{
// Rotate image:
Mat rotated(frame.size(), frame.type());
Mat rot_mat( 2, 3, CV_32FC1 );
Point center = Point( frame.cols/2, frame.rows/2 );
rot_mat = getRotationMatrix2D( center, charRegion.getTopLine().angle, 1.0 );
warpAffine( frame, rotated, rot_mat, frame.size() );
rotated.copyTo(frame);
}
CharacterSegmenter charSegmenter(frame, charRegion.thresholdsInverted(), config);
ocr->performOCR(charSegmenter.getThresholds(), charSegmenter.characters);
ocr->postProcessor->analyze(statecode, 25);
cout << files[i] << "," << statecode << "," << ocr->postProcessor->bestChars << endl;
imshow("Current LP", frame);
waitKey(5);
}
}
delete config;
delete ocr;
}
@@ -153,42 +153,42 @@ int main( int argc, const char** argv )
{
Config config(country);
RegionDetector plateDetector(&config);
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".png"))
{
string fullpath = inDir + "/" + files[i];
frame = imread( fullpath.c_str() );
vector<Rect> regions = plateDetector.detect(frame);
imshow("Current LP", frame);
waitKey(5);
}
}
}
else if (benchmarkName.compare("speed") == 0)
{
// Benchmarks speed of region detection, plate analysis, and OCR
timespec startTime;
timespec endTime;
Config config(country);
config.debugOff();
AlprImpl alpr(country);
alpr.config->debugOff();
alpr.setDetectRegion(true);
RegionDetector plateDetector(&config);
StateIdentifier stateIdentifier(&config);
OCR ocr(&config);
vector<double> endToEndTimes;
vector<double> regionDetectionTimes;
vector<double> stateIdTimes;
@@ -196,33 +196,33 @@ int main( int argc, const char** argv )
vector<double> lpAnalysisNegativeTimes;
vector<double> ocrTimes;
vector<double> postProcessTimes;
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".png"))
{
cout << "Image: " << files[i] << endl;
string fullpath = inDir + "/" + files[i];
frame = imread( fullpath.c_str() );
getTime(&startTime);
alpr.recognize(frame);
getTime(&endTime);
double endToEndTime = diffclock(startTime, endTime);
cout << " -- End to End recognition time: " << endToEndTime << "ms." << endl;
endToEndTimes.push_back(endToEndTime);
getTime(&startTime);
vector<Rect> regions = plateDetector.detect(frame);
getTime(&endTime);
double regionDetectionTime = diffclock(startTime, endTime);
cout << " -- Region detection time: " << regionDetectionTime << "ms." << endl;
regionDetectionTimes.push_back(regionDetectionTime);
for (int z = 0; z < regions.size(); z++)
{
getTime(&startTime);
@@ -232,26 +232,26 @@ int main( int argc, const char** argv )
double stateidTime = diffclock(startTime, endTime);
cout << "\tRegion " << z << ": State ID time: " << stateidTime << "ms." << endl;
stateIdTimes.push_back(stateidTime);
getTime(&startTime);
LicensePlateCandidate lp(frame, regions[z], &config);
lp.recognize();
getTime(&endTime);
double analysisTime = diffclock(startTime, endTime);
cout << "\tRegion " << z << ": Analysis time: " << analysisTime << "ms." << endl;
if (lp.confidence > 10)
{
lpAnalysisPositiveTimes.push_back(analysisTime);
getTime(&startTime);
ocr.performOCR(lp.charSegmenter->getThresholds(), lp.charSegmenter->characters);
getTime(&endTime);
double ocrTime = diffclock(startTime, endTime);
cout << "\tRegion " << z << ": OCR time: " << ocrTime << "ms." << endl;
ocrTimes.push_back(ocrTime);
getTime(&startTime);
ocr.postProcessor->analyze("", 25);
getTime(&endTime);
@@ -264,40 +264,40 @@ int main( int argc, const char** argv )
lpAnalysisNegativeTimes.push_back(analysisTime);
}
}
waitKey(5);
}
}
cout << endl << "---------------------" << endl;
cout << "End to End Time Statistics:" << endl;
outputStats(endToEndTimes);
cout << endl;
cout << "Region Detection Time Statistics:" << endl;
outputStats(regionDetectionTimes);
cout << endl;
cout << "State ID Time Statistics:" << endl;
outputStats(stateIdTimes);
cout << endl;
cout << "Positive Region Analysis Time Statistics:" << endl;
outputStats(lpAnalysisPositiveTimes);
cout << endl;
cout << "Negative Region Analysis Time Statistics:" << endl;
outputStats(lpAnalysisNegativeTimes);
cout << endl;
cout << "OCR Time Statistics:" << endl;
outputStats(ocrTimes);
cout << endl;
cout << "Post Processing Time Statistics:" << endl;
outputStats(postProcessTimes);
cout << endl;
@@ -306,41 +306,41 @@ int main( int argc, const char** argv )
{
Alpr alpr(country);
alpr.setDetectRegion(true);
ofstream outputdatafile;
outputdatafile.open("results.txt");
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".png"))
{
string fullpath = inDir + "/" + files[i];
frame = imread( fullpath.c_str() );
vector<uchar> buffer;
imencode(".bmp", frame, buffer );
vector<AlprResult> results = alpr.recognize(buffer);
outputdatafile << files[i] << ": ";
for (int z = 0; z < results.size(); z++)
{
outputdatafile << results[z].bestPlate.characters << ", ";
}
outputdatafile << endl;
imshow("Current LP", frame);
waitKey(5);
}
}
outputdatafile.close();
}
}
void outputStats(vector<double> datapoints)
@@ -357,5 +357,3 @@ void outputStats(vector<double> datapoints)
cout << "\t" << datapoints.size() << " samples, avg: " << mean << "ms, stdev: " << stdev << endl;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -43,7 +43,7 @@ const int RIGHT_ARROW_KEY = 3;
const int SPACE_KEY = 32;
const int ENTER_KEY = 13;
const int ESCAPE_KEY = 27;
const int DOWN_ARROW_KEY = 1;
const int UP_ARROW_KEY= 0;
const int DASHBOARD_COLUMNS = 9;
@@ -54,7 +54,7 @@ const int RIGHT_ARROW_KEY = 83;
const int SPACE_KEY = 32;
const int ENTER_KEY = 10;
const int ESCAPE_KEY = 27;
const int DOWN_ARROW_KEY = 84;
const int UP_ARROW_KEY= 82;
const int DASHBOARD_COLUMNS = 3;
@@ -64,35 +64,35 @@ const int DASHBOARD_COLUMNS = 3;
void showDashboard(vector<Mat> images, vector<bool> selectedImages, int selectedIndex);
vector<char> showCharSelection(Mat image, vector<Rect> charRegions, string state);
int main( int argc, const char** argv )
{
string inDir;
string outDir;
Mat frame;
//Check if user specify image to process
if(argc == 3)
{
inDir = argv[1];
outDir = argv[2];
}else{
printf("Use:\n\t%s indirectory outdirectory\n",argv[0]);
printf("Ex: \n\t%s ./pics/ ./out \n",argv[0]);
return 0;
}
}
if (DirectoryExists(outDir.c_str()) == false)
{
printf("Output dir does not exist\n");
return 0;
}
cout << "Usage: " << endl;
cout << "\tn -- Next plate" << endl;
cout << "\tp -- Previous plate" << endl;
@@ -104,16 +104,16 @@ int main( int argc, const char** argv )
cout << "\t<- and -> -- Cycle between characters" << endl;
cout << "\t[0-9A-Z] -- Identify a character (saves the image)" << endl;
cout << "\tESC/Ent/Space -- Back to plate selection" << endl;
Config* config = new Config("eu");
OCR ocr(config);
if (DirectoryExists(inDir.c_str()))
{
vector<string> files = getFilesInDir(inDir.c_str());
sort( files.begin(), files.end(), stringCompare );
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
@@ -122,57 +122,57 @@ int main( int argc, const char** argv )
cout << fullpath << endl;
frame = imread( fullpath.c_str() );
resize(frame, frame, Size(config->ocrImageWidthPx, config->ocrImageHeightPx));
imshow ("Original", frame);
char statecode[3];
statecode[0] = files[i][0];
statecode[1] = files[i][1];
statecode[2] = '\0';
string statecodestr(statecode);
CharacterRegion regionizer(frame, config);
if (abs(regionizer.getTopLine().angle) > 4)
{
// Rotate image:
Mat rotated(frame.size(), frame.type());
Mat rot_mat( 2, 3, CV_32FC1 );
Point center = Point( frame.cols/2, frame.rows/2 );
rot_mat = getRotationMatrix2D( center, regionizer.getTopLine().angle, 1.0 );
warpAffine( frame, rotated, rot_mat, frame.size() );
rotated.copyTo(frame);
}
CharacterSegmenter charSegmenter(frame, regionizer.thresholdsInverted(), config);
//ocr.cleanCharRegions(charSegmenter.thresholds, charSegmenter.characters);
ocr.performOCR(charSegmenter.getThresholds(), charSegmenter.characters);
ocr.postProcessor->analyze(statecodestr, 25);
cout << "OCR results: " << ocr.postProcessor->bestChars << endl;
vector<bool> selectedBoxes(charSegmenter.getThresholds().size());
for (int z = 0; z < charSegmenter.getThresholds().size(); z++)
selectedBoxes[z] = false;
int curDashboardSelection = 0;
vector<char> humanInputs(charSegmenter.characters.size());
for (int z = 0; z < charSegmenter.characters.size(); z++)
humanInputs[z] = ' ';
showDashboard(charSegmenter.getThresholds(), selectedBoxes, 0);
char waitkey = (char) waitKey(50);
while (waitkey != 'n' && waitkey != 'p') // Next image
{
if (waitkey == LEFT_ARROW_KEY) // left arrow key
@@ -233,17 +233,17 @@ int main( int argc, const char** argv )
// Save
if (somethingSelected && chardataTagged)
{
for (int c = 0; c < charSegmenter.characters.size(); c++)
{
if (humanInputs[c] == ' ')
continue;
for (int t = 0; t < charSegmenter.getThresholds().size(); t++)
{
if (selectedBoxes[t] == false)
continue;
stringstream filename;
Mat cropped = charSegmenter.getThresholds()[t](charSegmenter.characters[c]);
filename << outDir << "/" << humanInputs[c] << "-" << t << "-" << files[i];
@@ -257,34 +257,34 @@ int main( int argc, const char** argv )
else if (chardataTagged == false)
cout << "You have not tagged any characters" << endl;
}
waitkey = (char) waitKey(50);
}
if (waitkey == 'p')
i = i - 2;
if (i < -1)
i = -1;
}
}
}
}
void showDashboard(vector<Mat> images, vector<bool> selectedImages, int selectedIndex)
{
vector<Mat> vecCopy;
if (selectedIndex < 0)
selectedIndex = 0;
if (selectedIndex >= images.size())
selectedIndex = images.size() -1;
for (int i = 0; i < images.size(); i++)
{
Mat imgCopy(images[i].size(), images[i].type());
@@ -298,35 +298,35 @@ void showDashboard(vector<Mat> images, vector<bool> selectedImages, int selected
{
rectangle(imgCopy, Point(2,2), Point(imgCopy.size().width - 2, imgCopy.size().height -2), Scalar(255, 0, 0), 1);
}
vecCopy.push_back(imgCopy);
}
Mat dashboard = drawImageDashboard(vecCopy, vecCopy[0].type(), DASHBOARD_COLUMNS);
imshow("Selection dashboard", dashboard);
}
vector<char> showCharSelection(Mat image, vector<Rect> charRegions, string state)
{
int curCharIdx = 0;
vector<char> humanInputs(charRegions.size());
for (int i = 0; i < charRegions.size(); i++)
humanInputs[i] = (char) SPACE_KEY;
char waitkey = (char) waitKey(50);
while (waitkey != ENTER_KEY && waitkey != ESCAPE_KEY)
{
Mat imgCopy(image.size(), image.type());
image.copyTo(imgCopy);
cvtColor(imgCopy, imgCopy, CV_GRAY2BGR);
rectangle(imgCopy, charRegions[curCharIdx], Scalar(0, 255, 0), 1);
imshow("Character selector", imgCopy);
if (waitkey == LEFT_ARROW_KEY)
curCharIdx--;
else if (waitkey == RIGHT_ARROW_KEY )
@@ -336,22 +336,22 @@ vector<char> showCharSelection(Mat image, vector<Rect> charRegions, string state
// Save the character to disk
humanInputs[curCharIdx] = toupper((char) waitkey);
curCharIdx++;
if (curCharIdx >= charRegions.size())
{
waitkey = (char) ENTER_KEY;
break;
}
}
if (curCharIdx < 0)
curCharIdx = 0;
if (curCharIdx >= charRegions.size())
curCharIdx = charRegions.size() -1;
waitkey = (char) waitKey(50);
}
if (waitkey == ENTER_KEY)
{
// Save all the inputs
@@ -360,11 +360,11 @@ vector<char> showCharSelection(Mat image, vector<Rect> charRegions, string state
if (humanInputs[i] != (char) SPACE_KEY)
cout << "Tagged " << state << " char code: '" << humanInputs[i] << "' at char position: " << i << endl;
}
}
destroyWindow("Character selector");
return humanInputs;
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -35,89 +35,89 @@
// Also creates a box file so Tesseract can recognize it
int main( int argc, const char** argv )
{
string inDir;
//Check if user specify image to process
if(argc == 2)
{
inDir = argv[1];
}else{
printf("Use:\n\t%s input dir \n",argv[0]);
return 0;
}
}
if (DirectoryExists(inDir.c_str()) == false)
{
printf("Output dir does not exist\n");
return 0;
}
cout << "Usage: " << endl;
cout << "\tinputdir -- input dir for benchmark data" << endl;
if (DirectoryExists(inDir.c_str()))
{
const int X_OFFSET = 10;
const int Y_OFFSET = 10;
const int PAGE_MARGIN_X = 70;
const int PAGE_MARGIN_Y = 70;
const int HORIZONTAL_RESOLUTION = 3500;
const int TILE_WIDTH = 55;
const int CHAR_HORIZ_OFFSET = 40;
const int TILE_HEIGHT = 70;
const int CHAR_VERT_OFFSET = 48;
vector<string> files = getFilesInDir(inDir.c_str());
sort( files.begin(), files.end(), stringCompare );
int tiles_per_row = ((float) (HORIZONTAL_RESOLUTION - (PAGE_MARGIN_X * 2))) / ((float) TILE_WIDTH);
int lines = files.size() / (tiles_per_row);
int vertical_resolution = (lines * TILE_HEIGHT) + (PAGE_MARGIN_Y * 2) ;
cout << tiles_per_row << " : " << vertical_resolution << endl;
Mat bigTif = Mat::zeros(Size(HORIZONTAL_RESOLUTION, vertical_resolution), CV_8U);
bitwise_not(bigTif, bigTif);
stringstream boxFileOut;
for (int i = 0; i< files.size(); i++)
{
int col = i % tiles_per_row;
int line = i / tiles_per_row;
int xPos = (col * TILE_WIDTH) + PAGE_MARGIN_X;
int yPos = (line * TILE_HEIGHT) + PAGE_MARGIN_Y;
if (hasEnding(files[i], ".png") || hasEnding(files[i], ".jpg"))
{
string fullpath = inDir + "/" + files[i];
cout << "Processing file: " << (i + 1) << " of " << files.size() << endl;
char charcode = files[i][0];
Mat characterImg = imread(fullpath);
Mat charImgCopy = Mat::zeros(Size(150, 150), characterImg.type());
bitwise_not(charImgCopy, charImgCopy);
characterImg.copyTo(charImgCopy(Rect(X_OFFSET, Y_OFFSET, characterImg.cols, characterImg.rows)));
cvtColor(charImgCopy, charImgCopy, CV_BGR2GRAY);
bitwise_not(charImgCopy, charImgCopy);
vector<vector<Point> > contours;
//imshow("copy", charImgCopy);
findContours(charImgCopy, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
Rect tallestRect(0, 0, 0, 0);
for (int c = 0; c < contours.size(); c++)
{
@@ -125,23 +125,23 @@ int main( int argc, const char** argv )
if (tmpRect.height > tallestRect.height)
tallestRect = tmpRect;
}
//cout << tallestRect.x << ":" << tallestRect.y << " -- " << tallestRect.width << ":" << tallestRect.height << endl;
Rect cropRect(0, tallestRect.y - Y_OFFSET, tallestRect.width, tallestRect.height);
//cout << "Cropped: " << cropRect.x << ":" << cropRect.y << " -- " << cropRect.width << ":" << cropRect.height << endl;
Mat cropped(characterImg, cropRect);
cvtColor(cropped, cropped, CV_BGR2GRAY);
Rect destinationRect(xPos + (CHAR_HORIZ_OFFSET - tallestRect.width), yPos + (CHAR_VERT_OFFSET - tallestRect.height), tallestRect.width, tallestRect.height);
//cout << "1" << endl;
cropped.copyTo(bigTif(destinationRect));
int x1= destinationRect.x - 2;
int y1 = (vertical_resolution - destinationRect.y - destinationRect.height) - 2;
int x2 = (destinationRect.x + destinationRect.width) + 2;
@@ -150,24 +150,22 @@ int main( int argc, const char** argv )
boxFileOut << charcode << " " << x1 << " " << y1 << " ";
boxFileOut << x2 << " " << y2 ;
boxFileOut << " 0" << endl;
//rectangle(characterImg, tallestRect, Scalar(0, 255, 0));
//imshow("characterImg", cropped);
waitKey(2);
}
}
imwrite("combined.tif", bigTif);
ofstream boxFile("combined.box", std::ios::out);
boxFile << boxFileOut.str();
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -37,42 +37,42 @@
// This is used to sort our own positive image database as a first step before grabbing characters to use to train the OCR.
bool detectPlate( StateIdentifier* identifier, Mat frame);
int main( int argc, const char** argv )
{
string inDir;
string outDir;
Mat frame;
//Check if user specify image to process
if(argc == 3 )
{
inDir = argv[1];
outDir = argv[2];
outDir = outDir + "/";
}else{
printf("Use:\n\t%s directory \n",argv[0]);
printf("Ex: \n\t%s ./pics/ \n",argv[0]);
return 0;
}
}
Config config("us");
StateIdentifier identifier(&config);
if (DirectoryExists(outDir.c_str()) == false)
{
printf("Output dir does not exist\n");
return 0;
}
if (DirectoryExists(inDir.c_str()))
{
vector<string> files = getFilesInDir(inDir.c_str());
for (int i = 0; i< files.size(); i++)
{
if (hasEnding(files[i], ".png"))
@@ -80,26 +80,26 @@ int main( int argc, const char** argv )
string fullpath = inDir + "/" + files[i];
cout << fullpath << endl;
frame = imread( fullpath.c_str() );
char code[4];
int confidence = identifier.recognize(frame, code);
if (confidence <= 20)
{
code[0] = 'z';
code[1] = 'z';
confidence = 100;
}
//imshow("Plate", frame);
if (confidence > 20)
{
cout << confidence << " : " << code;
ostringstream convert; // stream used for the conversion
convert << i; // insert the textual representation of 'Number' in the characters in the stream
string copyCommand = "cp \"" + fullpath + "\" " + outDir + code + convert.str() + ".png";
system( copyCommand.c_str() );
waitKey(50);
@@ -108,10 +108,10 @@ int main( int argc, const char** argv )
else
waitKey(50);
}
}
}
}
bool detectPlate( StateIdentifier* identifier, Mat frame);
bool detectPlate( StateIdentifier* identifier, Mat frame);

View File

@@ -25,7 +25,7 @@ set(lpr_source_files
cjson.c
)
add_subdirectory(simpleini)
add_subdirectory(support)
@@ -35,4 +35,4 @@ add_library(openalpr ${lpr_source_files})
# Add definition for default runtime dir
add_definitions(-DDEFAULT_RUNTIME_DIR="${CMAKE_SOURCE_DIR}/../runtime_data/")
add_definitions(-DDEFAULT_RUNTIME_DIR="${CMAKE_SOURCE_DIR}/../runtime_data/")

View File

@@ -5,11 +5,11 @@
Copyright (C) 2003-2004 Alberto Demichelis
This software is provided 'as-is', without any express
or implied warranty. In no event will the authors be held
This software is provided 'as-is', without any express
or implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for
Permission is granted to anyone to use this software for
any purpose, including commercial applications, and to alter
it and redistribute it freely, subject to the following restrictions:
@@ -38,28 +38,28 @@ public:
TRexpp() { _exp = (TRex *)0; }
~TRexpp() { CleanUp(); }
// compiles a regular expression
void Compile(const TRexChar *pattern) {
void Compile(const TRexChar *pattern) {
const TRexChar *error;
CleanUp();
if(!(_exp = trex_compile(pattern,&error)))
throw TRexParseException(error);
}
// return true if the given text match the expression
bool Match(const TRexChar* text) {
return _exp?(trex_match(_exp,text) != 0):false;
bool Match(const TRexChar* text) {
return _exp?(trex_match(_exp,text) != 0):false;
}
// Searches for the first match of the expression in a zero terminated string
bool Search(const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) {
return _exp?(trex_search(_exp,text,out_begin,out_end) != 0):false;
bool Search(const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) {
return _exp?(trex_search(_exp,text,out_begin,out_end) != 0):false;
}
// Searches for the first match of the expression in a string sarting at text_begin and ending at text_end
bool SearchRange(const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) {
return _exp?(trex_searchrange(_exp,text_begin,text_end,out_begin,out_end) != 0):false;
bool SearchRange(const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) {
return _exp?(trex_searchrange(_exp,text_begin,text_end,out_begin,out_end) != 0):false;
}
bool GetSubExp(int n, const TRexChar** out_begin, int *out_len)
{
TRexMatch match;
TRexBool res = _exp?(trex_getsubexp(_exp,n,&match)):TRex_False;
TRexBool res = _exp?(trex_getsubexp(_exp,n,&match)):TRex_False;
if(res) {
*out_begin = match.begin;
*out_len = match.len;
@@ -72,4 +72,4 @@ private:
void CleanUp() { if(_exp) trex_free(_exp); _exp = (TRex *)0; }
TRex *_exp;
};
#endif //_TREXPP_H_
#endif //_TREXPP_H_

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -24,7 +24,7 @@
// ALPR code
Alpr::Alpr(const std::string country, const std::string runtimeDir)
{
impl = new AlprImpl(country, runtimeDir);
@@ -37,7 +37,7 @@ std::vector<AlprResult> Alpr::recognize(std::string filepath)
{
cv::Mat img = cv::imread(filepath, CV_LOAD_IMAGE_COLOR);
return impl->recognize(img);
}
@@ -45,7 +45,7 @@ std::vector<AlprResult> Alpr::recognize(std::vector<unsigned char> imageBuffer)
{
// Not sure if this actually works
cv::Mat img = cv::imdecode(Mat(imageBuffer), 1);
return impl->recognize(img);
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -30,7 +30,7 @@ struct AlprPlate
{
std::string characters;
float overall_confidence;
bool matches_template;
//int char_confidence[];
};
@@ -46,16 +46,16 @@ class AlprResult
public:
AlprResult();
virtual ~AlprResult();
int requested_topn;
int result_count;
AlprPlate bestPlate;
std::vector<AlprPlate> topNPlates;
float processing_time_ms;
AlprCoordinate plate_points[4];
int regionConfidence;
std::string region;
};
@@ -73,16 +73,16 @@ class Alpr
void setDetectRegion(bool detectRegion);
void setTopN(int topN);
void setDefaultRegion(std::string region);
std::vector<AlprResult> recognize(std::string filepath);
std::vector<AlprResult> recognize(std::vector<unsigned char> imageBuffer);
std::string toJson(const std::vector<AlprResult> results);
bool isLoaded();
private:
AlprImpl* impl;
};
#endif // APLR_H
#endif // APLR_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -26,32 +26,32 @@ AlprImpl::AlprImpl(const std::string country, const std::string runtimeDir)
plateDetector = new RegionDetector(config);
stateIdentifier = new StateIdentifier(config);
ocr = new OCR(config);
this->detectRegion = DEFAULT_DETECT_REGION;
this->topN = DEFAULT_TOPN;
this->defaultRegion = "";
if (config->opencl_enabled)
{
cv::ocl::PlatformsInfo platinfo;
cv::ocl::getOpenCLPlatforms(platinfo);
for (int i = 0; i < platinfo.size(); i++)
{
std::cout << platinfo[i]->platformName << std::endl;
}
cv::ocl::DevicesInfo devices;
cv::ocl::getOpenCLDevices(devices, cv::ocl::CVCL_DEVICE_TYPE_CPU);
for (int i = 0; i < devices.size(); i++)
std:: cout << devices[i]->deviceName << std::endl;
if (devices.size() > 0)
{
cv::ocl::setDevice(devices[0]);
cout << "Using OpenCL Device: " << devices[0]->deviceName << endl;
}
else
@@ -73,9 +73,9 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
{
timespec startTime;
getTime(&startTime);
vector<AlprResult> response;
vector<Rect> plateRegions = plateDetector->detect(img);
@@ -86,24 +86,24 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
{
timespec platestarttime;
getTime(&platestarttime);
LicensePlateCandidate lp(img, plateRegions[i], config);
lp.recognize();
if (lp.confidence > 10)
{
AlprResult plateResult;
plateResult.region = defaultRegion;
plateResult.regionConfidence = 0;
for (int pointidx = 0; pointidx < 4; pointidx++)
{
plateResult.plate_points[pointidx].x = (int) lp.plateCorners[pointidx].x;
plateResult.plate_points[pointidx].y = (int) lp.plateCorners[pointidx].y;
}
if (detectRegion)
{
char statecode[4];
@@ -113,26 +113,26 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
plateResult.region = statecode;
}
}
ocr->performOCR(lp.charSegmenter->getThresholds(), lp.charSegmenter->characters);
ocr->postProcessor->analyze(plateResult.region, topN);
//plateResult.characters = ocr->postProcessor->bestChars;
const vector<PPResult> ppResults = ocr->postProcessor->getResults();
int bestPlateIndex = 0;
for (int pp = 0; pp < ppResults.size(); pp++)
{
if (pp >= topN)
break;
// Set our "best plate" match to either the first entry, or the first entry with a postprocessor template match
if (bestPlateIndex == 0 && ppResults[pp].matchesTemplate)
bestPlateIndex = pp;
if (ppResults[pp].letters.size() >= config->postProcessMinCharacters &&
ppResults[pp].letters.size() <= config->postProcessMaxCharacters)
{
@@ -144,32 +144,32 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
}
}
plateResult.result_count = plateResult.topNPlates.size();
if (plateResult.topNPlates.size() > 0)
plateResult.bestPlate = plateResult.topNPlates[bestPlateIndex];
timespec plateEndTime;
getTime(&plateEndTime);
plateResult.processing_time_ms = diffclock(platestarttime, plateEndTime);
if (plateResult.result_count > 0)
response.push_back(plateResult);
if (config->debugGeneral)
{
rectangle(img, plateRegions[i], Scalar(0, 255, 0), 2);
for (int z = 0; z < 4; z++)
line(img, lp.plateCorners[z], lp.plateCorners[(z + 1) % 4], Scalar(255,0,255), 2);
}
}
else
{
if (config->debugGeneral)
rectangle(img, plateRegions[i], Scalar(0, 0, 255), 2);
}
}
if (config->debugTiming)
@@ -178,7 +178,7 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
getTime(&endTime);
cout << "Total Time to process image: " << diffclock(startTime, endTime) << "ms." << endl;
}
if (config->debugGeneral && config->debugShowImages)
{
displayImage(config, "Main Image", img);
@@ -191,21 +191,21 @@ std::vector<AlprResult> AlprImpl::recognize(cv::Mat img)
string AlprImpl::toJson(const vector< AlprResult > results)
{
cJSON *root = cJSON_CreateArray();
cJSON *root = cJSON_CreateArray();
for (int i = 0; i < results.size(); i++)
{
cJSON *resultObj = createJsonObj( &results[i] );
cJSON_AddItemToArray(root, resultObj);
}
// Print the JSON object to a string and return
char *out;
out=cJSON_PrintUnformatted(root);
cJSON_Delete(root);
string response(out);
free(out);
return response;
}
@@ -215,18 +215,18 @@ string AlprImpl::toJson(const vector< AlprResult > results)
cJSON* AlprImpl::createJsonObj(const AlprResult* result)
{
cJSON *root, *coords, *candidates;
root=cJSON_CreateObject();
root=cJSON_CreateObject();
cJSON_AddStringToObject(root,"plate", result->bestPlate.characters.c_str());
cJSON_AddNumberToObject(root,"confidence", result->bestPlate.overall_confidence);
cJSON_AddNumberToObject(root,"matches_template", result->bestPlate.matches_template);
cJSON_AddStringToObject(root,"region", result->region.c_str());
cJSON_AddNumberToObject(root,"region_confidence", result->regionConfidence);
cJSON_AddNumberToObject(root,"processing_time_ms", result->processing_time_ms);
cJSON_AddItemToObject(root, "coordinates", coords=cJSON_CreateArray());
for (int i=0;i<4;i++)
{
@@ -237,8 +237,8 @@ cJSON* AlprImpl::createJsonObj(const AlprResult* result)
cJSON_AddItemToArray(coords, coords_object);
}
cJSON_AddItemToObject(root, "candidates", candidates=cJSON_CreateArray());
for (int i = 0; i < result->topNPlates.size(); i++)
{
@@ -250,7 +250,7 @@ cJSON* AlprImpl::createJsonObj(const AlprResult* result)
cJSON_AddItemToArray(candidates, candidate_object);
}
return root;
}
@@ -267,4 +267,3 @@ void AlprImpl::setDefaultRegion(string region)
{
this->defaultRegion = region;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -34,7 +34,7 @@
#include <opencv2/core/core.hpp>
#include "opencv2/ocl/ocl.hpp"
#define DEFAULT_TOPN 25
@@ -48,28 +48,28 @@ class AlprImpl
virtual ~AlprImpl();
std::vector<AlprResult> recognize(cv::Mat img);
void applyRegionTemplate(AlprResult* result, std::string region);
void setDetectRegion(bool detectRegion);
void setTopN(int topn);
void setDefaultRegion(string region);
std::string toJson(const vector<AlprResult> results);
Config* config;
private:
RegionDetector* plateDetector;
StateIdentifier* stateIdentifier;
OCR* ocr;
int topN;
bool detectRegion;
std::string defaultRegion;
cJSON* createJsonObj(const AlprResult* result);
};
#endif // ALPRIMPL_H
#endif // ALPRIMPL_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -54,7 +54,7 @@ float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy) {
max_s = 0;
for (int j = y_firstth ; j<=y_lastth; j++)
for (int j = y_firstth ; j<=y_lastth; j++)
{
// Calculate the initial window at the beginning of the line
sum = sum_sq = 0;
@@ -91,7 +91,7 @@ float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy) {
map_s.fset(i+wxh, j, s);
}
}
return max_s;
}
@@ -103,9 +103,9 @@ float calcLocalStats (Mat &im, Mat &map_m, Mat &map_s, int winx, int winy) {
void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
int winx, int winy, float k) {
float dR = BINARIZEWOLF_DEFAULTDR;
float m, s, max_s;
float th=0;
double min_I, max_I;
@@ -121,11 +121,11 @@ void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
Mat map_m = Mat::zeros (im.rows, im.cols, CV_32F);
Mat map_s = Mat::zeros (im.rows, im.cols, CV_32F);
max_s = calcLocalStats (im, map_m, map_s, winx, winy);
minMaxLoc(im, &min_I, &max_I);
Mat thsurf (im.rows, im.cols, CV_32F);
// Create the threshold surface, including border processing
// ----------------------------------------------------
@@ -151,12 +151,12 @@ void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
case WOLFJOLION:
th = m + k * (s/max_s-1) * (m-min_I);
break;
default:
cerr << "Unknown threshold type in ImageThresholder::surfaceNiblackImproved()\n";
exit (1);
}
thsurf.fset(i+wxh,j,th);
if (i==0) {
@@ -205,10 +205,10 @@ void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
thsurf.fset(i,u,th);
}
for (int y=0; y<im.rows; ++y)
for (int x=0; x<im.cols; ++x)
for (int y=0; y<im.rows; ++y)
for (int x=0; x<im.cols; ++x)
{
if (im.uget(x,y) >= thsurf.fget(x,y))
{

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -30,7 +30,7 @@
using namespace std;
using namespace cv;
enum NiblackVersion
enum NiblackVersion
{
NIBLACK=0,
SAUVOLA,
@@ -53,4 +53,4 @@ void NiblackSauvolaWolfJolion (Mat im, Mat output, NiblackVersion version,
#endif // BINARIZEWOLF_H
#endif // BINARIZEWOLF_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -40,64 +40,62 @@ class CharacterAnalysis
bool hasPlateMask;
Mat plateMask;
Mat bestThreshold;
vector<vector<Point> > bestContours;
vector<Vec4i> bestHierarchy;
vector<bool> bestCharSegments;
int bestCharSegmentsCount;
LineSegment topLine;
LineSegment bottomLine;
vector<Point> linePolygon;
vector<Point> charArea;
LineSegment charBoxTop;
LineSegment charBoxBottom;
LineSegment charBoxLeft;
LineSegment charBoxRight;
bool thresholdsInverted;
vector<Mat> thresholds;
vector<vector<vector<Point> > > allContours;
vector<vector<Vec4i> > allHierarchy;
vector<vector<bool> > charSegments;
void analyze();
Mat getCharacterMask();
private:
Config* config;
Mat img_gray;
Mat findOuterBoxMask( );
bool isPlateInverted();
vector<bool> filter(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy);
vector<bool> filterByBoxSize(vector<vector<Point> > contours, vector<bool> goodIndices, int minHeightPx, int maxHeightPx);
vector<bool> filterByParentContour( vector< vector< Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<bool> filterContourHoles(vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<bool> filterByOuterMask(vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<Point> getCharArea();
vector<Point> getBestVotedLines(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices);
//vector<Point> getCharSegmentsBetweenLines(Mat img, vector<vector<Point> > contours, vector<Point> outerPolygon);
vector<bool> filterBetweenLines(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<Point> outerPolygon, vector<bool> goodIndices);
bool verifySize(Mat r, float minHeightPx, float maxHeightPx);
int getGoodIndicesCount(vector<bool> goodIndices);
};
#endif // CHARACTERANALYSIS_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,22 +25,22 @@ CharacterRegion::CharacterRegion(Mat img, Config* config)
{
this->config = config;
this->debug = config->debugCharRegions;
this->confidence = 0;
if (this->debug)
cout << "Starting CharacterRegion identification" << endl;
timespec startTime;
getTime(&startTime);
charAnalysis = new CharacterAnalysis(img, config);
charAnalysis->analyze();
if (this->debug)
{
vector<Mat> tempDash;
@@ -49,15 +49,15 @@ CharacterRegion::CharacterRegion(Mat img, Config* config)
Mat tmp(charAnalysis->thresholds[z].size(), charAnalysis->thresholds[z].type());
charAnalysis->thresholds[z].copyTo(tmp);
cvtColor(tmp, tmp, CV_GRAY2BGR);
tempDash.push_back(tmp);
}
Mat bestVal(charAnalysis->bestThreshold.size(), charAnalysis->bestThreshold.type());
charAnalysis->bestThreshold.copyTo(bestVal);
cvtColor(bestVal, bestVal, CV_GRAY2BGR);
for (int z = 0; z < charAnalysis->bestContours.size(); z++)
{
Scalar dcolor(255,0,0);
@@ -70,73 +70,73 @@ CharacterRegion::CharacterRegion(Mat img, Config* config)
}
if (this->debug)
{
/*
Mat img_contours(img_threshold.size(), CV_8U);
img_threshold.copyTo(img_contours);
cvtColor(img_contours, img_contours, CV_GRAY2RGB);
vector<vector<Point> > allowedContours;
for (int i = 0; i < contours.size(); i++)
{
if (charSegments[i])
allowedContours.push_back(contours[i]);
}
drawContours(img_contours, contours,
-1, // draw all contours
cv::Scalar(255,0,0), // in blue
1); // with a thickness of 1
drawContours(img_contours, allowedContours,
-1, // draw all contours
cv::Scalar(0,255,0), // in green
1); // with a thickness of 1
displayImage(config, "Matching Contours", img_contours);
*/
}
//charsegments = this->getPossibleCharRegions(img_threshold, allContours, allHierarchy, STARTING_MIN_HEIGHT + (bestFitIndex * HEIGHT_STEP), STARTING_MAX_HEIGHT + (bestFitIndex * HEIGHT_STEP));
if (charAnalysis->linePolygon.size() > 0)
{
int confidenceDrainers = 0;
int charSegmentCount = charAnalysis->bestCharSegmentsCount;
if (charSegmentCount == 1)
confidenceDrainers += 91;
else if (charSegmentCount < 5)
confidenceDrainers += (5 - charSegmentCount) * 10;
int absangle = abs(charAnalysis->topLine.angle);
if (absangle > 10)
confidenceDrainers += 91;
else if (absangle > 1)
confidenceDrainers += (10 - absangle) * 5;
if (confidenceDrainers >= 100)
this->confidence=1;
else
this->confidence = 100 - confidenceDrainers;
}
if (config->debugTiming)
{
timespec endTime;
getTime(&endTime);
cout << "Character Region Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
}
CharacterRegion::~CharacterRegion()
@@ -150,45 +150,43 @@ Mat CharacterRegion::getPlateMask()
{
return charAnalysis->plateMask;
}
LineSegment CharacterRegion::getTopLine()
{
return charAnalysis->topLine;
return charAnalysis->topLine;
}
LineSegment CharacterRegion::getBottomLine()
{
return charAnalysis->bottomLine;
return charAnalysis->bottomLine;
}
vector<Point> CharacterRegion::getCharArea()
{
return charAnalysis->charArea;
return charAnalysis->charArea;
}
LineSegment CharacterRegion::getCharBoxTop()
{
return charAnalysis->charBoxTop;
return charAnalysis->charBoxTop;
}
LineSegment CharacterRegion::getCharBoxBottom()
{
return charAnalysis->charBoxBottom;
return charAnalysis->charBoxBottom;
}
LineSegment CharacterRegion::getCharBoxLeft()
{
return charAnalysis->charBoxLeft;
return charAnalysis->charBoxLeft;
}
LineSegment CharacterRegion::getCharBoxRight()
{
return charAnalysis->charBoxRight;
return charAnalysis->charBoxRight;
}
bool CharacterRegion::thresholdsInverted()
{
return charAnalysis->thresholdsInverted;
return charAnalysis->thresholdsInverted;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -40,47 +40,45 @@ class CharacterRegion
virtual ~CharacterRegion();
CharacterAnalysis *charAnalysis;
int confidence;
Mat getPlateMask();
LineSegment getTopLine();
LineSegment getBottomLine();
//vector<Point> getLinePolygon();
vector<Point> getCharArea();
LineSegment getCharBoxTop();
LineSegment getCharBoxBottom();
LineSegment getCharBoxLeft();
LineSegment getCharBoxRight();
bool thresholdsInverted();
protected:
Config* config;
bool debug;
Mat findOuterBoxMask(vector<Mat> thresholds, vector<vector<vector<Point> > > allContours, vector<vector<Vec4i> > allHierarchy);
vector<bool> filter(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy);
vector<bool> filterByBoxSize(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices, float minHeightPx, float maxHeightPx);
vector<bool> filterByParentContour( vector< vector< Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<bool> filterContourHoles(vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<Point> getBestVotedLines(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices);
//vector<Point> getCharSegmentsBetweenLines(Mat img, vector<vector<Point> > contours, vector<Point> outerPolygon);
vector<bool> filterBetweenLines(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<Point> outerPolygon, vector<bool> goodIndices);
Mat getCharacterMask(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<Rect> wrapContours(vector<vector<Point> > contours);
bool verifySize(Mat r, float minHeightPx, float maxHeightPx);
int getGoodIndicesCount(vector<bool> goodIndices);
bool isPlateInverted(Mat threshold, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
};
#endif // CHARACTERREGION_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -53,53 +53,51 @@ class CharacterSegmenter
vector<Rect> characters;
int confidence;
vector<Mat> getThresholds();
private:
Config* config;
CharacterAnalysis* charAnalysis;
LineSegment top;
LineSegment bottom;
vector<Mat> imgDbgGeneral;
vector<Mat> imgDbgCleanStages;
vector<bool> filter(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy);
vector<bool> filterByBoxSize(vector< vector< Point> > contours, vector<bool> goodIndices, float minHeightPx, float maxHeightPx);
vector<bool> filterBetweenLines(Mat img, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<Point> outerPolygon, vector<bool> goodIndices);
vector<bool> filterContourHoles(vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
vector<Point> getBestVotedLines(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices);
int getGoodIndicesCount(vector<bool> goodIndices);
Mat getCharacterMask(Mat img_threshold, vector<vector<Point> > contours, vector<Vec4i> hierarchy, vector<bool> goodIndices);
Mat getCharBoxMask(Mat img_threshold, vector<Rect> charBoxes);
void removeSmallContours(vector<Mat> thresholds, vector<vector<vector<Point > > > allContours, float avgCharWidth, float avgCharHeight);
Mat getVerticalHistogram(Mat img, Mat mask);
vector<Rect> getHistogramBoxes(VerticalHistogram histogram, float avgCharWidth, float avgCharHeight, float* score);
vector<Rect> getBestCharBoxes(Mat img, vector<Rect> charBoxes, float avgCharWidth);
vector<Rect> combineCloseBoxes( vector<Rect> charBoxes, float avgCharWidth);
vector<Rect> get1DHits(Mat img, int yOffset);
void cleanCharRegions(vector<Mat> thresholds, vector<Rect> charRegions);
void cleanBasedOnColor(vector<Mat> thresholds, Mat colorMask, vector<Rect> charRegions);
void cleanMostlyFullBoxes(vector<Mat> thresholds, const vector<Rect> charRegions);
vector<Rect> filterMostlyEmptyBoxes(vector<Mat> thresholds, const vector<Rect> charRegions);
void filterEdgeBoxes(vector<Mat> thresholds, const vector<Rect> charRegions, float avgCharWidth, float avgCharHeight);
int getLongestBlobLengthBetweenLines(Mat img, int col);
int isSkinnyLineInsideBox(Mat threshold, Rect box, vector<vector<Point> > contours, vector<Vec4i> hierarchy, float avgCharWidth, float avgCharHeight);
vector<Point> getEncapsulatingLines(Mat img, vector<vector<Point> > contours, vector<bool> goodIndices);
};
#endif // CHARACTERSEGMENTER_H

View File

@@ -107,7 +107,7 @@ static const char *parse_number(cJSON *item,const char *num)
}
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
@@ -156,12 +156,12 @@ static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;} /* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
@@ -190,7 +190,7 @@ static const char *parse_string(cJSON *item,const char *str)
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
@@ -215,10 +215,10 @@ static const char *parse_string(cJSON *item,const char *str)
static char *print_string_ptr(const char *str)
{
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
@@ -351,7 +351,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
char *out=0,*ptr,*ret;int len=5;
cJSON *child=item->child;
int numentries=0,i=0,fail=0;
/* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Explicitly handle numentries==0 */
@@ -374,7 +374,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
child=child->next;
}
/* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
@@ -387,7 +387,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
cJSON_free(entries);
return 0;
}
/* Compose the output array. */
*out='[';
ptr=out+1;*ptr=0;
@@ -399,7 +399,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
}
cJSON_free(entries);
*ptr++=']';*ptr++=0;
return out;
return out;
}
/* Build an object from the text. */
@@ -407,11 +407,11 @@ static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return 0;} /* not an object! */
item->type=cJSON_Object;
value=skip(value+1);
if (*value=='}') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0;
value=skip(parse_string(child,skip(value)));
@@ -420,7 +420,7 @@ static const char *parse_object(cJSON *item,const char *value)
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
@@ -433,7 +433,7 @@ static const char *parse_object(cJSON *item,const char *value)
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
}
if (*value=='}') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
@@ -474,7 +474,7 @@ static char *print_object(cJSON *item,int depth,int fmt)
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
child=child->next;
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=1;
@@ -486,7 +486,7 @@ static char *print_object(cJSON *item,int depth,int fmt)
cJSON_free(names);cJSON_free(entries);
return 0;
}
/* Compose the output: */
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
for (i=0;i<numentries;i++)
@@ -499,11 +499,11 @@ static char *print_object(cJSON *item,int depth,int fmt)
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
return out;
return out;
}
/* Get Array size/item / object item. */
@@ -593,4 +593,4 @@ void cJSON_Minify(char *json)
else *into++=*json++; // All other characters.
}
*into=0; // and null-terminate.
}
}

View File

@@ -1,16 +1,16 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -36,7 +36,7 @@ extern "C"
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
/* The cJSON structure: */
@@ -80,7 +80,7 @@ extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
@@ -109,7 +109,7 @@ extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -24,31 +24,31 @@
ColorFilter::ColorFilter(Mat image, Mat characterMask, Config* config)
{
timespec startTime;
getTime(&startTime);
this->config = config;
this->debug = config->debugColorFiler;
this->grayscale = imageIsGrayscale(image);
if (this->debug)
cout << "ColorFilter: isGrayscale = " << grayscale << endl;
this->hsv = Mat(image.size(), image.type());
cvtColor( image, this->hsv, CV_BGR2HSV );
preprocessImage();
this->charMask = characterMask;
this->colorMask = Mat(image.size(), CV_8U);
findCharColors();
if (config->debugTiming)
{
timespec endTime;
@@ -72,7 +72,7 @@ bool ColorFilter::imageIsGrayscale(Mat image)
int r = (int) image.at<Vec3b>(row, col)[0];
int g = (int) image.at<Vec3b>(row, col)[1];
int b = (int) image.at<Vec3b>(row, col)[2];
if (r == g == b)
{
// So far so good
@@ -84,7 +84,7 @@ bool ColorFilter::imageIsGrayscale(Mat image)
}
}
}
return true;
}
@@ -94,7 +94,7 @@ void ColorFilter::preprocessImage()
vector<Mat> channels;
split(this->hsv,channels);
Mat img_equalized = equalizeBrightness(channels[2]);
merge(channels,this->hsv);
merge(channels,this->hsv);
}
// Gets the hue/sat/val for areas that we believe are license plate characters
@@ -102,14 +102,14 @@ void ColorFilter::preprocessImage()
void ColorFilter::findCharColors()
{
int MINIMUM_SATURATION = 45;
if (this->debug)
cout << "ColorFilter::findCharColors" << endl;
//charMask.copyTo(this->colorMask);
this->colorMask = Mat::zeros(charMask.size(), CV_8U);
bitwise_not(this->colorMask, this->colorMask);
Mat erodedCharMask(charMask.size(), CV_8U);
Mat element = getStructuringElement( 1,
Size( 2 + 1, 2+1 ),
@@ -120,80 +120,80 @@ void ColorFilter::findCharColors()
vector<Vec4i> hierarchy;
findContours(erodedCharMask, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
vector<float> hMeans, sMeans, vMeans;
vector<float> hStdDevs, sStdDevs, vStdDevs;
for (int i = 0; i < contours.size(); i++)
{
if (hierarchy[i][3] != -1)
continue;
Mat singleCharMask = Mat::zeros(hsv.size(), CV_8U);
drawContours(singleCharMask, contours,
i, // draw this contour
cv::Scalar(255,255,255), // in
CV_FILLED,
8,
cv::Scalar(255,255,255), // in
CV_FILLED,
8,
hierarchy
);
);
// get rid of the outline by drawing a 1 pixel width black line
drawContours(singleCharMask, contours,
i, // draw this contour
cv::Scalar(0,0,0), // in
1,
8,
cv::Scalar(0,0,0), // in
1,
8,
hierarchy
);
);
//drawAndWait(&singleCharMask);
Scalar mean;
Scalar stddev;
meanStdDev(hsv, mean, stddev, singleCharMask);
if (this->debug)
{
cout << "ColorFilter " << setw(3) << i << ". Mean: h: " << setw(7) << mean[0] << " s: " << setw(7) <<mean[1] << " v: " << setw(7) << mean[2]
cout << "ColorFilter " << setw(3) << i << ". Mean: h: " << setw(7) << mean[0] << " s: " << setw(7) <<mean[1] << " v: " << setw(7) << mean[2]
<< " | Std: h: " << setw(7) <<stddev[0] << " s: " << setw(7) <<stddev[1] << " v: " << stddev[2] << endl;
}
if (mean[0] == 0 && mean[1] == 0 && mean[2] == 0)
continue;
hMeans.push_back(mean[0]);
sMeans.push_back(mean[1]);
vMeans.push_back(mean[2]);
hStdDevs.push_back(stddev[0]);
sStdDevs.push_back(stddev[1]);
vStdDevs.push_back(stddev[2]);
}
if (hMeans.size() == 0)
return;
int bestHueIndex = this->getMajorityOpinion(hMeans, .65, 30);
int bestSatIndex = this->getMajorityOpinion(sMeans, .65, 35);
int bestValIndex = this->getMajorityOpinion(vMeans, .65, 30);
if (sMeans[bestSatIndex] < MINIMUM_SATURATION)
return;
bool doHueFilter = false, doSatFilter = false, doValFilter = false;
float hueMin, hueMax;
float satMin, satMax;
float valMin, valMax;
if (this->debug)
cout << "ColorFilter Winning indices:" << endl;
if (bestHueIndex != -1)
@@ -201,64 +201,64 @@ void ColorFilter::findCharColors()
doHueFilter = true;
hueMin = hMeans[bestHueIndex] - (2 * hStdDevs[bestHueIndex]);
hueMax = hMeans[bestHueIndex] + (2 * hStdDevs[bestHueIndex]);
if (abs(hueMin - hueMax) < 20)
{
hueMin = hMeans[bestHueIndex] - 20;
hueMax = hMeans[bestHueIndex] + 20;
}
if (hueMin < 0)
hueMin = 0;
if (hueMax > 180)
hueMax = 180;
if (this->debug)
cout << "ColorFilter Hue: " << bestHueIndex << " : " << setw(7) << hMeans[bestHueIndex] << " -- " << hueMin << "-" << hueMax << endl;
}
if (bestSatIndex != -1)
{
doSatFilter = true;
satMin = sMeans[bestSatIndex] - (2 * sStdDevs[bestSatIndex]);
satMax = sMeans[bestSatIndex] + (2 * sStdDevs[bestSatIndex]);
if (abs(satMin - satMax) < 20)
{
satMin = sMeans[bestSatIndex] - 20;
satMax = sMeans[bestSatIndex] + 20;
}
if (satMin < 0)
satMin = 0;
if (satMax > 255)
satMax = 255;
if (this->debug)
cout << "ColorFilter Sat: " << bestSatIndex << " : " << setw(7) << sMeans[bestSatIndex] << " -- " << satMin << "-" << satMax << endl;
}
if (bestValIndex != -1)
{
doValFilter = true;
valMin = vMeans[bestValIndex] - (1.5 * vStdDevs[bestValIndex]);
valMax = vMeans[bestValIndex] + (1.5 * vStdDevs[bestValIndex]);
if (abs(valMin - valMax) < 20)
{
valMin = vMeans[bestValIndex] - 20;
valMax = vMeans[bestValIndex] + 20;
}
if (valMin < 0)
valMin = 0;
if (valMax > 255)
valMax = 255;
if (this->debug)
cout << "ColorFilter Val: " << bestValIndex << " : " << setw(7) << vMeans[bestValIndex] << " -- " << valMin << "-" << valMax << endl;
}
Mat imgDebugHueOnly = Mat::zeros(hsv.size(), hsv.type());
@@ -266,7 +266,7 @@ void ColorFilter::findCharColors()
Mat imgDistanceFromCenter = Mat::zeros(hsv.size(), CV_8U);
Mat debugMask = Mat::zeros(hsv.size(), CV_8U);
bitwise_not(debugMask, debugMask);
for (int row = 0; row < charMask.rows; row++)
{
for (int col = 0; col < charMask.cols; col++)
@@ -274,21 +274,21 @@ void ColorFilter::findCharColors()
int h = (int) hsv.at<Vec3b>(row, col)[0];
int s = (int) hsv.at<Vec3b>(row, col)[1];
int v = (int) hsv.at<Vec3b>(row, col)[2];
bool hPasses = true;
bool sPasses = true;
bool vPasses = true;
int vDistance = abs(v - vMeans[bestValIndex]);
imgDebugHueOnly.at<Vec3b>(row, col)[0] = h;
imgDebugHueOnly.at<Vec3b>(row, col)[1] = 255;
imgDebugHueOnly.at<Vec3b>(row, col)[2] = 255;
imgDebug.at<Vec3b>(row, col)[0] = 255;
imgDebug.at<Vec3b>(row, col)[1] = 255;
imgDebug.at<Vec3b>(row, col)[2] = 255;
if (doHueFilter && (h < hueMin || h > hueMax))
{
hPasses = false;
@@ -305,20 +305,20 @@ void ColorFilter::findCharColors()
vPasses = false;
imgDebug.at<Vec3b>(row, col)[2] = 0;
}
//if (pixelPasses)
// colorMask.at<uchar>(row, col) = 255;
//else
//imgDebug.at<Vec3b>(row, col)[0] = hPasses & 255;
//imgDebug.at<Vec3b>(row, col)[1] = sPasses & 255;
//imgDebug.at<Vec3b>(row, col)[2] = vPasses & 255;
if ((hPasses) || (hPasses && sPasses))//(hPasses && vPasses) || (sPasses && vPasses) ||
this->colorMask.at<uchar>(row, col) = 255;
else
this->colorMask.at<uchar>(row, col) = 0;
if ((hPasses && sPasses) || (hPasses && vPasses) || (sPasses && vPasses))
{
vDistance = pow(vDistance, 0.9);
@@ -332,11 +332,11 @@ void ColorFilter::findCharColors()
imgDistanceFromCenter.at<uchar>(row, col) = vDistance;
}
}
vector<Mat> debugImagesSet;
if (this->debug)
{
debugImagesSet.push_back(addLabel(charMask, "Charecter mask"));
@@ -345,40 +345,40 @@ void ColorFilter::findCharColors()
colorMask.copyTo(maskCopy);
debugImagesSet.push_back(addLabel(maskCopy, "color Mask Before"));
}
Mat bigElement = getStructuringElement( 1,
Size( 3 + 1, 3+1 ),
Point( 1, 1 ) );
Mat smallElement = getStructuringElement( 1,
Size( 1 + 1, 1+1 ),
Point( 1, 1 ) );
morphologyEx(this->colorMask, this->colorMask, MORPH_CLOSE, bigElement);
//dilate(this->colorMask, this->colorMask, bigElement);
Mat combined(charMask.size(), charMask.type());
bitwise_and(charMask, colorMask, combined);
if (this->debug)
{
debugImagesSet.push_back(addLabel(colorMask, "Color Mask After"));
debugImagesSet.push_back(addLabel(combined, "Combined"));
//displayImage(config, "COLOR filter Mask", colorMask);
debugImagesSet.push_back(addLabel(imgDebug, "Color filter Debug"));
cvtColor(imgDebugHueOnly, imgDebugHueOnly, CV_HSV2BGR);
debugImagesSet.push_back(addLabel(imgDebugHueOnly, "Color Filter Hue"));
equalizeHist(imgDistanceFromCenter, imgDistanceFromCenter);
debugImagesSet.push_back(addLabel(imgDistanceFromCenter, "COLOR filter Distance"));
debugImagesSet.push_back(addLabel(debugMask, "COLOR Hues off"));
Mat dashboard = drawImageDashboard(debugImagesSet, imgDebugHueOnly.type(), 3);
displayImage(config, "Color Filter Images", dashboard);
}
@@ -394,7 +394,7 @@ int ColorFilter::getMajorityOpinion(vector<float> values, float minPercentAgreem
float bestPercentAgreement = 0;
float lowestOverallDiff = 1000000000;
int bestPercentAgreementIndex = -1;
for (int i = 0; i < values.size(); i++)
{
int valuesInRange = 0;
@@ -404,10 +404,10 @@ int ColorFilter::getMajorityOpinion(vector<float> values, float minPercentAgreem
float diff = abs(values[i] - values[j]);
if (diff < maxValDifference)
valuesInRange++;
overallDiff += diff;
}
float percentAgreement = ((float) valuesInRange) / ((float) values.size());
if (overallDiff < lowestOverallDiff && percentAgreement >= bestPercentAgreement && percentAgreement >= minPercentAgreement)
{
@@ -416,6 +416,6 @@ int ColorFilter::getMajorityOpinion(vector<float> values, float minPercentAgreem
lowestOverallDiff = overallDiff;
}
}
return bestPercentAgreementIndex;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -43,23 +43,23 @@ class ColorFilter
Mat colorMask;
private:
Config* config;
bool debug;
Mat hsv;
Mat charMask;
bool grayscale;
void preprocessImage();
void findCharColors();
bool imageIsGrayscale(Mat image);
int getMajorityOpinion(vector<float> values, float minPercentAgreement, float maxValDifference);
};
#endif // COLORFILTER_H
#endif // COLORFILTER_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,15 +23,15 @@
Config::Config(const std::string country, const std::string runtimeBaseDir)
{
this->runtimeBaseDir = runtimeBaseDir;
ini = new CSimpleIniA();
char* envRuntimeDir;
envRuntimeDir = getenv (ENV_VARIABLE_RUNTIME_DIR);
if (runtimeBaseDir.compare("") != 0)
{
// User has supplied a runtime directory. Use that.
}
else if (envRuntimeDir!=NULL)
{
@@ -43,9 +43,9 @@ Config::Config(const std::string country, const std::string runtimeBaseDir)
// Use the default
this->runtimeBaseDir = DEFAULT_RUNTIME_DIR;
}
string configFile = (this->runtimeBaseDir + CONFIG_FILE);
if (DirectoryExists(this->runtimeBaseDir.c_str()) == false)
{
std::cerr << "--(!)Runtime directory '" << this->runtimeBaseDir << "' does not exist!" << endl;
@@ -56,11 +56,11 @@ Config::Config(const std::string country, const std::string runtimeBaseDir)
std::cerr << "--(!)Runtime directory '" << this->runtimeBaseDir << "' does not contain a config file '" << CONFIG_FILE << "'!" << endl;
return;
}
ini->LoadFile(configFile.c_str());
this->country = country;
loadValues(country);
}
Config::~Config()
@@ -70,56 +70,56 @@ Config::~Config()
void Config::loadValues(string country)
{
opencl_enabled = getBoolean("common", "opencl_enabled", false);
maxPlateWidthPercent = getFloat("common", "max_plate_width_percent", 100);
maxPlateHeightPercent = getFloat("common", "max_plate_height_percent", 100);
minPlateSizeWidthPx = getInt(country, "min_plate_size_width_px", 100);
minPlateSizeHeightPx = getInt(country, "min_plate_size_height_px", 100);
plateWidthMM = getFloat(country, "plate_width_mm", 100);
plateHeightMM = getFloat(country, "plate_height_mm", 100);
charHeightMM = getFloat(country, "char_height_mm", 100);
charWidthMM = getFloat(country, "char_width_mm", 100);
charWhitespaceTopMM = getFloat(country, "char_whitespace_top_mm", 100);
charWhitespaceBotMM = getFloat(country, "char_whitespace_bot_mm", 100);
templateWidthPx = getInt(country, "template_max_width_px", 100);
templateHeightPx = getInt(country, "template_max_height_px", 100);
float ocrImagePercent = getFloat("common", "ocr_img_size_percent", 100);
ocrImageWidthPx = round(((float) templateWidthPx) * ocrImagePercent);
ocrImageHeightPx = round(((float)templateHeightPx) * ocrImagePercent);
float stateIdImagePercent = getFloat("common", "state_id_img_size_percent", 100);
stateIdImageWidthPx = round(((float)templateWidthPx) * ocrImagePercent);
stateIdimageHeightPx = round(((float)templateHeightPx) * ocrImagePercent);
charAnalysisMinPercent = getFloat(country, "char_analysis_min_pct", 0);
charAnalysisHeightRange = getFloat(country, "char_analysis_height_range", 0);
charAnalysisHeightStepSize = getFloat(country, "char_analysis_height_step_size", 0);
charAnalysisNumSteps = getInt(country, "char_analysis_height_num_steps", 0);
segmentationMinBoxWidthPx = getInt(country, "segmentation_min_box_width_px", 0);
segmentationMinCharHeightPercent = getFloat(country, "segmentation_min_charheight_percent", 0);
segmentationMaxCharWidthvsAverage = getFloat(country, "segmentation_max_segment_width_percent_vs_average", 0);
plateLinesSensitivityVertical = getFloat(country, "plateline_sensitivity_vertical", 0);
plateLinesSensitivityHorizontal = getFloat(country, "plateline_sensitivity_horizontal", 0);
ocrLanguage = getString(country, "ocr_language", "none");
ocrMinFontSize = getInt("common", "ocr_min_font_point", 100);
postProcessMinConfidence = getFloat("common", "postprocess_min_confidence", 100);
postProcessConfidenceSkipLevel = getFloat("common", "postprocess_confidence_skip_level", 100);
postProcessMaxSubstitutions = getInt("common", "postprocess_max_substitutions", 100);
postProcessMinCharacters = getInt("common", "postprocess_min_characers", 100);
postProcessMaxCharacters = getInt("common", "postprocess_max_characers", 100);
debugGeneral = getBoolean("debug", "general", false);
debugTiming = getBoolean("debug", "timing", false);
debugStateId = getBoolean("debug", "state_id", false);
@@ -132,7 +132,7 @@ void Config::loadValues(string country)
debugOcr = getBoolean("debug", "ocr", false);
debugPostProcess = getBoolean("debug", "postprocess", false);
debugShowImages = getBoolean("debug", "show_images", false);
}
void Config::debugOff()
@@ -179,7 +179,7 @@ float Config::getFloat(string section, string key, float defaultValue)
std::cout << "Error: missing configuration entry for: " << section << "->" << key << endl;
return defaultValue;
}
float val = atof(pszValue);
return val;
}
@@ -191,7 +191,7 @@ int Config::getInt(string section, string key, int defaultValue)
std::cout << "Error: missing configuration entry for: " << section << "->" << key << endl;
return defaultValue;
}
int val = atoi(pszValue);
return val;
}
@@ -203,7 +203,7 @@ bool Config::getBoolean(string section, string key, bool defaultValue)
std::cout << "Error: missing configuration entry for: " << section << "->" << key << endl;
return defaultValue;
}
int val = atoi(pszValue);
return val != 0;
}
@@ -215,7 +215,7 @@ string Config::getString(string section, string key, string defaultValue)
std::cout << "Error: missing configuration entry for: " << section << "->" << key << endl;
return defaultValue;
}
string val = string(pszValue);
return val;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -42,54 +42,54 @@ class Config
virtual ~Config();
string country;
bool opencl_enabled;
float maxPlateWidthPercent;
float maxPlateHeightPercent;
float minPlateSizeWidthPx;
float minPlateSizeHeightPx;
float plateWidthMM;
float plateHeightMM;
float charHeightMM;
float charWidthMM;
float charWhitespaceTopMM;
float charWhitespaceBotMM;
int templateWidthPx;
int templateHeightPx;
int ocrImageWidthPx;
int ocrImageHeightPx;
int stateIdImageWidthPx;
int stateIdimageHeightPx;
float charAnalysisMinPercent;
float charAnalysisHeightRange;
float charAnalysisHeightStepSize;
int charAnalysisNumSteps;
float plateLinesSensitivityVertical;
float plateLinesSensitivityHorizontal;
int segmentationMinBoxWidthPx;
float segmentationMinCharHeightPercent;
float segmentationMaxCharWidthvsAverage;
string ocrLanguage;
int ocrMinFontSize;
float postProcessMinConfidence;
float postProcessConfidenceSkipLevel;
int postProcessMaxSubstitutions;
int postProcessMinCharacters;
int postProcessMaxCharacters;
bool debugGeneral;
bool debugTiming;
bool debugStateId;
@@ -102,9 +102,9 @@ class Config
bool debugOcr;
bool debugPostProcess;
bool debugShowImages;
void debugOff();
string getKeypointsRuntimeDir();
string getCascadeRuntimeDir();
string getPostProcessRuntimeDir();
@@ -114,9 +114,9 @@ private:
CSimpleIniA* ini;
string runtimeBaseDir;
void loadValues(string country);
int getInt(string section, string key, int defaultValue);
float getFloat(string section, string key, float defaultValue);
string getString(string section, string key, string defaultValue);
@@ -124,4 +124,4 @@ private:
};
#endif // CONFIG_H
#endif // CONFIG_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -26,4 +26,4 @@
#define DEFAULT_RUNTIME_DIR "/default_runtime_data_dir/"
#endif
#define ENV_VARIABLE_RUNTIME_DIR "OPENALPR_RUNTIME_DIR"
#define ENV_VARIABLE_RUNTIME_DIR "OPENALPR_RUNTIME_DIR"

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -29,13 +29,13 @@ const float MAX_DISTANCE_TO_MATCH = 100.0f;
FeatureMatcher::FeatureMatcher(Config* config)
{
this->config = config;
//this->descriptorMatcher = DescriptorMatcher::create( "BruteForce-HammingLUT" );
this->descriptorMatcher = new BFMatcher(NORM_HAMMING, false);
//this->descriptorMatcher = DescriptorMatcher::create( "FlannBased" );
this->detector = new FastFeatureDetector(10, true);
this->extractor = new BRISK(10, 1, 0.9);
}
@@ -45,11 +45,11 @@ FeatureMatcher::~FeatureMatcher()
for (int i = 0; i < trainingImgKeypoints.size(); i++)
trainingImgKeypoints[i].clear();
trainingImgKeypoints.clear();
descriptorMatcher.release();
detector.release();
extractor.release();
}
@@ -59,7 +59,7 @@ bool FeatureMatcher::isLoaded()
{
return false;
}
return true;
}
@@ -75,13 +75,13 @@ void FeatureMatcher::surfStyleMatching( const Mat& queryDescriptors, vector<KeyP
vector<DMatch>& matches12 )
{
vector<vector<DMatch> > matchesKnn;
this->descriptorMatcher->radiusMatch(queryDescriptors, matchesKnn, MAX_DISTANCE_TO_MATCH);
vector<DMatch> tempMatches;
_surfStyleMatching(queryDescriptors, matchesKnn, tempMatches);
crisscrossFiltering(queryKeypoints, tempMatches, matches12);
}
@@ -101,13 +101,13 @@ 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
if (matchesKnn[descInd].size() > 1)
{
// Next throw out matches with a crappy score
// Ignore... already handled by the radiusMatch
//if (matchesKnn[descInd][0].distance < MAX_DISTANCE_TO_MATCH)
//{
float ratioThreshold = 0.75;
// Check if both matches came from the same image. If they both came from the same image, score them slightly less harshly
if (matchesKnn[descInd][0].imgIdx == matchesKnn[descInd][1].imgIdx)
{
@@ -125,20 +125,20 @@ void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vect
already_exists = true;
break;
}
else if ((matchesKnn[descInd][0].trainIdx == matches12[q].trainIdx) &&
else if ((matchesKnn[descInd][0].trainIdx == matches12[q].trainIdx) &&
(matchesKnn[descInd][0].imgIdx == matches12[q].imgIdx))
{
already_exists = true;
break;
}
}
// Good match.
if (already_exists == false)
matches12.push_back(matchesKnn[descInd][0]);
}
//}
}
else if (matchesKnn[descInd].size() == 1)
@@ -149,28 +149,28 @@ void FeatureMatcher::_surfStyleMatching(const Mat& queryDescriptors, vector<vect
// In the ratio test, we will compare the quality of a match with the next match that is not from the same object:
// we can accept several matches with similar scores as long as they are for the same object. Those should not be
// part of the model anyway as they are not discriminative enough
//for (unsigned int first_index = 0; first_index < matches.size(); ++first_index)
//{
//matches12.push_back(match);
//}
}
}
// 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
void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches)
{
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
for (int i = 0; i < billMapping.size(); i++)
{
vector<DMatch> matchesForOnePlate;
@@ -179,32 +179,32 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
if (inputMatches[j].imgIdx == i)
matchesForOnePlate.push_back(inputMatches[j]);
}
// For each plate, compare the lines for the keypoints (training image and query image)
// go through each line between keypoints and filter out matches that are criss-crossing
vector<LineSegment> vlines;
vector<LineSegment> hlines;
vector<int> matchIdx;
for (int j = 0; j < matchesForOnePlate.size(); j++)
{
KeyPoint tkp = trainingImgKeypoints[i][matchesForOnePlate[j].trainIdx];
KeyPoint qkp = queryKeypoints[matchesForOnePlate[j].queryIdx];
vlines.push_back(LineSegment(tkp.pt.x, tkp.pt.y + config->stateIdimageHeightPx, qkp.pt.x, qkp.pt.y));
hlines.push_back(LineSegment(tkp.pt.x, tkp.pt.y, qkp.pt.x + config->stateIdImageWidthPx, qkp.pt.y));
matchIdx.push_back(j);
}
// Iterate through each line (n^2) removing the one with the most criss-crosses until there are none left.
int mostIntersections = 1;
while (mostIntersections > 0 && vlines.size() > 0)
{
int mostIntersectionsIndex = -1;
mostIntersections = 0;
for (int j = 0; j < vlines.size(); j++)
{
int intrCount = 0;
@@ -223,14 +223,14 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
intrCount++;
}
}
if (intrCount > mostIntersections)
{
mostIntersections = intrCount;
mostIntersectionsIndex = j;
}
}
if (mostIntersectionsIndex >= 0)
{
if (this->config->debugStateId)
@@ -239,75 +239,75 @@ void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints,
hlines.erase(hlines.begin() + mostIntersectionsIndex);
matchIdx.erase(matchIdx.begin() + mostIntersectionsIndex);
}
}
// Push the non-crisscrosses back on the list
for (int j = 0; j < matchIdx.size(); j++)
{
outputMatches.push_back(matchesForOnePlate[matchIdx[j]]);
}
}
}
// Returns true if successful, false otherwise
bool FeatureMatcher::loadRecognitionSet(string country)
{
std::ostringstream out;
std::ostringstream out;
out << config->getKeypointsRuntimeDir() << "/" << country << "/";
string country_dir = out.str();
if (DirectoryExists(country_dir.c_str()))
{
vector<Mat> trainImages;
vector<string> plateFiles = getFilesInDir(country_dir.c_str());
for (int i = 0; i < plateFiles.size(); i++)
{
if (hasEnding(plateFiles[i], ".jpg") == false)
continue;
string fullpath = country_dir + plateFiles[i];
Mat img = imread( fullpath );
// convert to gray and resize to the size of the templates
cvtColor(img, img, CV_BGR2GRAY);
resize(img, img, getSizeMaintainingAspect(img, config->stateIdImageWidthPx, config->stateIdimageHeightPx));
if( img.empty() )
{
cout << "Can not read images" << endl;
return -1;
}
Mat descriptors;
vector<KeyPoint> keypoints;
detector->detect( img, keypoints );
extractor->compute(img, keypoints, descriptors);
if (descriptors.cols > 0)
{
billMapping.push_back(plateFiles[i].substr(0, 2));
trainImages.push_back(descriptors);
trainingImgKeypoints.push_back(keypoints);
}
}
this->descriptorMatcher->add(trainImages);
this->descriptorMatcher->train();
return true;
}
return false;
}
@@ -317,16 +317,16 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
)
{
RecognitionResult result;
result.haswinner = false;
Mat queryDescriptors;
vector<KeyPoint> queryKeypoints;
detector->detect( queryImg, queryKeypoints );
extractor->compute(queryImg, queryKeypoints, queryDescriptors);
if (queryKeypoints.size() <= 5)
{
@@ -337,27 +337,27 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
}
return result;
}
vector<DMatch> filteredMatches;
surfStyleMatching( queryDescriptors, queryKeypoints, filteredMatches );
// Create and initialize the counts to 0
std::vector<int> bill_match_counts( billMapping.size() );
for (int i = 0; i < billMapping.size(); i++) { bill_match_counts[i] = 0; }
for (int i = 0; i < filteredMatches.size(); i++)
{
bill_match_counts[filteredMatches[i].imgIdx]++;
//if (filteredMatches[i].imgIdx
}
float max_count = 0; // represented as a percent (0 to 100)
int secondmost_count = 0;
int maxcount_index = -1;
@@ -368,25 +368,25 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
secondmost_count = max_count;
if (secondmost_count <= 2) // A value of 1 or 2 is effectively 0
secondmost_count = 0;
max_count = bill_match_counts[i];
maxcount_index = i;
}
}
float score = ((max_count - secondmost_count - 3) / 10) * 100;
if (score < 0)
score = 0;
else if (score > 100)
score = 100;
if (score > 0)
{
result.haswinner = true;
result.winner = billMapping[maxcount_index];
result.confidence = score;
if (drawOnImage)
{
vector<KeyPoint> positiveMatches;
@@ -397,36 +397,35 @@ RecognitionResult FeatureMatcher::recognize( const Mat& queryImg, bool drawOnIma
positiveMatches.push_back( queryKeypoints[filteredMatches[i].queryIdx] );
}
}
Mat tmpImg;
drawKeypoints( queryImg, queryKeypoints, tmpImg, CV_RGB(185, 0, 0), DrawMatchesFlags::DEFAULT );
drawKeypoints( tmpImg, positiveMatches, *outputImage, CV_RGB(0, 255, 0), DrawMatchesFlags::DEFAULT );
if (result.haswinner == true)
{
std::ostringstream out;
std::ostringstream out;
out << result.winner << " (" << result.confidence << "%)";
// we detected a bill, let the people know!
//putText(*outputImage, out.str(), Point(15, 27), FONT_HERSHEY_DUPLEX, 1.1, CV_RGB(0, 0, 0), 2);
}
}
}
if (this->config->debugStateId)
{
for (int i = 0; i < billMapping.size(); i++)
{
cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
}
}
return result;
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -55,31 +55,31 @@ class FeatureMatcher
RecognitionResult recognize( const Mat& queryImg, bool drawOnImage, Mat* outputImage,
bool debug_on, vector<int> debug_matches_array );
bool loadRecognitionSet(string country);
bool isLoaded();
int numTrainingElements();
private:
Config* config;
Ptr<DescriptorMatcher> descriptorMatcher;
Ptr<FastFeatureDetector> detector;
Ptr<BRISK> extractor;
vector<vector<KeyPoint> > trainingImgKeypoints;
vector<vector<KeyPoint> > trainingImgKeypoints;
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);
vector<string> billMapping;
void surfStyleMatching( const Mat& queryDescriptors, vector<KeyPoint> queryKeypoints,
@@ -88,5 +88,3 @@ class FeatureMatcher
};
#endif // FEATUREMATCHER_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,7 +23,7 @@
LicensePlateCandidate::LicensePlateCandidate(Mat frame, Rect regionOfInterest, Config* config)
{
this->config = config;
this->frame = frame;
this->plateRegion = regionOfInterest;
}
@@ -37,61 +37,61 @@ LicensePlateCandidate::~LicensePlateCandidate()
void LicensePlateCandidate::recognize()
{
charSegmenter = NULL;
this->confidence = 0;
int expandX = round(this->plateRegion.width * 0.15);
int expandY = round(this->plateRegion.height * 0.10);
// expand box by 15% in all directions
Rect expandedRegion = expandRect( this->plateRegion, expandX, expandY, frame.cols, frame.rows) ;
Mat plate_bgr = Mat(frame, expandedRegion);
resize(plate_bgr, plate_bgr, Size(config->templateWidthPx, config->templateHeightPx));
Mat plate_bgr_cleaned = Mat(plate_bgr.size(), plate_bgr.type());
this->cleanupColors(plate_bgr, plate_bgr_cleaned);
CharacterRegion charRegion(plate_bgr, config);
if (charRegion.confidence > 10)
{
PlateLines plateLines(config);
//Mat boogedy = charRegion.getPlateMask();
plateLines.processImage(charRegion.getPlateMask(), 1.15);
plateLines.processImage(plate_bgr_cleaned, 0.9);
PlateCorners cornerFinder(plate_bgr, &plateLines, &charRegion, config);
vector<Point> smallPlateCorners = cornerFinder.findPlateCorners();
if (cornerFinder.confidence > 0)
{
this->plateCorners = transformPointsToOriginalImage(frame, plate_bgr, expandedRegion, smallPlateCorners);
this->deskewed = deSkewPlate(frame, this->plateCorners);
charSegmenter = new CharacterSegmenter(deskewed, charRegion.thresholdsInverted(), config);
//this->recognizedText = ocr->recognizedText;
//strcpy(this->recognizedText, ocr.recognizedText);
this->confidence = 100;
}
charRegion.confidence = 0;
}
}
@@ -106,30 +106,30 @@ vector<Point2f> LicensePlateCandidate::transformPointsToOriginalImage(Mat bigIma
{
float bigX = (corners[i].x * ((float) region.width / smallImage.cols));
float bigY = (corners[i].y * ((float) region.height / smallImage.rows));
bigX = bigX + region.x;
bigY = bigY + region.y;
cornerPoints.push_back(Point2f(bigX, bigY));
}
return cornerPoints;
}
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.
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 topEdge(round(corners[0].x), round(corners[0].y), round(corners[1].x), round(corners[1].y));
LineSegment bottomEdge(round(corners[3].x), round(corners[3].y), round(corners[2].x), round(corners[2].y));
float w = distanceBetweenPoints(leftEdge.midpoint(), rightEdge.midpoint());
float h = distanceBetweenPoints(bottomEdge.midpoint(), topEdge.midpoint());
float aspect = w/h;
int width = config->ocrImageWidthPx;
int height = round(((float) width) / aspect);
if (height > config->ocrImageHeightPx)
@@ -137,9 +137,9 @@ Mat LicensePlateCandidate::deSkewPlate(Mat inputImage, vector<Point2f> corners)
height = config->ocrImageHeightPx;
width = round(((float) height) * aspect);
}
Mat deskewed(height, width, frame.type());
// Corners of the destination image
vector<Point2f> quad_pts;
quad_pts.push_back(Point2f(0, 0));
@@ -152,10 +152,10 @@ Mat LicensePlateCandidate::deSkewPlate(Mat inputImage, vector<Point2f> corners)
// Apply perspective transformation
warpPerspective(inputImage, deskewed, transmtx, deskewed.size());
if (this->config->debugGeneral)
displayImage(config, "quadrilateral", deskewed);
return deskewed;
}
@@ -164,13 +164,13 @@ void LicensePlateCandidate::cleanupColors(Mat inputImage, Mat outputImage)
{
if (this->config->debugGeneral)
cout << "LicensePlate::cleanupColors" << endl;
//Mat normalized(inputImage.size(), inputImage.type());
Mat intermediate(inputImage.size(), inputImage.type());
normalize(inputImage, intermediate, 0, 255, CV_MINMAX );
// Equalize intensity:
if(intermediate.channels() >= 3)
{
@@ -189,14 +189,14 @@ void LicensePlateCandidate::cleanupColors(Mat inputImage, Mat outputImage)
//ycrcb.release();
}
bilateralFilter(intermediate, outputImage, 3, 25, 35);
bilateralFilter(intermediate, outputImage, 3, 25, 35);
if (this->config->debugGeneral)
{
displayImage(config, "After cleanup", outputImage);
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -54,28 +54,28 @@ class LicensePlateCandidate
float confidence; // 0-100
//vector<Point> points; // top-left, top-right, bottom-right, bottom-left
vector<Point2f> plateCorners;
void recognize();
Mat deskewed;
CharacterSegmenter* charSegmenter;
private:
Config* config;
Mat frame;
Rect plateRegion;
void cleanupColors(Mat inputImage, Mat outputImage);
Mat filterByCharacterHue(vector<vector<Point> > charRegionContours);
vector<Point> findPlateCorners(Mat inputImage, PlateLines plateLines, CharacterRegion charRegion); // top-left, top-right, bottom-right, bottom-left
vector<Point2f> transformPointsToOriginalImage(Mat bigImage, Mat smallImage, Rect region, vector<Point> corners);
Mat deSkewPlate(Mat inputImage, vector<Point2f> corners);
};
#endif // STAGE2_H
#endif // STAGE2_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,9 +25,9 @@
OCR::OCR(Config* config)
{
this->config = config;
this->postProcessor = new PostProcess(config);
tesseract=new TessBaseAPI();
// Tesseract requires the prefix directory to be set as an env variable
@@ -35,11 +35,11 @@ OCR::OCR(Config* config)
strcpy(tessdataPrefix.data(), config->getTessdataPrefix().c_str());
putenv(tessdataPrefix.data());
tesseract->Init("", config->ocrLanguage.c_str() );
tesseract->SetVariable("save_blob_choices", "T");
//tesseract->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNPQRSTUVWXYZ1234567890");
//tesseract->SetVariable("tessedit_char_whitelist", "ABCDEFGHIJKLMNPQRSTUVWXYZ1234567890");
tesseract->SetPageSegMode(PSM_SINGLE_CHAR);
}
@@ -53,56 +53,56 @@ OCR::~OCR()
void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
{
timespec startTime;
getTime(&startTime);
postProcessor->clear();
for (int i = 0; i < thresholds.size(); i++)
{
// Make it black text on white background
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());
for (int j = 0; j < charRegions.size(); j++)
{
Rect expandedRegion = expandRect( charRegions[j], 2, 2, thresholds[i].cols, thresholds[i].rows) ;
tesseract->SetRectangle(expandedRegion.x, expandedRegion.y, expandedRegion.width, expandedRegion.height);
tesseract->Recognize(NULL);
tesseract::ResultIterator* ri = tesseract->GetIterator();
tesseract::PageIteratorLevel level = tesseract::RIL_SYMBOL;
do {
const char* symbol = ri->GetUTF8Text(level);
float conf = ri->Confidence(level);
bool dontcare;
int fontindex = 0;
int pointsize = 0;
const char* fontName = ri->WordFontAttributes(&dontcare, &dontcare, &dontcare, &dontcare, &dontcare, &dontcare, &pointsize, &fontindex);
if(symbol != 0 && pointsize >= config->ocrMinFontSize) {
postProcessor->addLetter(*symbol, j, conf);
if (this->config->debugOcr)
printf("charpos%d: threshold %d: symbol %s, conf: %f font: %s (index %d) size %dpx", j, i, symbol, conf, fontName, fontindex, pointsize);
bool indent = false;
tesseract::ChoiceIterator ci(*ri);
do {
const char* choice = ci.GetUTF8Text();
postProcessor->addLetter(*choice, j, ci.Confidence());
//letterScores.addScore(*choice, j, ci.Confidence() - MIN_CONFIDENCE);
if (this->config->debugOcr)
{
@@ -110,36 +110,31 @@ void OCR::performOCR(vector<Mat> thresholds, vector<Rect> charRegions)
printf("\t- ");
printf("%s conf: %f\n", choice, ci.Confidence());
}
indent = true;
} while(ci.Next());
}
if (this->config->debugOcr)
printf("---------------------------------------------\n");
delete[] symbol;
} while((ri->Next(level)));
delete ri;
}
}
if (config->debugTiming)
{
timespec endTime;
getTime(&endTime);
cout << "OCR Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,7 +25,7 @@
#include <iostream>
#include <stdio.h>
#include "utility.h"
#include "postprocess.h"
#include "config.h"
@@ -45,22 +45,22 @@ class OCR
public:
OCR(Config* config);
virtual ~OCR();
void performOCR(vector<Mat> thresholds, vector<Rect> charRegions);
PostProcess* postProcessor;
//string recognizedText;
//float confidence;
//float overallConfidence;
private:
Config* config;
TessBaseAPI *tesseract;
};

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,20 +23,20 @@
PlateCorners::PlateCorners(Mat inputImage, PlateLines* plateLines, CharacterRegion* charRegion, Config* config)
{
this->config = config;
if (this->config->debugPlateCorners)
cout << "PlateCorners constructor" << endl;
this->inputImage = inputImage;
this->plateLines = plateLines;
this->charRegion = charRegion;
this->bestHorizontalScore = 9999999999999;
this->bestVerticalScore = 9999999999999;
Point topPoint = charRegion->getTopLine().midpoint();
Point bottomPoint = charRegion->getBottomLine().closestPointOnSegmentTo(topPoint);
this->charHeight = distanceBetweenPoints(topPoint, bottomPoint);
@@ -45,7 +45,7 @@ PlateCorners::PlateCorners(Mat inputImage, PlateLines* plateLines, CharacterRegi
//this->charHeight = this->charHeight - 2; // Adjust since this height is a box around our char.
// Adjust the char height for the difference in size...
//this->charHeight = ((float) inputImage.size().height / (float) TEMPLATE_PLATE_HEIGHT) * this->charHeight;
this->charAngle = angleBetweenPoints(charRegion->getCharArea()[0], charRegion->getCharArea()[1]);
}
@@ -58,61 +58,61 @@ vector<Point> PlateCorners::findPlateCorners()
{
if (this->config->debugPlateCorners)
cout << "PlateCorners::findPlateCorners" << endl;
timespec startTime;
getTime(&startTime);
int horizontalLines = this->plateLines->horizontalLines.size();
int verticalLines = this->plateLines->verticalLines.size();
// layout horizontal lines
for (int h1 = NO_LINE; h1 < horizontalLines; h1++)
{
for (int h2 = NO_LINE; h2 < horizontalLines; h2++)
{
if (h1 == h2 && h1 != NO_LINE) continue;
this->scoreHorizontals(h1, h2);
}
}
// layout vertical lines
for (int v1 = NO_LINE; v1 < verticalLines; v1++)
{
for (int v2 = NO_LINE; v2 < verticalLines; v2++)
{
if (v1 == v2 && v1 != NO_LINE) continue;
this->scoreVerticals(v1, v2);
}
}
if (this->config->debugPlateCorners)
{
cout << "Drawing debug stuff..." << endl;
Mat imgCorners = Mat(inputImage.size(), inputImage.type());
inputImage.copyTo(imgCorners);
for (int i = 0; i < 4; i++)
circle(imgCorners, charRegion->getCharArea()[i], 2, Scalar(0, 0, 0));
line(imgCorners, this->bestTop.p1, this->bestTop.p2, Scalar(255, 0, 0), 1, CV_AA);
line(imgCorners, this->bestRight.p1, this->bestRight.p2, Scalar(0, 0, 255), 1, CV_AA);
line(imgCorners, this->bestBottom.p1, this->bestBottom.p2, Scalar(0, 0, 255), 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.
if (bestLeft.p1.x == 0 && bestLeft.p1.y == 0 && bestLeft.p2.x == 0 && bestLeft.p2.y == 0)
confidence = 0;
@@ -120,49 +120,49 @@ vector<Point> PlateCorners::findPlateCorners()
confidence = 0;
else
confidence = 100;
vector<Point> corners;
corners.push_back(bestTop.intersection(bestLeft));
corners.push_back(bestTop.intersection(bestRight));
corners.push_back(bestBottom.intersection(bestRight));
corners.push_back(bestBottom.intersection(bestLeft));
if (config->debugTiming)
{
timespec endTime;
getTime(&endTime);
cout << "Plate Corners Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
return corners;
}
void PlateCorners::scoreVerticals(int v1, int v2)
{
float score = 0; // Lower is better
LineSegment left;
LineSegment right;
float charHeightToPlateWidthRatio = config->plateWidthMM / config->charHeightMM;
float idealPixelWidth = this->charHeight * (charHeightToPlateWidthRatio * 1.05); // Add 10% so we don't clip any characters
if (v1 == NO_LINE && v2 == NO_LINE)
{
//return;
Point centerTop = charRegion->getCharBoxTop().midpoint();
Point centerBottom = charRegion->getCharBoxBottom().midpoint();
LineSegment centerLine = LineSegment(centerBottom.x, centerBottom.y, centerTop.x, centerTop.y);
left = centerLine.getParallelLine(idealPixelWidth / 2);
right = centerLine.getParallelLine(-1 * idealPixelWidth / 2 );
score += SCORING_MISSING_SEGMENT_PENALTY_VERTICAL * 2;
}
else if (v1 != NO_LINE && v2 != NO_LINE)
@@ -182,109 +182,109 @@ void PlateCorners::scoreVerticals(int v1, int v2)
right = left.getParallelLine(-1 * idealPixelWidth);
score += SCORING_MISSING_SEGMENT_PENALTY_VERTICAL;
}
// Make sure this line is to the left of our license plate letters
if (left.isPointBelowLine(charRegion->getCharBoxLeft().midpoint()) == false)
return;
// Make sure this line is to the right of our license plate letters
if (right.isPointBelowLine(charRegion->getCharBoxRight().midpoint()))
return;
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Score "Distance from the edge...
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
float leftDistanceFromEdge = abs((float) (left.p1.x + left.p2.x) / 2);
float rightDistanceFromEdge = abs(this->inputImage.cols - ((float) (right.p1.x + right.p2.x) / 2));
float distanceFromEdge = leftDistanceFromEdge + rightDistanceFromEdge;
score += distanceFromEdge * SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT;
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Score "Boxiness" of the 4 lines. How close is it to a parallelogram?
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
float verticalAngleDiff = abs(left.angle - right.angle);
score += (verticalAngleDiff) * SCORING_BOXINESS_WEIGHT;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// SCORE the shape wrt character position and height relative to position
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
Point leftMidLinePoint = left.closestPointOnSegmentTo(charRegion->getCharBoxLeft().midpoint());
Point rightMidLinePoint = right.closestPointOnSegmentTo(charRegion->getCharBoxRight().midpoint());
float plateDistance = abs(idealPixelWidth - distanceBetweenPoints(leftMidLinePoint, rightMidLinePoint));
score += plateDistance * SCORING_VERTICALDISTANCE_WEIGHT;
if (score < this->bestVerticalScore)
{
float scorecomponent;
if (this->config->debugPlateCorners)
{
cout << "xx xx Score: charHeight " << this->charHeight << endl;
cout << "xx xx Score: idealwidth " << idealPixelWidth << endl;
cout << "xx xx Score: v1,v2= " << v1 << "," << v2 << endl;
cout << "xx xx Score: Left= " << left.str() << endl;
cout << "xx xx Score: Right= " << right.str() << endl;
cout << "xx xx Score: charHeight " << this->charHeight << endl;
cout << "xx xx Score: idealwidth " << idealPixelWidth << endl;
cout << "xx xx Score: v1,v2= " << v1 << "," << v2 << endl;
cout << "xx xx Score: Left= " << left.str() << endl;
cout << "xx xx Score: Right= " << right.str() << endl;
cout << "Vertical breakdown Score:" << endl;
cout << " -- Boxiness Score: " << verticalAngleDiff << " -- Weight (" << SCORING_BOXINESS_WEIGHT << ")" << endl;
scorecomponent = verticalAngleDiff * SCORING_BOXINESS_WEIGHT;
scorecomponent = verticalAngleDiff * SCORING_BOXINESS_WEIGHT;
cout << " -- -- Score: " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Distance From Edge Score: " << distanceFromEdge << " -- Weight (" << SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT << ")" << endl;
scorecomponent = distanceFromEdge * SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT;
scorecomponent = distanceFromEdge * SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT;
cout << " -- -- Score: " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Distance Score: " << plateDistance << " -- Weight (" << SCORING_VERTICALDISTANCE_WEIGHT << ")" << endl;
scorecomponent = plateDistance * SCORING_VERTICALDISTANCE_WEIGHT;
scorecomponent = plateDistance * SCORING_VERTICALDISTANCE_WEIGHT;
cout << " -- -- Score: " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Score: " << score << endl;
}
this->bestVerticalScore = score;
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);
}
}
// 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
void PlateCorners::scoreHorizontals(int h1, int h2)
{
//if (this->debug)
// cout << "PlateCorners::scorePlate" << endl;
float score = 0; // Lower is better
LineSegment top;
LineSegment bottom;
float charHeightToPlateHeightRatio = config->plateHeightMM / config->charHeightMM;
float idealPixelHeight = this->charHeight * charHeightToPlateHeightRatio;
float idealPixelHeight = this->charHeight * charHeightToPlateHeightRatio;
if (h1 == NO_LINE && h2 == NO_LINE)
{
// return;
Point centerLeft = charRegion->getCharBoxLeft().midpoint();
Point centerRight = charRegion->getCharBoxRight().midpoint();
LineSegment centerLine = LineSegment(centerLeft.x, centerLeft.y, centerRight.x, centerRight.y);
top = centerLine.getParallelLine(idealPixelHeight / 2);
bottom = centerLine.getParallelLine(-1 * idealPixelHeight / 2 );
@@ -307,141 +307,141 @@ void PlateCorners::scoreHorizontals(int h1, int h2)
bottom = top.getParallelLine(-1 * idealPixelHeight);
score += SCORING_MISSING_SEGMENT_PENALTY_HORIZONTAL;
}
// Make sure this line is above our license plate letters
if (top.isPointBelowLine(charRegion->getCharBoxTop().midpoint()) == false)
return;
// Make sure this line is below our license plate letters
if (bottom.isPointBelowLine(charRegion->getCharBoxBottom().midpoint()))
return;
// We now have 4 possible lines. Let's put them to the test and score them...
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Score "Boxiness" of the 4 lines. How close is it to a parallelogram?
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
float horizontalAngleDiff = abs(top.angle - bottom.angle);
score += (horizontalAngleDiff) * SCORING_BOXINESS_WEIGHT;
// if (this->debug)
// cout << "PlateCorners boxiness score: " << (horizontalAngleDiff + verticalAngleDiff) * SCORING_BOXINESS_WEIGHT << endl;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// SCORE the shape wrt character position and height relative to position
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
Point topPoint = top.midpoint();
Point botPoint = bottom.closestPointOnSegmentTo(topPoint);
float plateHeightPx = distanceBetweenPoints(topPoint, botPoint);
// Get the height difference
float heightRatio = charHeight / plateHeightPx;
float idealHeightRatio = (config->charHeightMM / config->plateHeightMM);
//if (leftRatio < MIN_CHAR_HEIGHT_RATIO || leftRatio > MAX_CHAR_HEIGHT_RATIO || rightRatio < MIN_CHAR_HEIGHT_RATIO || rightRatio > MAX_CHAR_HEIGHT_RATIO)
float heightRatioDiff = abs(heightRatio - idealHeightRatio);
// Ideal ratio == ~.45
// Get the distance from the top and the distance from the bottom
// Take the average distances from the corners of the character region to the top/bottom lines
// float topDistance = distanceBetweenPoints(topMidLinePoint, charRegion->getCharBoxTop().midpoint());
// float bottomDistance = distanceBetweenPoints(bottomMidLinePoint, charRegion->getCharBoxBottom().midpoint());
// float idealTopDistance = charHeight * (TOP_WHITESPACE_HEIGHT_MM / CHARACTER_HEIGHT_MM);
// float idealBottomDistance = charHeight * (BOTTOM_WHITESPACE_HEIGHT_MM / CHARACTER_HEIGHT_MM);
// float distScore = abs(topDistance - idealTopDistance) + abs(bottomDistance - idealBottomDistance);
score += heightRatioDiff * SCORING_PLATEHEIGHT_WEIGHT;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// SCORE the middliness of the stuff. We want our top and bottom line to have the characters right towards the middle
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
Point charAreaMidPoint = charRegion->getCharBoxLeft().midpoint();
Point topLineSpot = top.closestPointOnSegmentTo(charAreaMidPoint);
Point botLineSpot = bottom.closestPointOnSegmentTo(charAreaMidPoint);
float topDistanceFromMiddle = distanceBetweenPoints(topLineSpot, charAreaMidPoint);
float bottomDistanceFromMiddle = distanceBetweenPoints(topLineSpot, charAreaMidPoint);
float idealDistanceFromMiddle = idealPixelHeight / 2;
float middleScore = abs(topDistanceFromMiddle - idealDistanceFromMiddle) + abs(bottomDistanceFromMiddle - idealDistanceFromMiddle);
score += middleScore * SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT;
// if (this->debug)
// {
// cout << "PlateCorners boxiness score: " << avgRatio * SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT << endl;
// cout << "PlateCorners boxiness score: " << distScore * SCORING_PLATEHEIGHT_WEIGHT << endl;
// }
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// SCORE: the shape for angles matching the character region
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
float charanglediff = abs(charAngle - top.angle) + abs(charAngle - bottom.angle);
score += charanglediff * SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT;
// if (this->debug)
// cout << "PlateCorners boxiness score: " << charanglediff * SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT << endl;
if (score < this->bestHorizontalScore)
{
float scorecomponent;
if (this->config->debugPlateCorners)
{
cout << "xx xx Score: charHeight " << this->charHeight << endl;
cout << "xx xx Score: idealHeight " << idealPixelHeight << endl;
cout << "xx xx Score: h1,h2= " << h1 << "," << h2 << endl;
cout << "xx xx Score: Top= " << top.str() << endl;
cout << "xx xx Score: Bottom= " << bottom.str() << endl;
cout << "xx xx Score: charHeight " << this->charHeight << endl;
cout << "xx xx Score: idealHeight " << idealPixelHeight << endl;
cout << "xx xx Score: h1,h2= " << h1 << "," << h2 << endl;
cout << "xx xx Score: Top= " << top.str() << endl;
cout << "xx xx Score: Bottom= " << bottom.str() << endl;
cout << "Horizontal breakdown Score:" << endl;
cout << " -- Boxiness Score: " << horizontalAngleDiff << " -- Weight (" << SCORING_BOXINESS_WEIGHT << ")" << endl;
scorecomponent = horizontalAngleDiff * SCORING_BOXINESS_WEIGHT;
scorecomponent = horizontalAngleDiff * SCORING_BOXINESS_WEIGHT;
cout << " -- -- Score: " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Height Ratio Diff Score: " << heightRatioDiff << " -- Weight (" << SCORING_PLATEHEIGHT_WEIGHT << ")" << endl;
scorecomponent = heightRatioDiff * SCORING_PLATEHEIGHT_WEIGHT;
scorecomponent = heightRatioDiff * SCORING_PLATEHEIGHT_WEIGHT;
cout << " -- -- " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Distance Score: " << middleScore << " -- Weight (" << SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT << ")" << endl;
scorecomponent = middleScore * SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT;
scorecomponent = middleScore * SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT;
cout << " -- -- Score: " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Char angle Score: " << charanglediff << " -- Weight (" << SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT << ")" << endl;
scorecomponent = charanglediff * SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT;
scorecomponent = charanglediff * SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT;
cout << " -- -- Score: " << scorecomponent << " = " << scorecomponent / score * 100 << "% of score" << endl;
cout << " -- Score: " << score << endl;
}
this->bestHorizontalScore = score;
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);
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -36,13 +36,13 @@ using namespace std;
#define SCORING_MISSING_SEGMENT_PENALTY_VERTICAL 10
#define SCORING_MISSING_SEGMENT_PENALTY_HORIZONTAL 15
#define SCORING_BOXINESS_WEIGHT 0.8
#define SCORING_PLATEHEIGHT_WEIGHT 2.2
#define SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT 0.05
#define SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT 1.1
#define SCORING_VERTICALDISTANCE_WEIGHT 0.1
#define SCORING_BOXINESS_WEIGHT 0.8
#define SCORING_PLATEHEIGHT_WEIGHT 2.2
#define SCORING_TOP_BOTTOM_SPACE_VS_CHARHEIGHT_WEIGHT 0.05
#define SCORING_ANGLE_MATCHES_LPCHARS_WEIGHT 1.1
#define SCORING_VERTICALDISTANCE_WEIGHT 0.1
#define SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT 0.05
#define SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT 0.05
class PlateCorners
{
@@ -50,33 +50,31 @@ class PlateCorners
public:
PlateCorners(Mat inputImage, PlateLines* plateLines, CharacterRegion* charRegion, Config* config);
virtual ~PlateCorners();
vector<Point> findPlateCorners();
float confidence;
private:
Config* config;
Mat inputImage;
float charHeight;
float charAngle;
float bestHorizontalScore;
float bestVerticalScore;
LineSegment bestTop;
LineSegment bestBottom;
LineSegment bestLeft;
LineSegment bestRight;
PlateLines* plateLines;
CharacterRegion* charRegion;
void scoreHorizontals( int h1, int h2 );
void scoreVerticals( int v1, int v2 );
};
#endif // PLATELINES_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -24,10 +24,10 @@ PlateLines::PlateLines(Config* config)
{
this->config = config;
this->debug = config->debugPlateLines;
if (debug)
cout << "PlateLines constructor" << endl;
}
@@ -36,18 +36,18 @@ PlateLines::~PlateLines()
}
void PlateLines::processImage(Mat inputImage, float sensitivity)
{
if (this->debug)
cout << "PlateLines findLines" << endl;
timespec startTime;
getTime(&startTime);
Mat smoothed(inputImage.size(), inputImage.type());
inputImage.copyTo(smoothed);
int morph_elem = 2;
@@ -55,31 +55,31 @@ void PlateLines::processImage(Mat inputImage, float sensitivity)
Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
morphologyEx( smoothed, smoothed, MORPH_CLOSE, element );
morph_size = 1;
element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
//morphologyEx( thresholded, thresholded, MORPH_GRADIENT, element );
morph_size = 1;
element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
morphologyEx( smoothed, smoothed, MORPH_OPEN, element );
Mat edges(inputImage.size(), inputImage.type());
Canny(smoothed, edges, 66, 133);
vector<LineSegment> hlines = this->getLines(edges, sensitivity, false);
vector<LineSegment> vlines = this->getLines(edges, sensitivity, true);
for (int i = 0; i < hlines.size(); i++)
this->horizontalLines.push_back(hlines[i]);
for (int i = 0; i < vlines.size(); i++)
this->verticalLines.push_back(vlines[i]);
// if debug is enabled, draw the image
if (this->debug)
@@ -90,27 +90,27 @@ void PlateLines::processImage(Mat inputImage, float sensitivity)
edges.copyTo(debugImgVert);
cvtColor(debugImgHoriz,debugImgHoriz,CV_GRAY2BGR);
cvtColor(debugImgVert,debugImgVert,CV_GRAY2BGR);
for( size_t i = 0; i < this->horizontalLines.size(); i++ )
{
line( debugImgHoriz, this->horizontalLines[i].p1, this->horizontalLines[i].p2, Scalar(0,0,255), 1, CV_AA);
}
for( size_t i = 0; i < this->verticalLines.size(); i++ )
{
line( debugImgVert, this->verticalLines[i].p1, this->verticalLines[i].p2, Scalar(0,0,255), 1, CV_AA);
}
vector<Mat> images;
images.push_back(debugImgHoriz);
images.push_back(debugImgVert);
Mat dashboard = drawImageDashboard(images, debugImgVert.type(), 1);
displayImage(config, "Hough Lines", dashboard);
}
if (config->debugTiming)
{
timespec endTime;
@@ -118,27 +118,27 @@ void PlateLines::processImage(Mat inputImage, float sensitivity)
cout << "Plate Lines Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
//smoothed.release();
//////////////// METHOD2!!!!!!!////////////////////
/*
Mat imgBlur;
Mat imgCanny;
GaussianBlur(inputImage, imgBlur, Size(9, 9), 1, 1);
Canny(imgBlur, imgCanny, 10, 30, 3);
Canny(imgBlur, imgCanny, 10, 30, 3);
//int morph_elem = 2;
//int morph_size = 1;
//Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
morphologyEx( imgCanny, imgCanny, MORPH_CLOSE, element );
Mat imgShaped;
imgCanny.copyTo(imgShaped);
//Find contours of possibles characters
@@ -147,26 +147,26 @@ void PlateLines::processImage(Mat inputImage, float sensitivity)
biggestShapes, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_SIMPLE ); // all pixels of each contours
// Draw blue contours on a white image
//cvtColor(imgShaped, imgShaped, CV_GRAY2RGB);
cv::drawContours(imgShaped,biggestShapes,
-1, // draw all contours
cv::Scalar(255,255,255), // in blue
1); // with a thickness of 1
displayImage(config, "Blurred", imgCanny);
displayImage(config, "Blurred Contours", imgShaped);
vector<Rect> shapeRects( biggestShapes.size() );
vector<vector<Point> >hull( biggestShapes.size() );
for( int i = 0; i < biggestShapes.size(); i++ )
{
{
//approxPolyDP( Mat(biggestShapes[i]), shapeRects[i], 3, true );
convexHull( biggestShapes[i], hull[i], false );
//approxPolyDP( biggestShapes[i], hull[i], 10, true );
//minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
}
*/
@@ -176,21 +176,21 @@ void PlateLines::processImage(Mat inputImage, float sensitivity)
/*
vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
{
vector<LineSegment> filteredLines;
int sensitivity;
LSWMS lswms(Size(edges.cols, edges.rows), 3, 155, false);
vector<LSEG> lsegs;
vector<double> errors;
lswms.run(edges, lsegs, errors);
for( size_t i = 0; i < lsegs.size(); i++ )
{
if (vertical)
{
LineSegment candidate;
@@ -198,13 +198,13 @@ vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
candidate = LineSegment(lsegs[i][0].x, lsegs[i][0].y, lsegs[i][1].x, lsegs[i][1].y);
else
candidate = LineSegment(lsegs[i][1].x, lsegs[i][1].y, lsegs[i][0].x, lsegs[i][0].y);
cout << "VERT Angle: " << candidate.angle << endl;
//if ((candidate.angle > 70 && candidate.angle < 110) || (candidate.angle > 250 && candidate.angle < 290))
//{
// good vertical
filteredLines.push_back(candidate);
//}
}
else
@@ -215,26 +215,26 @@ vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
else
candidate = LineSegment(lsegs[i][1].x, lsegs[i][1].y, lsegs[i][0].x, lsegs[i][0].y);
cout << "HORIZAngle: " << candidate.angle << endl;
//if ( (candidate.angle > -20 && candidate.angle < 20) || (candidate.angle > 160 && candidate.angle < 200))
//{
// good horizontal
filteredLines.push_back(candidate);
//}
}
}
// if debug is enabled, draw the image
if (this->debug)
{
Mat debugImg(edges.size(), edges.type());
edges.copyTo(debugImg);
cvtColor(debugImg,debugImg,CV_GRAY2BGR);
for( size_t i = 0; i < filteredLines.size(); i++ )
{
line( debugImg, filteredLines[i].p1, filteredLines[i].p2, Scalar(0,0,255), 1, CV_AA);
}
if (vertical)
@@ -242,7 +242,7 @@ vector<LineSegment> PlateLines::getLines(Mat edges, bool vertical)
else
displayImage(config, "Lines Horizontal", debugImg);
}
return filteredLines;
}
*/
@@ -252,47 +252,47 @@ vector<LineSegment> PlateLines::getLines(Mat edges, float sensitivityMultiplier,
{
if (this->debug)
cout << "PlateLines::getLines" << endl;
static int HORIZONTAL_SENSITIVITY = config->plateLinesSensitivityHorizontal;
static int VERTICAL_SENSITIVITY = config->plateLinesSensitivityVertical;
vector<Vec2f> allLines;
vector<LineSegment> filteredLines;
int sensitivity;
if (vertical)
sensitivity = VERTICAL_SENSITIVITY * (1.0 / sensitivityMultiplier);
else
sensitivity = HORIZONTAL_SENSITIVITY * (1.0 / sensitivityMultiplier);
HoughLines( edges, allLines, 1, CV_PI/180, sensitivity, 0, 0 );
for( size_t i = 0; i < allLines.size(); i++ )
{
float rho = allLines[i][0], theta = allLines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
double angle = theta * (180 / CV_PI);
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
if (vertical)
{
if (angle < 20 || angle > 340 || (angle > 160 && angle < 210))
{
// good vertical
LineSegment line;
if (pt1.y <= pt2.y)
line = LineSegment(pt2.x, pt2.y, pt1.x, pt1.y);
else
line = LineSegment(pt1.x, pt1.y, pt2.x, pt2.y);
// Get rid of the -1000, 1000 stuff. Terminate at the edges of the image
// Helps with debugging/rounding issues later
LineSegment top(0, 0, edges.cols, 0);
@@ -304,28 +304,28 @@ vector<LineSegment> PlateLines::getLines(Mat edges, float sensitivityMultiplier,
}
else
{
if ( (angle > 70 && angle < 110) || (angle > 250 && angle < 290))
{
// good horizontal
LineSegment line;
if (pt1.x <= pt2.x)
line = LineSegment(pt1.x, pt1.y, pt2.x, pt2.y);
else
line =LineSegment(pt2.x, pt2.y, pt1.x, pt1.y);
// Get rid of the -1000, 1000 stuff. Terminate at the edges of the image
// Helps with debugging/ rounding issues later
int newY1 = line.getPointAt(0);
int newY2 = line.getPointAt(edges.cols);
filteredLines.push_back(LineSegment(0, newY1, edges.cols, newY2));
}
}
}
return filteredLines;
}
@@ -337,11 +337,11 @@ Mat PlateLines::customGrayscaleConversion(Mat src)
{
Mat img_hsv;
cvtColor(src,img_hsv,CV_BGR2HSV);
Mat grayscale = Mat(img_hsv.size(), CV_8U );
Mat hue(img_hsv.size(), CV_8U );
for (int row = 0; row < img_hsv.rows; row++)
{
for (int col = 0; col < img_hsv.cols; col++)
@@ -349,18 +349,18 @@ Mat PlateLines::customGrayscaleConversion(Mat src)
int h = (int) img_hsv.at<Vec3b>(row, col)[0];
int s = (int) img_hsv.at<Vec3b>(row, col)[1];
int v = (int) img_hsv.at<Vec3b>(row, col)[2];
int pixval = pow(v, 1.05);
if (pixval > 255)
pixval = 255;
grayscale.at<uchar>(row, col) = pixval;
hue.at<uchar>(row, col) = h * (255.0 / 180.0);
}
}
//displayImage(config, "Hue", hue);
return grayscale;
}
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -38,24 +38,22 @@ class PlateLines
public:
PlateLines(Config* config);
virtual ~PlateLines();
void processImage(Mat img, float sensitivity=1.0);
vector<LineSegment> horizontalLines;
vector<LineSegment> verticalLines;
vector<Point> winningCorners;
private:
Config* config;
bool debug;
Mat customGrayscaleConversion(Mat src);
void findLines(Mat inputImage);
vector<LineSegment> getLines(Mat edges, float sensitivityMultiplier, bool vertical);
};
#endif // PLATELINES_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,19 +23,19 @@
PostProcess::PostProcess(Config* config)
{
this->config = config;
stringstream filename;
filename << config->getPostProcessRuntimeDir() << "/" << config->country << ".patterns";
std::ifstream infile(filename.str().c_str());
string region, pattern;
while (infile >> region >> pattern)
{
RegexRule* rule = new RegexRule(region, pattern);
//cout << "REGION: " << region << " PATTERN: " << pattern << endl;
if (rules.find(region) == rules.end())
{
vector<RegexRule*> newRule;
@@ -49,7 +49,7 @@ PostProcess::PostProcess(Config* config)
rules[region] = oldRule;
}
}
//vector<RegexRule> test = rules["base"];
//for (int i = 0; i < test.size(); i++)
// cout << "Rule: " << test[i].regex << endl;
@@ -66,7 +66,7 @@ PostProcess::~PostProcess()
{
delete iter->second[i];
}
}
}
@@ -75,28 +75,28 @@ void PostProcess::addLetter(char letter, int charposition, float score)
{
if (score < config->postProcessMinConfidence)
return;
insertLetter(letter, charposition, score);
if (score < config->postProcessConfidenceSkipLevel)
{
float adjustedScore = abs(config->postProcessConfidenceSkipLevel - score) + config->postProcessMinConfidence;
insertLetter(SKIP_CHAR, charposition, adjustedScore );
}
//if (letter == '0')
//{
// insertLetter('O', charposition, score - 0.5);
//}
}
void PostProcess::insertLetter(char letter, int charposition, float score)
{
score = score - config->postProcessMinConfidence;
int existingIndex = -1;
if (letters.size() < charposition + 1)
{
@@ -106,7 +106,7 @@ void PostProcess::insertLetter(char letter, int charposition, float score)
letters.push_back(tmp);
}
}
for (int i = 0; i < letters[charposition].size(); i++)
{
if (letters[charposition][i].letter == letter &&
@@ -116,7 +116,7 @@ void PostProcess::insertLetter(char letter, int charposition, float score)
break;
}
}
if (existingIndex == -1)
{
Letter newLetter;
@@ -131,7 +131,7 @@ void PostProcess::insertLetter(char letter, int charposition, float score)
letters[charposition][existingIndex].occurences = letters[charposition][existingIndex].occurences + 1;
letters[charposition][existingIndex].totalscore = letters[charposition][existingIndex].totalscore + score;
}
}
@@ -142,23 +142,23 @@ void PostProcess::clear()
letters[i].clear();
}
letters.resize(0);
unknownCharPositions.clear();
unknownCharPositions.resize(0);
allPossibilities.clear();
//allPossibilities.resize(0);
bestChars = "";
matchesTemplate = false;
}
void PostProcess::analyze(string templateregion, int topn)
{
timespec startTime;
getTime(&startTime);
// Get a list of missing positions
for (int i = letters.size() -1; i >= 0; i--)
{
@@ -167,38 +167,38 @@ void PostProcess::analyze(string templateregion, int topn)
unknownCharPositions.push_back(i);
}
}
if (letters.size() == 0)
return;
// Sort the letters as they are
for (int i = 0; i < letters.size(); i++)
{
if (letters[i].size() > 0)
sort(letters[i].begin(), letters[i].end(), letterCompare);
}
if (this->config->debugPostProcess)
{
// Print all letters
for (int i = 0; i < letters.size(); i++)
{
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;
}
}
// Prune the letters based on the topN value.
// If our topN value is 3, for example, we can get rid of a lot of low scoring letters
// because it would be impossible for them to be a part of our topN results.
vector<int> maxDepth = getMaxDepth(topn);
for (int i = 0; i < letters.size(); i++)
{
for (int k = letters[i].size() - 1; k > maxDepth[i]; k--)
@@ -206,37 +206,37 @@ void PostProcess::analyze(string templateregion, int topn)
letters[i].erase(letters[i].begin() + k);
}
}
//getTopN();
vector<Letter> tmp;
findAllPermutations(tmp, 0, config->postProcessMaxSubstitutions);
timespec sortStartTime;
getTime(&sortStartTime);
int numelements = topn;
if (allPossibilities.size() < topn)
numelements = allPossibilities.size() - 1;
partial_sort( allPossibilities.begin(), allPossibilities.begin() + numelements, allPossibilities.end(), wordCompare );
if (config->debugTiming)
{
timespec sortEndTime;
getTime(&sortEndTime);
cout << " -- PostProcess Sort Time: " << diffclock(sortStartTime, sortEndTime) << "ms." << endl;
}
matchesTemplate = false;
if (templateregion != "")
{
vector<RegexRule*> regionRules = rules[templateregion];
for (int i = 0; i < allPossibilities.size(); i++)
{
for (int j = 0; j < regionRules.size(); j++)
@@ -250,16 +250,16 @@ void PostProcess::analyze(string templateregion, int topn)
break;
}
}
if (i >= topn - 1)
break;
//if (matchesTemplate || i >= TOP_N - 1)
//break;
}
}
if (matchesTemplate)
{
for (int z = 0; z < allPossibilities.size(); z++)
@@ -275,26 +275,26 @@ void PostProcess::analyze(string templateregion, int topn)
{
bestChars = allPossibilities[0].letters;
}
// Now adjust the confidence scores to a percentage value
if (allPossibilities.size() > 0)
{
float maxPercentScore = calculateMaxConfidenceScore();
float highestRelativeScore = (float) allPossibilities[0].totalscore;
for (int i = 0; i < allPossibilities.size(); i++)
{
allPossibilities[i].totalscore = maxPercentScore * (allPossibilities[i].totalscore / highestRelativeScore);
}
}
if (this->config->debugPostProcess)
{
// Print top words
for (int i = 0; i < allPossibilities.size(); i++)
{
@@ -302,22 +302,22 @@ void PostProcess::analyze(string templateregion, int topn)
if (allPossibilities[i].letters == bestChars)
cout << " <--- ";
cout << endl;
if (i >= topn - 1)
break;
}
cout << allPossibilities.size() << " total permutations" << endl;
}
if (config->debugTiming)
{
timespec endTime;
getTime(&endTime);
cout << "PostProcess Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
if (this->config->debugPostProcess)
cout << "PostProcess Analysis Complete: " << bestChars << " -- MATCH: " << matchesTemplate << endl;
}
@@ -325,7 +325,7 @@ void PostProcess::analyze(string templateregion, int topn)
float PostProcess::calculateMaxConfidenceScore()
{
// Take the best score for each char position and average it.
float totalScore = 0;
int numScores = 0;
// Get a list of missing positions
@@ -337,15 +337,15 @@ float PostProcess::calculateMaxConfidenceScore()
numScores++;
}
}
if (numScores == 0)
return 0;
return totalScore / ((float) numScores);
}
// Finds the minimum number of letters to include in the recursive sorting algorithm.
// For example, if I have letters
// For example, if I have letters
// A-200 B-100 C-100
// X-99 Y-95 Z-90
// Q-55 R-80
@@ -356,23 +356,23 @@ float PostProcess::calculateMaxConfidenceScore()
// Y-95 Z-90
vector<int> PostProcess::getMaxDepth(int topn)
{
vector<int> depth;
for (int i = 0; i < letters.size(); i++)
depth.push_back(0);
int nextLeastDropCharPos = getNextLeastDrop(depth);
while (nextLeastDropCharPos != -1)
{
if (getPermutationCount(depth) >= topn)
break;
depth[nextLeastDropCharPos] = depth[nextLeastDropCharPos] + 1;
nextLeastDropCharPos = getNextLeastDrop(depth);
}
return depth;
}
@@ -383,7 +383,7 @@ int PostProcess::getPermutationCount(vector<int> depth)
{
permutationCount *= (depth[i] + 1);
}
return permutationCount;
}
@@ -391,21 +391,21 @@ int PostProcess::getNextLeastDrop(vector<int> depth)
{
int nextLeastDropCharPos = -1;
float leastNextDrop = 99999999999;
for (int i = 0; i < letters.size(); i++)
{
if (depth[i] + 1 >= letters[i].size())
continue;
float drop = letters[i][depth[i]].totalscore - letters[i][depth[i]+1].totalscore;
if (drop < leastNextDrop)
{
nextLeastDropCharPos = i;
leastNextDrop = drop;
}
}
return nextLeastDropCharPos;
}
@@ -416,14 +416,14 @@ const vector<PPResult> PostProcess::getResults()
void PostProcess::findAllPermutations(vector<Letter> prevletters, int charPos, int substitutionsLeft)
{
if (substitutionsLeft < 0)
return;
// Add my letter to the chain and recurse
for (int i = 0; i < letters[charPos].size(); i++)
{
if (charPos == letters.size() - 1)
{
// Last letter, add the word
@@ -437,27 +437,27 @@ void PostProcess::findAllPermutations(vector<Letter> prevletters, int charPos, i
possibility.letters = possibility.letters + prevletters[z].letter;
possibility.totalscore = possibility.totalscore + prevletters[z].totalscore;
}
if (letters[charPos][i].letter != SKIP_CHAR)
possibility.letters = possibility.letters + letters[charPos][i].letter;
possibility.totalscore = possibility.totalscore +letters[charPos][i].totalscore;
allPossibilities.push_back(possibility);
}
else
{
prevletters.push_back(letters[charPos][i]);
float scorePercentDiff = abs( letters[charPos][0].totalscore - letters[charPos][i].totalscore ) / letters[charPos][0].totalscore;
if (i != 0 && letters[charPos][i].letter != SKIP_CHAR && scorePercentDiff > 0.10f )
findAllPermutations(prevletters, charPos + 1, substitutionsLeft - 1);
else
findAllPermutations(prevletters, charPos + 1, substitutionsLeft);
prevletters.pop_back();
}
}
if (letters[charPos].size() == 0)
{
// No letters for this char position...
@@ -465,8 +465,8 @@ void PostProcess::findAllPermutations(vector<Letter> prevletters, int charPos, i
findAllPermutations(prevletters, charPos + 1, substitutionsLeft);
}
}
@@ -491,7 +491,7 @@ RegexRule::RegexRule(string region, string pattern)
{
this->original = pattern;
this->region = region;
numchars = 0;
for (int i = 0; i < pattern.size(); i++)
{
@@ -503,7 +503,7 @@ RegexRule::RegexRule(string region, string pattern)
i++;
}
this->regex = this->regex + ']';
}
else if (pattern.at(i) == '?')
{
@@ -518,12 +518,12 @@ RegexRule::RegexRule(string region, string pattern)
{
this->regex = this->regex + "\\d";
}
numchars++;
}
trexp.Compile(this->regex.c_str());
//cout << "AA " << this->region << ": " << original << " regex: " << regex << endl;
//for (int z = 0; z < this->skipPositions.size(); z++)
// cout << "AA Skip position: " << skipPositions[z] << endl;
@@ -534,7 +534,7 @@ bool RegexRule::match(string text)
{
if (text.length() != numchars)
return false;
return trexp.Match(text.c_str());
}
@@ -552,10 +552,10 @@ string RegexRule::filterSkips(string text)
break;
}
}
if (skip == false)
response = response + text[i];
}
return response;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -35,7 +35,7 @@ using namespace std;
#define SKIP_CHAR '~'
struct Letter
struct Letter
{
char letter;
int charposition;
@@ -60,10 +60,10 @@ class RegexRule
public:
RegexRule(string region, string pattern);
bool match(string text);
string filterSkips(string text);
private:
int numchars;
TRexpp trexp;
@@ -79,34 +79,34 @@ class PostProcess
public:
PostProcess(Config* config);
~PostProcess();
void addLetter(char letter, int charposition, float score);
void clear();
void analyze(string templateregion, int topn);
string bestChars;
bool matchesTemplate;
const vector<PPResult> getResults();
private:
Config* config;
//void getTopN();
void findAllPermutations(vector<Letter> prevletters, int charPos, int substitutionsLeft);
void insertLetter(char letter, int charPosition, float score);
map<string, vector<RegexRule*> > rules;
float calculateMaxConfidenceScore();
vector<vector<Letter> > letters;
vector<int> unknownCharPositions;
vector<PPResult> allPossibilities;
// Functions used to prune the list of letters (based on topn) to improve performance
vector<int> getMaxDepth(int topn);
int getPermutationCount(vector<int> depth);
@@ -118,18 +118,18 @@ class LetterScores
{
public:
LetterScores(int numCharPositions);
void addScore(char letter, int charposition, float score);
vector<char> getBestScore();
float getConfidence();
private:
int numCharPositions;
vector<char> letters;
vector<int> charpositions;
vector<float> scores;
};
*/
#endif // POSTPROCESS_H
#endif // POSTPROCESS_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -27,18 +27,18 @@ RegionDetector::RegionDetector(Config* config)
this->config = config;
// Don't scale. Can change this in the future (i.e., maximum resolution preference, or some such).
this->scale_factor = 1.0f;
// Load either the regular or OpenCL version of the cascade classifier
if (config->opencl_enabled)
{
this->plate_cascade = new ocl::OclCascadeClassifier();
this->plate_cascade = new ocl::OclCascadeClassifier();
}
else
{
this->plate_cascade = new CascadeClassifier();
}
if( this->plate_cascade->load( config->getCascadeRuntimeDir() + config->country + ".xml" ) )
{
this->loaded = true;
@@ -46,11 +46,11 @@ RegionDetector::RegionDetector(Config* config)
else
{
this->loaded = false;
printf("--(!)Error loading classifier\n");
printf("--(!)Error loading classifier\n");
}
}
RegionDetector::~RegionDetector()
@@ -68,10 +68,10 @@ bool RegionDetector::isLoaded()
vector<Rect> RegionDetector::detect(Mat frame)
{
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
vector<Rect> regionsOfInterest = doCascade(frame_gray);
return regionsOfInterest;
@@ -84,19 +84,19 @@ vector<Rect> RegionDetector::doCascade(Mat frame)
//float scale_factor = 1;
int w = frame.size().width;
int h = frame.size().height;
vector<Rect> plates;
equalizeHist( frame, frame );
resize(frame, frame, Size(w * this->scale_factor, h * this->scale_factor));
//-- Detect plates
timespec startTime;
getTime(&startTime);
Size minSize(config->minPlateSizeWidthPx * this->scale_factor, config->minPlateSizeHeightPx * this->scale_factor);
Size maxSize(w * config->maxPlateWidthPercent * this->scale_factor, h * config->maxPlateHeightPercent * this->scale_factor);
if (config->opencl_enabled)
{
ocl::oclMat openclFrame(frame);
@@ -104,14 +104,14 @@ vector<Rect> RegionDetector::doCascade(Mat frame)
}
else
{
plate_cascade->detectMultiScale( frame, plates, 1.1, 3,
plate_cascade->detectMultiScale( frame, plates, 1.1, 3,
0,
//0|CV_HAAR_SCALE_IMAGE,
minSize, maxSize );
}
if (config->debugTiming)
{
timespec endTime;
@@ -120,15 +120,15 @@ vector<Rect> RegionDetector::doCascade(Mat frame)
}
for( int i = 0; i < plates.size(); i++ )
{
plates[i].x = plates[i].x / scale_factor;
plates[i].y = plates[i].y / scale_factor;
plates[i].width = plates[i].width / scale_factor;
plates[i].height = plates[i].height / scale_factor;
plates[i].height = plates[i].height / scale_factor;
}
return plates;
return plates;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,7 +25,7 @@
#include <iostream>
#include <stdio.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
@@ -36,10 +36,10 @@
#include "support/timing.h"
#include "constants.h"
class RegionDetector
{
@@ -52,17 +52,17 @@ class RegionDetector
private:
Config* config;
float scale_factor;
CascadeClassifier* plate_cascade;
bool loaded;
vector<Rect> doCascade(Mat frame);
};
#endif // REGIONDETECTOR_H

View File

@@ -4,5 +4,5 @@ set(simpleini_source_files
ConvertUTF.c
)
add_library(simpleini ${simpleini_source_files})
add_library(simpleini ${simpleini_source_files})

View File

@@ -1,8 +1,8 @@
/*
* Copyright 2001-2004 Unicode, Inc.
*
*
* Disclaimer
*
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
@@ -10,9 +10,9 @@
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
*
* Limitations on Rights to Redistribute This Code
*
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
@@ -59,7 +59,7 @@ static const UTF32 halfMask = 0x3FFUL;
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
@@ -108,7 +108,7 @@ ConversionResult ConvertUTF32toUTF16 (
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
@@ -187,7 +187,7 @@ static const char trailingBytesForUTF8[256] = {
* This table contains as many values as there might be trailing bytes
* in a UTF-8 sequence.
*/
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
/*
@@ -212,7 +212,7 @@ static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF16* source = *sourceStart;
@@ -221,7 +221,7 @@ ConversionResult ConvertUTF16toUTF8 (
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
const UTF32 byteMark = 0x80;
const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
@@ -334,7 +334,7 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;
@@ -407,7 +407,7 @@ ConversionResult ConvertUTF8toUTF16 (
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF32* source = *sourceStart;
@@ -416,7 +416,7 @@ ConversionResult ConvertUTF32toUTF8 (
UTF32 ch;
unsigned short bytesToWrite = 0;
const UTF32 byteMask = 0xBF;
const UTF32 byteMark = 0x80;
const UTF32 byteMark = 0x80;
ch = *source++;
if (flags == strictConversion ) {
/* UTF-16 surrogate values are illegal in UTF-32 */
@@ -438,7 +438,7 @@ ConversionResult ConvertUTF32toUTF8 (
ch = UNI_REPLACEMENT_CHAR;
result = sourceIllegal;
}
target += bytesToWrite;
if (target > targetEnd) {
--source; /* Back up source pointer! */
@@ -460,7 +460,7 @@ ConversionResult ConvertUTF32toUTF8 (
/* --------------------------------------------------------------------- */
ConversionResult ConvertUTF8toUTF32 (
const UTF8** sourceStart, const UTF8* sourceEnd,
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
ConversionResult result = conversionOK;
const UTF8* source = *sourceStart;

View File

@@ -1,8 +1,8 @@
/*
* Copyright 2001-2004 Unicode, Inc.
*
*
* Disclaimer
*
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
@@ -10,9 +10,9 @@
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
*
* Limitations on Rights to Redistribute This Code
*
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
@@ -33,7 +33,7 @@
Each routine converts the text between *sourceStart and sourceEnd,
putting the result into the buffer between *targetStart and
targetEnd. Note: the end pointers are *after* the last item: e.g.
targetEnd. Note: the end pointers are *after* the last item: e.g.
*(sourceEnd - 1) is the last item.
The return result indicates whether the conversion was successful,
@@ -71,7 +71,7 @@
sequence is malformed. When "sourceIllegal" is returned, the source
value will point to the illegal value that caused the problem. E.g.,
in UTF-8 when a sequence is malformed, it points to the start of the
malformed sequence.
malformed sequence.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
@@ -117,27 +117,27 @@ extern "C" {
#endif
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF8 (
const UTF16** sourceStart, const UTF16* sourceEnd,
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF8toUTF32 (
const UTF8** sourceStart, const UTF8* sourceEnd,
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF8 (
const UTF32** sourceStart, const UTF32* sourceEnd,
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF16toUTF32 (
const UTF16** sourceStart, const UTF16* sourceEnd,
const UTF16** sourceStart, const UTF16* sourceEnd,
UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);

View File

@@ -78,14 +78,14 @@ ini.GetAllKeys("section-name", keys);
```c++
// get the value of a key
const char * pszValue = ini.GetValue("section-name",
const char * pszValue = ini.GetValue("section-name",
"key-name", NULL /*default*/);
// get the value of a key which may have multiple
// values. If bHasMultipleValues is true, then just
// get the value of a key which may have multiple
// values. If bHasMultipleValues is true, then just
// one value has been returned
bool bHasMultipleValues;
pszValue = ini.GetValue("section-name", "key-name",
pszValue = ini.GetValue("section-name", "key-name",
NULL /*default*/, &amp;bHasMultipleValues);
// get all values of a key with multiple values
@@ -97,7 +97,7 @@ values.sort(CSimpleIniA::Entry::LoadOrder());
// output all of the items
CSimpleIniA::TNamesDepend::const_iterator i;
for (i = values.begin(); i != values.end(); ++i) {
for (i = values.begin(); i != values.end(); ++i) {
printf("key-name = '%s'\n", i->pItem);
}
```
@@ -108,20 +108,20 @@ for (i = values.begin(); i != values.end(); ++i) {
// adding a new section
rc = ini.SetValue("new-section", NULL, NULL);
if (rc < 0) return false;
printf("section: %s\n", rc == SI_INSERTED ?
printf("section: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
// adding a new key ("new-section" will be added
// adding a new key ("new-section" will be added
// automatically if it doesn't already exist)
rc = ini.SetValue("new-section", "new-key", "value");
if (rc < 0) return false;
printf("key: %s\n", rc == SI_INSERTED ?
printf("key: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
// changing the value of a key
rc = ini.SetValue("section", "key", "updated-value");
if (rc < 0) return false;
printf("key: %s\n", rc == SI_INSERTED ?
printf("key: %s\n", rc == SI_INSERTED ?
"inserted" : "updated");
```
@@ -130,7 +130,7 @@ printf("key: %s\n", rc == SI_INSERTED ?
```c++
// deleting a key from a section. Optionally the entire
// section may be deleted if it is now empty.
ini.Delete("section-name", "key-name",
ini.Delete("section-name", "key-name",
true /*delete the section if empty*/);
// deleting an entire section and all keys in it

View File

@@ -1,5 +1,5 @@
; Syntax file for ini files - contributed by Brodie Thiesfield
;
;
; Suggested Colors:
; Comments (;#) Comments, Comments 2 Green
; Sections Characters Red
@@ -13,24 +13,24 @@ IgnoreCase = Yes
KeyWordLength = 1
BracketChars =
OperatorChars =
PreprocStart =
PreprocStart =
SyntaxStart =
SyntaxEnd =
HexPrefix =
CommentStart =
CommentEnd =
CommentStartAlt =
CommentEndAlt =
CommentStart =
CommentEnd =
CommentStartAlt =
CommentEndAlt =
SingleComment = #
SingleCommentCol =
SingleCommentAlt = ;
SingleCommentColAlt =
SingleCommentEsc =
StringsSpanLines = No
StringStart =
StringEnd =
StringStart =
StringEnd =
StringAlt = =
StringEsc =
StringEsc =
CharStart = [
CharEnd = ]
CharEsc =

File diff suppressed because it is too large Load Diff

View File

@@ -163,7 +163,7 @@
SI_NO_MBCS. This is defined automatically on Windows CE platforms.
@section contrib CONTRIBUTIONS
- 2010/05/03: Tobias Gehrig: added GetDoubleValue()
@section licence MIT LICENCE
@@ -530,7 +530,7 @@ public:
bool IsMultiLine() const { return m_bAllowMultiLine; }
/** Should spaces be added around the equals sign when writing key/value
pairs out. When true, the result will be "key = value". When false,
pairs out. When true, the result will be "key = value". When false,
the result will be "key=value". This value may be changed at any time.
\param a_bSpaces Add spaces around the equals sign?
@@ -541,7 +541,7 @@ public:
/** Query the status of spaces output */
bool UsingSpaces() const { return m_bSpaces; }
/*-----------------------------------------------------------------------*/
/** @}
@{ @name Loading INI Data */
@@ -771,8 +771,8 @@ public:
) const;
/** Retrieve all unique key names in a section. The sort order of the
returned strings is NOT DEFINED. You can sort the names into the load
order if desired. Search this file for ".sort" for an example. Only
returned strings is NOT DEFINED. You can sort the names into the load
order if desired. Search this file for ".sort" for an example. Only
unique key names are returned.
NOTE! This structure contains only pointers to strings. The actual
@@ -793,8 +793,8 @@ public:
) const;
/** Retrieve all values for a specific key. This method can be used when
multiple keys are both enabled and disabled. Note that the sort order
of the returned strings is NOT DEFINED. You can sort the names into
multiple keys are both enabled and disabled. Note that the sort order
of the returned strings is NOT DEFINED. You can sort the names into
the load order if desired. Search this file for ".sort" for an example.
NOTE! The returned values are pointers to string data stored in memory
@@ -915,7 +915,7 @@ public:
Strings starting with "t", "y", "on" or "1" are returned as logically true.
Strings starting with "f", "n", "of" or "0" are returned as logically false.
For all other values the default is returned. Character comparisons are
For all other values the default is returned. Character comparisons are
case-insensitive.
@param a_pSection Section to search
@@ -954,9 +954,9 @@ public:
character starting every line).
@param a_bForceReplace Should all existing values in a multi-key INI
file be replaced with this entry. This option has
no effect if not using multi-key files. The
no effect if not using multi-key files. The
difference between Delete/SetValue and SetValue
with a_bForceReplace = true, is that the load
with a_bForceReplace = true, is that the load
order and comment will be preserved this way.
@return SI_Error See error definitions
@@ -978,19 +978,19 @@ public:
when multiple keys are enabled.
@param a_pSection Section to add or update
@param a_pKey Key to add or update.
@param a_nValue Value to set.
@param a_pComment Comment to be associated with the key. See the
@param a_pKey Key to add or update.
@param a_nValue Value to set.
@param a_pComment Comment to be associated with the key. See the
notes on SetValue() for comments.
@param a_bUseHex By default the value will be written to the file
in decimal format. Set this to true to write it
@param a_bUseHex By default the value will be written to the file
in decimal format. Set this to true to write it
as hexadecimal.
@param a_bForceReplace Should all existing values in a multi-key INI
file be replaced with this entry. This option has
no effect if not using multi-key files. The
difference between Delete/SetLongValue and
SetLongValue with a_bForceReplace = true, is that
the load order and comment will be preserved this
no effect if not using multi-key files. The
difference between Delete/SetLongValue and
SetLongValue with a_bForceReplace = true, is that
the load order and comment will be preserved this
way.
@return SI_Error See error definitions
@@ -1010,16 +1010,16 @@ public:
when multiple keys are enabled.
@param a_pSection Section to add or update
@param a_pKey Key to add or update.
@param a_nValue Value to set.
@param a_pComment Comment to be associated with the key. See the
@param a_pKey Key to add or update.
@param a_nValue Value to set.
@param a_pComment Comment to be associated with the key. See the
notes on SetValue() for comments.
@param a_bForceReplace Should all existing values in a multi-key INI
file be replaced with this entry. This option has
no effect if not using multi-key files. The
difference between Delete/SetDoubleValue and
SetDoubleValue with a_bForceReplace = true, is that
the load order and comment will be preserved this
no effect if not using multi-key files. The
difference between Delete/SetDoubleValue and
SetDoubleValue with a_bForceReplace = true, is that
the load order and comment will be preserved this
way.
@return SI_Error See error definitions
@@ -1038,16 +1038,16 @@ public:
when multiple keys are enabled.
@param a_pSection Section to add or update
@param a_pKey Key to add or update.
@param a_bValue Value to set.
@param a_pComment Comment to be associated with the key. See the
@param a_pKey Key to add or update.
@param a_bValue Value to set.
@param a_pComment Comment to be associated with the key. See the
notes on SetValue() for comments.
@param a_bForceReplace Should all existing values in a multi-key INI
file be replaced with this entry. This option has
no effect if not using multi-key files. The
difference between Delete/SetBoolValue and
SetBoolValue with a_bForceReplace = true, is that
the load order and comment will be preserved this
no effect if not using multi-key files. The
difference between Delete/SetBoolValue and
SetBoolValue with a_bForceReplace = true, is that
the load order and comment will be preserved this
way.
@return SI_Error See error definitions
@@ -1141,9 +1141,9 @@ private:
comment character starting every line).
@param a_bForceReplace Should all existing values in a multi-key INI
file be replaced with this entry. This option has
no effect if not using multi-key files. The
no effect if not using multi-key files. The
difference between Delete/AddEntry and AddEntry
with a_bForceReplace = true, is that the load
with a_bForceReplace = true, is that the load
order and comment will be preserved this way.
@param a_bCopyStrings Should copies of the strings be made or not.
If false then the pointers will be used as is.
@@ -1238,7 +1238,7 @@ private:
/** Should spaces be written out surrounding the equals sign? */
bool m_bSpaces;
/** Next order value, used to ensure sections and keys are output in the
same order that they are loaded/added.
*/
@@ -1358,14 +1358,14 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::LoadFile(
if (lSize == 0) {
return SI_OK;
}
// allocate and ensure NULL terminated
char * pData = new char[lSize+1];
if (!pData) {
return SI_NOMEM;
}
pData[lSize] = 0;
// load data into buffer
fseek(a_fpFile, 0, SEEK_SET);
size_t uRead = fread(pData, sizeof(char), lSize, a_fpFile);
@@ -2018,15 +2018,15 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::GetLongValue(
}
// any invalid strings will return the default value
if (*pszSuffix) {
return a_nDefault;
if (*pszSuffix) {
return a_nDefault;
}
return nValue;
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetLongValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
@@ -2050,7 +2050,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetLongValue(
// convert to output text
SI_CHAR szOutput[64];
SI_CONVERTER c(m_bStoreIsUtf8);
c.ConvertFromStore(szInput, strlen(szInput) + 1,
c.ConvertFromStore(szInput, strlen(szInput) + 1,
szOutput, sizeof(szOutput) / sizeof(SI_CHAR));
// actually add it
@@ -2081,15 +2081,15 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::GetDoubleValue(
double nValue = strtod(szValue, &pszSuffix);
// any invalid strings will return the default value
if (!pszSuffix || *pszSuffix) {
return a_nDefault;
if (!pszSuffix || *pszSuffix) {
return a_nDefault;
}
return nValue;
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetDoubleValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
@@ -2112,7 +2112,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetDoubleValue(
// convert to output text
SI_CHAR szOutput[64];
SI_CONVERTER c(m_bStoreIsUtf8);
c.ConvertFromStore(szInput, strlen(szInput) + 1,
c.ConvertFromStore(szInput, strlen(szInput) + 1,
szOutput, sizeof(szOutput) / sizeof(SI_CHAR));
// actually add it
@@ -2155,7 +2155,7 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::GetBoolValue(
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
SI_Error
SI_Error
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetBoolValue(
const SI_CHAR * a_pSection,
const SI_CHAR * a_pKey,
@@ -2173,13 +2173,13 @@ CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::SetBoolValue(
// convert to output text
SI_CHAR szOutput[64];
SI_CONVERTER c(m_bStoreIsUtf8);
c.ConvertFromStore(pszInput, strlen(pszInput) + 1,
c.ConvertFromStore(pszInput, strlen(pszInput) + 1,
szOutput, sizeof(szOutput) / sizeof(SI_CHAR));
// actually add it
return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true);
}
template<class SI_CHAR, class SI_STRLESS, class SI_CONVERTER>
bool
CSimpleIniTempl<SI_CHAR,SI_STRLESS,SI_CONVERTER>::GetAllValues(
@@ -3383,4 +3383,3 @@ typedef CSimpleIniTempl<wchar_t,
#endif
#endif // INCLUDED_SimpleIni_h

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,15 +23,15 @@
StateIdentifier::StateIdentifier(Config* config)
{
this->config = config;
featureMatcher = new FeatureMatcher(config);
if (featureMatcher->isLoaded() == false)
{
cout << "Can not create detector or descriptor extractor or descriptor matcher of given types" << endl;
return;
}
featureMatcher->loadRecognitionSet(config->country);
}
@@ -43,56 +43,55 @@ StateIdentifier::~StateIdentifier()
int StateIdentifier::recognize(Mat img, Rect frame, char* stateCode)
{
Mat croppedImage = Mat(img, frame);
return this->recognize(croppedImage, stateCode);
}
// Attempts to recognize the plate. Returns a confidence level. Updates teh "stateCode" variable
// Attempts to recognize the plate. Returns a confidence level. Updates teh "stateCode" variable
// with the value of the country/state
int StateIdentifier::recognize(Mat img, char* stateCode)
{
timespec startTime;
getTime(&startTime);
cvtColor(img, img, CV_BGR2GRAY);
resize(img, img, getSizeMaintainingAspect(img, config->stateIdImageWidthPx, config->stateIdimageHeightPx));
Mat plateImg(img.size(), img.type());
//plateImg = equalizeBrightness(img);
img.copyTo(plateImg);
Mat debugImg(plateImg.size(), plateImg.type());
plateImg.copyTo(debugImg);
vector<int> matchesArray(featureMatcher->numTrainingElements());
RecognitionResult result = featureMatcher->recognize(plateImg, true, &debugImg, true, matchesArray );
if (this->config->debugStateId)
{
displayImage(config, "State Identifier1", plateImg);
displayImage(config, "State Identifier", debugImg);
cout << result.haswinner << " : " << result.confidence << " : " << result.winner << endl;
}
if (config->debugTiming)
{
timespec endTime;
getTime(&endTime);
cout << "State Identification Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
if (result.haswinner == false)
return 0;
strcpy(stateCode, result.winner.c_str());
return result.confidence;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -39,20 +39,18 @@ class StateIdentifier
int recognize(Mat img, Rect frame, char* stateCode);
int recognize(Mat img, char* stateCode);
//int confidence;
protected:
Config* config;
private:
FeatureMatcher* featureMatcher;
};
#endif // STATEIDENTIFIER_H

View File

@@ -5,5 +5,5 @@ set(support_source_files
timing.cpp
)
add_library(support ${support_source_files})
add_library(support ${support_source_files})

View File

@@ -22,7 +22,7 @@ bool DirectoryExists( const char* pzPath )
if (pDir != NULL)
{
bExists = true;
bExists = true;
(void) closedir (pDir);
}
@@ -34,7 +34,7 @@ bool fileExists( const char* pzPath )
if (pzPath == NULL) return false;
bool fExists = false;
std::ifstream f(pzPath);
std::ifstream f(pzPath);
fExists = f.is_open();
f.close();
return fExists;
@@ -43,9 +43,9 @@ bool fileExists( const char* pzPath )
std::vector<std::string> getFilesInDir(const char* dirPath)
{
DIR *dir;
std::vector<std::string> files;
struct dirent *ent;
if ((dir = opendir (dirPath)) != NULL) {
/* print all the files and directories within directory */
@@ -59,7 +59,7 @@ std::vector<std::string> getFilesInDir(const char* dirPath)
perror ("");
return files;
}
return files;
}
@@ -73,4 +73,4 @@ bool stringCompare( const std::string &left, const std::string &right ){
if( left.size() < right.size() )
return true;
return false;
}
}

View File

@@ -23,8 +23,8 @@
bool DirectoryExists( const char* pzPath );
bool fileExists( const char* pzPath );
std::vector<std::string> getFilesInDir(const char* dirPath);
bool stringCompare( const std::string &left, const std::string &right );
#endif // FILESYSTEM_H
#endif // FILESYSTEM_H

View File

@@ -76,8 +76,8 @@ double diffclock(timespec time1,timespec time2)
{
timespec delta = diff(time1,time2);
double milliseconds = (delta.tv_sec * 1000) + (((double) delta.tv_usec) / 1000.0);
return milliseconds;
}
@@ -116,13 +116,13 @@ void getTime(timespec* time)
}
double diffclock(timespec time1,timespec time2)
{
timespec delta = diff(time1,time2);
double milliseconds = (delta.tv_sec * 1000) + (((double) delta.tv_nsec) / 1000000.0);
return milliseconds;
}

View File

@@ -18,6 +18,6 @@
void getTime(timespec* time);
double diffclock(timespec time1,timespec time2);
#endif
#endif

View File

@@ -33,7 +33,7 @@
* capital W) in order to maintain compatibility with MingW.
*
* Version 1.12, Sep 30 2012, Toni Ronkko
* Define PATH_MAX and NAME_MAX. Added wide-character variants _wDIR,
* Define PATH_MAX and NAME_MAX. Added wide-character variants _wDIR,
* _wdirent, _wopendir(), _wreaddir(), _wclosedir() and _wrewinddir().
* Thanks to Edgar Buerkle and Jan Nijtmans for ideas and code.
*
@@ -410,11 +410,11 @@ _wreaddir(
if (datap) {
size_t n;
DWORD attr;
/* Pointer to directory entry to return */
entp = &dirp->ent;
/*
/*
* Copy file name as wide-character string. If the file name is too
* long to fit in to the destination buffer, then truncate file name
* to PATH_MAX characters and zero-terminate the buffer.
@@ -570,12 +570,12 @@ dirent_next(
return p;
}
/*
/*
* Open directory stream using plain old C-string.
*/
static DIR*
opendir(
const char *dirname)
const char *dirname)
{
struct DIR *dirp;
int error;
@@ -608,7 +608,7 @@ opendir(
}
} else {
/*
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
@@ -646,7 +646,7 @@ opendir(
*/
static struct dirent*
readdir(
DIR *dirp)
DIR *dirp)
{
WIN32_FIND_DATAW *datap;
struct dirent *entp;
@@ -661,7 +661,7 @@ readdir(
error = dirent_wcstombs_s(
&n, dirp->ent.d_name, MAX_PATH + 1, datap->cFileName, MAX_PATH);
/*
/*
* If the file name cannot be represented by a multi-byte string,
* then attempt to use old 8+3 file name. This allows traditional
* Unix-code to access some file names despite of unicode
@@ -674,7 +674,7 @@ readdir(
if (error && datap->cAlternateFileName[0] != '\0') {
error = dirent_wcstombs_s(
&n, dirp->ent.d_name, MAX_PATH + 1, datap->cAlternateFileName,
sizeof (datap->cAlternateFileName) /
sizeof (datap->cAlternateFileName) /
sizeof (datap->cAlternateFileName[0]));
}
@@ -702,7 +702,7 @@ readdir(
entp->d_reclen = sizeof (struct dirent);
} else {
/*
/*
* Cannot convert file name to multi-byte string so construct
* an errornous directory entry and return that. Note that
* we cannot return NULL as that would stop the processing
@@ -730,7 +730,7 @@ readdir(
*/
static int
closedir(
DIR *dirp)
DIR *dirp)
{
int ok;
if (dirp) {
@@ -757,7 +757,7 @@ closedir(
*/
static void
rewinddir(
DIR* dirp)
DIR* dirp)
{
/* Rewind wide-character string directory stream */
_wrewinddir (dirp->wdirp);
@@ -886,4 +886,3 @@ dirent_set_errno(
}
#endif
#endif /*DIRENT_H*/

View File

@@ -1,9 +1,9 @@
#ifndef _UNISTD_H
#define _UNISTD_H 1
/* This file intended to serve as a drop-in replacement for
/* This file intended to serve as a drop-in replacement for
* unistd.h on Windows
* Please add functionality as neeeded
* Please add functionality as neeeded
*/
#include <stdlib.h>
@@ -31,7 +31,7 @@
#define STDERR_FILENO 2
/* should be in some equivalent to <sys/types.h> */
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
@@ -39,4 +39,4 @@ typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#endif /* unistd.h */
#endif /* unistd.h */

View File

@@ -2,6 +2,6 @@
#include <math.h>
static inline double round(double val)
{
{
return floor(val + 0.5);
}
}

View File

@@ -105,7 +105,7 @@ static void trex_error(TRex *exp,const TRexChar *error)
}
static void trex_expect(TRex *exp, int n){
if((*exp->_p) != n)
if((*exp->_p) != n)
trex_error(exp, _SC("expected paren"));
exp->_p++;
}
@@ -144,31 +144,31 @@ static int trex_charnode(TRex *exp,TRexBool isclass)
case 'r': exp->_p++; return trex_newnode(exp,'\r');
case 'f': exp->_p++; return trex_newnode(exp,'\f');
case 'v': exp->_p++; return trex_newnode(exp,'\v');
case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
case 'p': case 'P': case 'l': case 'u':
case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
case 'p': case 'P': case 'l': case 'u':
{
t = *exp->_p; exp->_p++;
t = *exp->_p; exp->_p++;
return trex_charclass(exp,t);
}
case 'b':
case 'b':
case 'B':
if(!isclass) {
int node = trex_newnode(exp,OP_WB);
exp->_nodes[node].left = *exp->_p;
exp->_p++;
exp->_p++;
return node;
} //else default
default:
t = *exp->_p; exp->_p++;
default:
t = *exp->_p; exp->_p++;
return trex_newnode(exp,t);
}
}
else if(!scisprint(*exp->_p)) {
trex_error(exp,_SC("letter expected"));
}
t = *exp->_p; exp->_p++;
t = *exp->_p; exp->_p++;
return trex_newnode(exp,t);
}
static int trex_class(TRex *exp)
@@ -179,11 +179,11 @@ static int trex_class(TRex *exp)
ret = trex_newnode(exp,OP_NCLASS);
exp->_p++;
}else ret = trex_newnode(exp,OP_CLASS);
if(*exp->_p == ']') trex_error(exp,_SC("empty class"));
chain = ret;
while(*exp->_p != ']' && exp->_p != exp->_eol) {
if(*exp->_p == '-' && first != -1){
if(*exp->_p == '-' && first != -1){
int r,t;
if(*exp->_p++ == ']') trex_error(exp,_SC("unfinished range"));
r = trex_newnode(exp,OP_RANGE);
@@ -297,7 +297,7 @@ static int trex_element(TRex *exp)
trex_error(exp,_SC(", or } expected"));
}
/*******************************/
isgreedy = TRex_True;
isgreedy = TRex_True;
break;
}
@@ -384,7 +384,7 @@ static TRexBool trex_matchclass(TRex* exp,TRexNode *node,TRexChar c)
static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *str,TRexNode *next)
{
TRexNodeType type = node->type;
switch(type) {
case OP_GREEDY: {
@@ -428,7 +428,7 @@ static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *s
}
}
}
if(s >= exp->_eol)
break;
}
@@ -467,7 +467,7 @@ static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *s
exp->_matches[capture].begin = cur;
exp->_currsubexp++;
}
do {
TRexNode *subnext = NULL;
if(n->next != -1) {
@@ -484,10 +484,10 @@ static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *s
}
} while((n->next != -1) && (n = &exp->_nodes[n->next]));
if(capture != -1)
if(capture != -1)
exp->_matches[capture].len = cur - exp->_matches[capture].begin;
return cur;
}
}
case OP_WB:
if(str == exp->_bol && !isspace(*str)
|| (str == exp->_eol && !isspace(*(str-1)))
@@ -640,4 +640,3 @@ TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp)
*subexp = exp->_matches[n];
return TRex_True;
}

View File

@@ -5,11 +5,11 @@
Copyright (C) 2003-2006 Alberto Demichelis
This software is provided 'as-is', without any express
or implied warranty. In no event will the authors be held
This software is provided 'as-is', without any express
or implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for
Permission is granted to anyone to use this software for
any purpose, including commercial applications, and to alter
it and redistribute it freely, subject to the following restrictions:
@@ -30,13 +30,13 @@
#ifdef _UNICODE
#define TRexChar unsigned short
#define MAX_CHAR 0xFFFF
#define _TREXC(c) L##c
#define _TREXC(c) L##c
#define trex_strlen wcslen
#define trex_printf wprintf
#else
#define TRexChar char
#define MAX_CHAR 0xFF
#define _TREXC(c) (c)
#define _TREXC(c) (c)
#define trex_strlen strlen
#define trex_printf printf
#endif

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -26,14 +26,14 @@
Rect expandRect(Rect original, int expandXPixels, int expandYPixels, int maxX, int maxY)
{
Rect expandedRegion = Rect(original);
float halfX = round((float) expandXPixels / 2.0);
float halfY = round((float) expandYPixels / 2.0);
expandedRegion.x = expandedRegion.x - halfX;
expandedRegion.width = expandedRegion.width + expandXPixels;
expandedRegion.y = expandedRegion.y - halfY;
expandedRegion.height = expandedRegion.height + expandYPixels;
if (expandedRegion.x < 0)
expandedRegion.x = 0;
if (expandedRegion.y < 0)
@@ -42,16 +42,16 @@ Rect expandRect(Rect original, int expandXPixels, int expandYPixels, int maxX, i
expandedRegion.width = maxX - expandedRegion.x;
if (expandedRegion.y + expandedRegion.height > maxY)
expandedRegion.height = maxY - expandedRegion.y;
return expandedRegion;
}
Mat drawImageDashboard(vector<Mat> images, int imageType, int numColumns)
{
int numRows = ceil((float) images.size() / (float) numColumns);
Mat dashboard(Size(images[0].cols * numColumns, images[0].rows * numRows), imageType);
for (int i = 0; i < numColumns * numRows; i++)
{
if (i < images.size())
@@ -62,7 +62,7 @@ Mat drawImageDashboard(vector<Mat> images, int imageType, int numColumns)
black.copyTo(dashboard(Rect((i%numColumns) * images[0].cols, floor((float) i/numColumns) * images[0].rows, images[0].cols, images[0].rows)));
}
}
return dashboard;
}
@@ -73,20 +73,20 @@ Mat addLabel(Mat input, string label)
const int extraHeight = 20;
const Scalar bg(222,222,222);
const Scalar fg(0,0,0);
Rect destinationRect(border_size, extraHeight, input.cols, input.rows);
Mat newImage(Size(input.cols + (border_size), input.rows + extraHeight + (border_size )), input.type());
input.copyTo(newImage(destinationRect));
cout << " Adding label " << label << endl;
if (input.type() == CV_8U)
cvtColor(newImage, newImage, CV_GRAY2BGR);
rectangle(newImage, Point(0,0), Point(input.cols, extraHeight), bg, CV_FILLED);
putText(newImage, label, Point(5, extraHeight - 5), CV_FONT_HERSHEY_PLAIN , 0.7, fg);
rectangle(newImage, Point(0,0), Point(newImage.cols - 1, newImage.rows -1), border_color, border_size);
return newImage;
}
@@ -95,12 +95,12 @@ Mat addLabel(Mat input, string label)
void drawAndWait(cv::Mat* frame)
{
cv::imshow("Temp Window", *frame);
while (cv::waitKey(50) == -1)
{
// loop
}
cv::destroyWindow("Temp Window");
}
@@ -114,35 +114,35 @@ vector<Mat> produceThresholds(const Mat img_gray, Config* config)
{
const int THRESHOLD_COUNT = 4;
//Mat img_equalized = equalizeBrightness(img_gray);
timespec startTime;
getTime(&startTime);
vector<Mat> thresholds;
for (int i = 0; i < THRESHOLD_COUNT; i++)
thresholds.push_back(Mat(img_gray.size(), CV_8U));
int i = 0;
// Adaptive
//adaptiveThreshold(img_gray, thresholds[i++], 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV , 7, 3);
//adaptiveThreshold(img_gray, thresholds[i++], 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV , 13, 3);
//adaptiveThreshold(img_gray, thresholds[i++], 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV , 17, 3);
// Wolf
int k = 0, win=18;
//NiblackSauvolaWolfJolion (img_gray, thresholds[i++], WOLFJOLION, win, win, 0.05 + (k * 0.35));
//bitwise_not(thresholds[i-1], thresholds[i-1]);
NiblackSauvolaWolfJolion (img_gray, thresholds[i++], WOLFJOLION, win, win, 0.05 + (k * 0.35));
bitwise_not(thresholds[i-1], thresholds[i-1]);
k = 1; win = 22;
NiblackSauvolaWolfJolion (img_gray, thresholds[i++], WOLFJOLION, win, win, 0.05 + (k * 0.35));
bitwise_not(thresholds[i-1], thresholds[i-1]);
//NiblackSauvolaWolfJolion (img_gray, thresholds[i++], WOLFJOLION, win, win, 0.05 + (k * 0.35));
//bitwise_not(thresholds[i-1], thresholds[i-1]);
// Sauvola
k = 1;
NiblackSauvolaWolfJolion (img_gray, thresholds[i++], SAUVOLA, 12, 12, 0.18 * k);
@@ -150,22 +150,22 @@ vector<Mat> produceThresholds(const Mat img_gray, Config* config)
k=2;
NiblackSauvolaWolfJolion (img_gray, thresholds[i++], SAUVOLA, 12, 12, 0.18 * k);
bitwise_not(thresholds[i-1], thresholds[i-1]);
if (config->debugTiming)
{
timespec endTime;
getTime(&endTime);
cout << " -- Produce Threshold Time: " << diffclock(startTime, endTime) << "ms." << endl;
}
return thresholds;
//threshold(img_equalized, img_threshold, 100, 255, THRESH_BINARY);
}
double median(int array[], int arraySize)
@@ -175,7 +175,7 @@ double median(int array[], int arraySize)
//std::cerr << "Median calculation requested on empty array" << endl;
return 0;
}
std::sort(&array[0], &array[arraySize]);
return arraySize % 2 ? array[arraySize / 2] : (array[arraySize / 2 - 1] + array[arraySize / 2]) / 2;
}
@@ -183,7 +183,7 @@ double median(int array[], int arraySize)
Mat equalizeBrightness(Mat img)
{
// Divide the image by its morphologically closed counterpart
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
Mat closed;
@@ -193,7 +193,7 @@ Mat equalizeBrightness(Mat img)
divide(img, closed, img, 1, CV_32FC1);
normalize(img, img, 0, 255, NORM_MINMAX);
img.convertTo(img, CV_8U); // convert back to unsigned int
return img;
}
@@ -201,7 +201,7 @@ Mat equalizeBrightness(Mat img)
void drawRotatedRect(Mat* img, RotatedRect rect, Scalar color, int thickness)
{
Point2f rect_points[4];
Point2f rect_points[4];
rect.points( rect_points );
for( int j = 0; j < 4; j++ )
line( *img, rect_points[j], rect_points[(j+1)%4], color, thickness, 8 );
@@ -215,7 +215,7 @@ void fillMask(Mat img, const Mat mask, Scalar color)
for (int col = 0; col < img.cols; col++)
{
int m = (int) mask.at<uchar>(row, col);
if (m)
{
for (int z = 0; z < 3; z++)
@@ -236,7 +236,7 @@ void drawX(Mat img, Rect rect, Scalar color, int thickness)
Point tr(rect.x + rect.width, rect.y);
Point bl(rect.x, rect.y + rect.height);
Point br(rect.x + rect.width, rect.y + rect.height);
line(img, tl, br, color, thickness);
line(img, bl, tr, color, thickness);
}
@@ -245,7 +245,7 @@ double distanceBetweenPoints(Point p1, Point p2)
{
float asquared = (p2.x - p1.x)*(p2.x - p1.x);
float bsquared = (p2.y - p1.y)*(p2.y - p1.y);
return sqrt(asquared + bsquared);
}
@@ -253,7 +253,7 @@ float angleBetweenPoints(Point p1, Point p2)
{
int deltaY = p2.y - p1.y;
int deltaX = p2.x - p1.x;
return atan2((float) deltaY, (float) deltaX) * (180 / CV_PI);
}
@@ -261,7 +261,7 @@ float angleBetweenPoints(Point p1, Point p2)
Size getSizeMaintainingAspect(Mat inputImg, int maxWidth, int maxHeight)
{
float aspect = ((float) inputImg.cols) / ((float) inputImg.rows);
if (maxWidth / aspect > maxHeight)
{
return Size(maxHeight * aspect, maxHeight);
@@ -296,9 +296,9 @@ void LineSegment::init(int x1, int y1, int x2, int y2)
this->slope = 0.00000000001;
else
this->slope = (float) (p2.y - p1.y) / (float) (p2.x - p1.x);
this->length = distanceBetweenPoints(p1, p2);
this->angle = angleBetweenPoints(p1, p2);
}
@@ -314,15 +314,15 @@ float LineSegment::getPointAt(float x)
Point LineSegment::closestPointOnSegmentTo(Point p)
{
float top = (p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y)*(p2.y - p1.y);
float bottom = distanceBetweenPoints(p2, p1);
bottom = bottom * bottom;
float u = top / bottom;
float x = p1.x + u * (p2.x - p1.x);
float y = p1.y + u * (p2.y - p1.y);
return Point(x, y);
}
@@ -330,12 +330,12 @@ Point LineSegment::intersection(LineSegment line)
{
float c1, c2;
float intersection_X = -1, intersection_Y= -1;
c1 = p1.y - slope * p1.x; // which is same as y2 - slope * x2
c2 = line.p2.y - line.slope * line.p2.x; // which is same as y2 - slope * x2
if( (slope - line.slope) == 0)
{
//std::cout << "No Intersection between the lines" << endl;
@@ -344,7 +344,7 @@ Point LineSegment::intersection(LineSegment line)
{
// Line1 is vertical
return Point(p1.x, line.getPointAt(p1.x));
}
}
else if (line.p1.x == line.p2.x)
{
// Line2 is vertical
@@ -354,11 +354,11 @@ Point LineSegment::intersection(LineSegment line)
{
intersection_X = (c2 - c1) / (slope - line.slope);
intersection_Y = slope * intersection_X + c1;
}
return Point(intersection_X, intersection_Y);
}
@@ -375,7 +375,7 @@ Point LineSegment::midpoint()
float diff = p2.x - p1.x;
float midX = ((float) p1.x) + (diff / 2);
int midY = getPointAt(midX);
return Point(midX, midY);
}
@@ -386,17 +386,12 @@ LineSegment LineSegment::getParallelLine(float distance)
float angle = atan2( diff_x, diff_y);
float dist_x = distance * cos(angle);
float dist_y = -distance * sin(angle);
int offsetX = (int)round(dist_x);
int offsetY = (int)round(dist_y);
LineSegment result(p1.x + offsetX, p1.y + offsetY,
p2.x + offsetX, p2.y + offsetY);
return result;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -38,9 +38,9 @@
#include "binarize_wolf.h"
#include <vector>
#include "config.h"
/*
struct LineSegment
{
@@ -50,70 +50,70 @@ struct LineSegment
float y2;
};
*/
class LineSegment
{
public:
Point p1, p2;
float slope;
float length;
float angle;
// LineSegment(Point point1, Point point2);
LineSegment();
LineSegment(int x1, int y1, int x2, int y2);
LineSegment(Point p1, Point p2);
void init(int x1, int y1, int x2, int y2);
bool isPointBelowLine(Point tp);
float getPointAt(float x);
Point closestPointOnSegmentTo(Point p);
Point intersection(LineSegment line);
LineSegment getParallelLine(float distance);
Point midpoint();
inline std::string str()
{
std::stringstream ss;
ss << "(" << p1.x << ", " << p1.y << ") : (" << p2.x << ", " << p2.y << ")";
return ss.str() ;
}
};
double median(int array[], int arraySize);
vector<Mat> produceThresholds(const Mat img_gray, Config* config);
Mat drawImageDashboard(vector<Mat> images, int imageType, int numColumns);
void displayImage(Config* config, string windowName, cv::Mat frame);
void drawAndWait(cv::Mat* frame);
double distanceBetweenPoints(Point p1, Point p2);
void drawRotatedRect(Mat* img, RotatedRect rect, Scalar color, int thickness);
void drawX(Mat img, Rect rect, Scalar color, int thickness);
void fillMask(Mat img, const Mat mask, Scalar color);
float angleBetweenPoints(Point p1, Point p2);
Size getSizeMaintainingAspect(Mat inputImg, int maxWidth, int maxHeight);
Mat equalizeBrightness(Mat img);
Rect expandRect(Rect original, int expandXPixels, int expandYPixels, int maxX, int maxY);
Mat addLabel(Mat input, string label);
#endif // UTILITY_H

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -22,9 +22,9 @@
VerticalHistogram::VerticalHistogram(Mat inputImage, Mat mask)
{
analyzeImage(inputImage, mask);
}
VerticalHistogram::~VerticalHistogram()
@@ -38,44 +38,44 @@ void VerticalHistogram::analyzeImage(Mat inputImage, Mat mask)
{
highestPeak = 0;
lowestValley = inputImage.rows;
histoImg = Mat::zeros(inputImage.size(), CV_8U);
int columnCount;
for (int col = 0; col < inputImage.cols; col++)
{
columnCount = 0;
for (int row = 0; row < inputImage.rows; row++)
{
if (inputImage.at<uchar>(row, col) > 0 && mask.at<uchar>(row, col) > 0)
columnCount++;
}
this->colHeights.push_back(columnCount);
if (columnCount < lowestValley)
lowestValley = columnCount;
if (columnCount > highestPeak)
highestPeak = columnCount;
for (; columnCount > 0; columnCount--)
histoImg.at<uchar>(inputImage.rows - columnCount, col) = 255;
}
}
int VerticalHistogram::getLocalMinimum(int leftX, int rightX)
{
int minimum = histoImg.rows + 1;
int lowestX = leftX;
for (int i = leftX; i <= rightX; i++)
{
if (colHeights[i] < minimum)
@@ -84,7 +84,7 @@ int VerticalHistogram::getLocalMinimum(int leftX, int rightX)
minimum = colHeights[i];
}
}
return lowestX;
}
@@ -92,7 +92,7 @@ int VerticalHistogram::getLocalMaximum(int leftX, int rightX)
{
int maximum = -1;
int highestX = leftX;
for (int i = leftX; i <= rightX; i++)
{
if (colHeights[i] > maximum)
@@ -101,8 +101,8 @@ int VerticalHistogram::getLocalMaximum(int leftX, int rightX)
maximum = colHeights[i];
}
}
return highestX;
return highestX;
}
int VerticalHistogram::getHeightAt(int x)
@@ -113,78 +113,78 @@ int VerticalHistogram::getHeightAt(int x)
void VerticalHistogram::findValleys()
{
int MINIMUM_PEAK_HEIGHT = (int) (((float) highestPeak) * 0.75);
int totalWidth = colHeights.size();
int midpoint = ((highestPeak - lowestValley) / 2) + lowestValley;
HistogramDirection prevDirection = FALLING;
int relativePeakHeight = 0;
int valleyStart = 0;
for (int i = 0; i < totalWidth; i++)
{
bool aboveMidpoint = (colHeights[i] >= midpoint);
if (aboveMidpoint)
{
if (colHeights[i] > relativePeakHeight)
relativePeakHeight = colHeights[i];
prevDirection = FLAT;
}
else
{
relativePeakHeight = 0;
HistogramDirection direction = getHistogramDirection(i);
if ((prevDirection == FALLING || prevDirection == FLAT) && direction == RISING)
{
}
else if ((prevDirection == FALLING || prevDirection == FLAT) && direction == RISING)
{
}
}
}
}
HistogramDirection VerticalHistogram::getHistogramDirection(int index)
{
int EXTRA_WIDTH_TO_AVERAGE = 2;
float trailingAverage = 0;
float forwardAverage = 0;
int trailStartIndex = index - EXTRA_WIDTH_TO_AVERAGE;
if (trailStartIndex < 0)
trailStartIndex = 0;
int forwardEndIndex = index + EXTRA_WIDTH_TO_AVERAGE;
if (forwardEndIndex >= colHeights.size())
forwardEndIndex = colHeights.size() - 1;
for (int i = index; i >= trailStartIndex; i--)
{
trailingAverage += colHeights[i];
}
trailingAverage = trailingAverage / ((float) (1 + index - trailStartIndex));
for (int i = index; i <= forwardEndIndex; i++)
{
forwardAverage += colHeights[i];
}
forwardAverage = forwardAverage / ((float) (1 + forwardEndIndex - index));
float diff = forwardAverage - trailingAverage;
float minDiff = ((float) (highestPeak - lowestValley)) * 0.10;
if (diff > minDiff)
return RISING;
else if (diff < minDiff)
@@ -192,5 +192,3 @@ HistogramDirection VerticalHistogram::getHistogramDirection(int index)
else
return FLAT;
}

View File

@@ -1,18 +1,18 @@
/*
* Copyright (c) 2013 New Designs Unlimited, LLC
* Opensource Automated License Plate Recognition [http://www.openalpr.com]
*
*
* This file is part of OpenAlpr.
*
*
* OpenAlpr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* it under the terms of the GNU Affero General Public License
* version 3 as published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -45,24 +45,24 @@ class VerticalHistogram
virtual ~VerticalHistogram();
Mat histoImg;
// Returns the lowest X position between two points.
int getLocalMinimum(int leftX, int rightX);
// Returns the highest X position between two points.
int getLocalMaximum(int leftX, int rightX);
int getHeightAt(int x);
private:
vector<int> colHeights;
int highestPeak;
int lowestValley;
vector<Valley> valleys;
void analyzeImage(Mat inputImage, Mat mask);
void findValleys();
HistogramDirection getHistogramDirection(int index);
};
#endif // VERTICALHISTOGRAM_H
#endif // VERTICALHISTOGRAM_H

View File

@@ -689,4 +689,3 @@ inline void Arg::reset()
} //namespace TCLAP
#endif

View File

@@ -1,24 +1,24 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
/******************************************************************************
*
* file: ArgException.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_ARG_EXCEPTION_H
@@ -36,7 +36,7 @@ namespace TCLAP {
class ArgException : public std::exception
{
public:
/**
* Constructor.
* \param text - The text of the exception.
@@ -44,15 +44,15 @@ class ArgException : public std::exception
* \param td - Text describing the type of ArgException it is.
* of the exception.
*/
ArgException( const std::string& text = "undefined exception",
ArgException( const std::string& text = "undefined exception",
const std::string& id = "undefined",
const std::string& td = "Generic ArgException")
: std::exception(),
_errorText(text),
_argId( id ),
: std::exception(),
_errorText(text),
_argId( id ),
_typeDescription(td)
{ }
{ }
/**
* Destructor.
*/
@@ -66,20 +66,20 @@ class ArgException : public std::exception
/**
* Returns the argument id.
*/
std::string argId() const
{
std::string argId() const
{
if ( _argId == "undefined" )
return " ";
else
return ( "Argument: " + _argId );
return ( "Argument: " + _argId );
}
/**
* Returns the arg id and error text.
* Returns the arg id and error text.
*/
const char* what() const throw()
const char* what() const throw()
{
static std::string ex;
static std::string ex;
ex = _argId + " -- " + _errorText;
return ex.c_str();
}
@@ -90,7 +90,7 @@ class ArgException : public std::exception
*/
std::string typeDescription() const
{
return _typeDescription;
return _typeDescription;
}
@@ -119,19 +119,19 @@ class ArgException : public std::exception
* parse the argument it has been passed.
*/
class ArgParseException : public ArgException
{
{
public:
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source
* \param id - The text identifying the argument source
* of the exception.
*/
ArgParseException( const std::string& text = "undefined exception",
ArgParseException( const std::string& text = "undefined exception",
const std::string& id = "undefined" )
: ArgException( text,
id,
std::string( "Exception found while parsing " ) +
: ArgException( text,
id,
std::string( "Exception found while parsing " ) +
std::string( "the value the Arg has been passed." ))
{ }
};
@@ -146,12 +146,12 @@ class CmdLineParseException : public ArgException
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source
* \param id - The text identifying the argument source
* of the exception.
*/
CmdLineParseException( const std::string& text = "undefined exception",
CmdLineParseException( const std::string& text = "undefined exception",
const std::string& id = "undefined" )
: ArgException( text,
: ArgException( text,
id,
std::string( "Exception found when the values ") +
std::string( "on the command line do not meet ") +
@@ -161,7 +161,7 @@ class CmdLineParseException : public ArgException
};
/**
* Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
* Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
* same flag as another Arg, same name, etc.
*/
class SpecificationException : public ArgException
@@ -170,16 +170,16 @@ class SpecificationException : public ArgException
/**
* Constructor.
* \param text - The text of the exception.
* \param id - The text identifying the argument source
* \param id - The text identifying the argument source
* of the exception.
*/
SpecificationException( const std::string& text = "undefined exception",
const std::string& id = "undefined" )
: ArgException( text,
: ArgException( text,
id,
std::string("Exception found when an Arg object ")+
std::string("is improperly defined by the ") +
std::string("developer." ))
std::string("developer." ))
{ }
};
@@ -197,4 +197,3 @@ private:
} // namespace TCLAP
#endif

View File

@@ -452,7 +452,7 @@ inline void CmdLine::parse(std::vector<std::string>& args)
int requiredCount = 0;
for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
{
bool matched = false;
for (ArgListIterator it = _argList.begin();
@@ -619,7 +619,7 @@ inline void CmdLine::reset()
{
for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
(*it)->reset();
_progName.clear();
}

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: CmdLineInterface.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_COMMANDLINE_INTERFACE_H
#define TCLAP_COMMANDLINE_INTERFACE_H
@@ -31,7 +31,7 @@
namespace TCLAP {
class Arg;
class CmdLineOutput;
class XorHandler;
@@ -51,29 +51,29 @@ class CmdLineInterface
/**
* Adds an argument to the list of arguments to be parsed.
* \param a - Argument to be added.
* \param a - Argument to be added.
*/
virtual void add( Arg& a )=0;
/**
* An alternative add. Functionally identical.
* \param a - Argument to be added.
* \param a - Argument to be added.
*/
virtual void add( Arg* a )=0;
/**
* Add two Args that will be xor'd.
* Add two Args that will be xor'd.
* If this method is used, add does
* not need to be called.
* \param a - Argument to be added and xor'd.
* \param b - Argument to be added and xor'd.
* \param a - Argument to be added and xor'd.
* \param b - Argument to be added and xor'd.
*/
virtual void xorAdd( Arg& a, Arg& b )=0;
/**
* Add a list of Args that will be xor'd. If this method is used,
* Add a list of Args that will be xor'd. If this method is used,
* add does not need to be called.
* \param xors - List of Args to be added and xor'd.
* \param xors - List of Args to be added and xor'd.
*/
virtual void xorAdd( std::vector<Arg*>& xors )=0;
@@ -86,7 +86,7 @@ class CmdLineInterface
/**
* Parses the command line.
* \param args - A vector of strings representing the args.
* \param args - A vector of strings representing the args.
* args[0] is still the program name.
*/
void parse(std::vector<std::string>& args);
@@ -97,7 +97,7 @@ class CmdLineInterface
virtual CmdLineOutput* getOutput()=0;
/**
* \param co - CmdLineOutput object that we want to use instead.
* \param co - CmdLineOutput object that we want to use instead.
*/
virtual void setOutput(CmdLineOutput* co)=0;
@@ -112,12 +112,12 @@ class CmdLineInterface
virtual std::string& getProgramName()=0;
/**
* Returns the argList.
* Returns the argList.
*/
virtual std::list<Arg*>& getArgList()=0;
/**
* Returns the XorHandler.
* Returns the XorHandler.
*/
virtual XorHandler& getXorHandler()=0;
@@ -137,9 +137,9 @@ class CmdLineInterface
*/
virtual bool hasHelpAndVersion()=0;
/**
/**
* Resets the instance as if it had just been constructed so that the
* instance can be reused.
* instance can be reused.
*/
virtual void reset()=0;
};
@@ -147,4 +147,4 @@ class CmdLineInterface
} //namespace
#endif
#endif

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: CmdLineOutput.h
*
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_CMDLINEOUTPUT_H
#define TCLAP_CMDLINEOUTPUT_H
@@ -38,7 +38,7 @@ class ArgException;
/**
* The interface that any output object must implement.
*/
class CmdLineOutput
class CmdLineOutput
{
public:
@@ -49,26 +49,26 @@ class CmdLineOutput
virtual ~CmdLineOutput() {}
/**
* Generates some sort of output for the USAGE.
* \param c - The CmdLine object the output is generated for.
* Generates some sort of output for the USAGE.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c)=0;
/**
* Generates some sort of output for the version.
* \param c - The CmdLine object the output is generated for.
* Generates some sort of output for the version.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c)=0;
/**
* Generates some sort of output for a failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
* Generates some sort of output for a failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure( CmdLineInterface& c,
virtual void failure( CmdLineInterface& c,
ArgException& e )=0;
};
} //namespace TCLAP
#endif
#endif

View File

@@ -1,24 +1,24 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
/******************************************************************************
*
* file: DocBookOutput.h
*
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_DOCBOOKOUTPUT_H
#define TCLAP_DOCBOOKOUTPUT_H
@@ -37,7 +37,7 @@
namespace TCLAP {
/**
* A class that generates DocBook output for usage() method for the
* A class that generates DocBook output for usage() method for the
* given CmdLine and its Args.
*/
class DocBookOutput : public CmdLineOutput
@@ -46,35 +46,35 @@ class DocBookOutput : public CmdLineOutput
public:
/**
* Prints the usage to stdout. Can be overridden to
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
virtual void failure(CmdLineInterface& c,
ArgException& e );
protected:
/**
* Substitutes the char r for string x in string s.
* \param s - The string to operate on.
* \param r - The char to replace.
* \param x - What to replace r with.
* \param s - The string to operate on.
* \param r - The char to replace.
* \param x - What to replace r with.
*/
void substituteSpecialChars( std::string& s, char r, std::string& x );
void removeChar( std::string& s, char r);
@@ -87,12 +87,12 @@ class DocBookOutput : public CmdLineOutput
};
inline void DocBookOutput::version(CmdLineInterface& _cmd)
{
inline void DocBookOutput::version(CmdLineInterface& _cmd)
{
std::cout << _cmd.getVersion() << std::endl;
}
inline void DocBookOutput::usage(CmdLineInterface& _cmd )
inline void DocBookOutput::usage(CmdLineInterface& _cmd )
{
std::list<Arg*> argList = _cmd.getArgList();
std::string progName = _cmd.getProgramName();
@@ -127,13 +127,13 @@ inline void DocBookOutput::usage(CmdLineInterface& _cmd )
for ( int i = 0; (unsigned int)i < xorList.size(); i++ )
{
std::cout << "<group choice='req'>" << std::endl;
for ( ArgVectorIterator it = xorList[i].begin();
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end(); it++ )
printShortArg((*it));
std::cout << "</group>" << std::endl;
}
// rest of args
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
@@ -145,7 +145,7 @@ inline void DocBookOutput::usage(CmdLineInterface& _cmd )
std::cout << "<refsect1>" << std::endl;
std::cout << "<title>Description</title>" << std::endl;
std::cout << "<para>" << std::endl;
std::cout << _cmd.getMessage() << std::endl;
std::cout << _cmd.getMessage() << std::endl;
std::cout << "</para>" << std::endl;
std::cout << "</refsect1>" << std::endl;
@@ -153,7 +153,7 @@ inline void DocBookOutput::usage(CmdLineInterface& _cmd )
std::cout << "<title>Options</title>" << std::endl;
std::cout << "<variablelist>" << std::endl;
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
printLongArg((*it));
@@ -163,17 +163,17 @@ inline void DocBookOutput::usage(CmdLineInterface& _cmd )
std::cout << "<refsect1>" << std::endl;
std::cout << "<title>Version</title>" << std::endl;
std::cout << "<para>" << std::endl;
std::cout << xversion << std::endl;
std::cout << xversion << std::endl;
std::cout << "</para>" << std::endl;
std::cout << "</refsect1>" << std::endl;
std::cout << "</refentry>" << std::endl;
}
inline void DocBookOutput::failure( CmdLineInterface& _cmd,
ArgException& e )
{
ArgException& e )
{
static_cast<void>(_cmd); // unused
std::cout << e.what() << std::endl;
throw ExitException(1);
@@ -211,15 +211,15 @@ inline void DocBookOutput::basename( std::string& s )
inline void DocBookOutput::printShortArg(Arg* a)
{
std::string lt = "&lt;";
std::string gt = "&gt;";
std::string lt = "&lt;";
std::string gt = "&gt;";
std::string id = a->shortID();
substituteSpecialChars(id,'<',lt);
substituteSpecialChars(id,'>',gt);
removeChar(id,'[');
removeChar(id,']');
std::string choice = "opt";
if ( a->isRequired() )
choice = "plain";
@@ -251,8 +251,8 @@ inline void DocBookOutput::printShortArg(Arg* a)
inline void DocBookOutput::printLongArg(Arg* a)
{
std::string lt = "&lt;";
std::string gt = "&gt;";
std::string lt = "&lt;";
std::string gt = "&gt;";
std::string desc = a->getDescription();
substituteSpecialChars(desc,'<',lt);
@@ -296,4 +296,4 @@ inline void DocBookOutput::printLongArg(Arg* a)
}
} //namespace TCLAP
#endif
#endif

View File

@@ -1,23 +1,23 @@
/******************************************************************************
*
/******************************************************************************
*
* file: HelpVisitor.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_HELP_VISITOR_H
#define TCLAP_HELP_VISITOR_H
@@ -44,12 +44,12 @@ class HelpVisitor: public Visitor
protected:
/**
* The CmdLine the output will be generated for.
* The CmdLine the output will be generated for.
*/
CmdLineInterface* _cmd;
/**
* The output object.
* The output object.
*/
CmdLineOutput** _out;
@@ -58,17 +58,17 @@ class HelpVisitor: public Visitor
/**
* Constructor.
* \param cmd - The CmdLine the output will be generated for.
* \param out - The type of output.
* \param out - The type of output.
*/
HelpVisitor(CmdLineInterface* cmd, CmdLineOutput** out)
HelpVisitor(CmdLineInterface* cmd, CmdLineOutput** out)
: Visitor(), _cmd( cmd ), _out( out ) { }
/**
* Calls the usage method of the CmdLineOutput for the
* Calls the usage method of the CmdLineOutput for the
* specified CmdLine.
*/
void visit() { (*_out)->usage(*_cmd); throw ExitException(0); }
};
}

View File

@@ -1,23 +1,23 @@
/******************************************************************************
*
/******************************************************************************
*
* file: IgnoreRestVisitor.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_IGNORE_REST_VISITOR_H

View File

@@ -1,22 +1,22 @@
/******************************************************************************
*
/******************************************************************************
*
* file: MultiArg.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
@@ -39,7 +39,7 @@ template<class T>
class MultiArg : public Arg
{
public:
typedef std::vector<T> container_type;
typedef std::vector<T> container_type;
typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator;
@@ -56,7 +56,7 @@ protected:
std::string _typeDesc;
/**
* A list of constraint on this Arg.
* A list of constraint on this Arg.
*/
Constraint<T>* _constraint;
@@ -117,7 +117,7 @@ public:
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiArg( const std::string& flag,
MultiArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
@@ -146,7 +146,7 @@ public:
bool req,
Constraint<T>* constraint,
Visitor* v = NULL );
/**
* Constructor.
* \param flag - The one character flag that identifies this
@@ -163,14 +163,14 @@ public:
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiArg( const std::string& flag,
MultiArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
@@ -179,7 +179,7 @@ public:
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns a vector of type T containing the values parsed from
@@ -200,13 +200,13 @@ public:
const_iterator end() const { return _values.end(); }
/**
* Returns the a short id string. Used in the usage.
* Returns the a short id string. Used in the usage.
* \param val - value to be used.
*/
virtual std::string shortID(const std::string& val="val") const;
/**
* Returns the a long id string. Used in the usage.
* Returns the a long id string. Used in the usage.
* \param val - value to be used.
*/
virtual std::string longID(const std::string& val="val") const;
@@ -218,7 +218,7 @@ public:
virtual bool isRequired() const;
virtual bool allowMore();
virtual void reset();
private:
@@ -231,7 +231,7 @@ private:
};
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
@@ -242,12 +242,12 @@ MultiArg<T>::MultiArg(const std::string& flag,
_typeDesc( typeDesc ),
_constraint( NULL ),
_allowMore(false)
{
{
_acceptsMultipleValues = true;
}
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
@@ -259,7 +259,7 @@ MultiArg<T>::MultiArg(const std::string& flag,
_typeDesc( typeDesc ),
_constraint( NULL ),
_allowMore(false)
{
{
parser.add( this );
_acceptsMultipleValues = true;
}
@@ -268,7 +268,7 @@ MultiArg<T>::MultiArg(const std::string& flag,
*
*/
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
@@ -279,12 +279,12 @@ MultiArg<T>::MultiArg(const std::string& flag,
_typeDesc( constraint->shortID() ),
_constraint( constraint ),
_allowMore(false)
{
{
_acceptsMultipleValues = true;
}
template<class T>
MultiArg<T>::MultiArg(const std::string& flag,
MultiArg<T>::MultiArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
@@ -296,7 +296,7 @@ MultiArg<T>::MultiArg(const std::string& flag,
_typeDesc( constraint->shortID() ),
_constraint( constraint ),
_allowMore(false)
{
{
parser.add( this );
_acceptsMultipleValues = true;
}
@@ -305,7 +305,7 @@ template<class T>
const std::vector<T>& MultiArg<T>::getValue() { return _values; }
template<class T>
bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
@@ -321,7 +321,7 @@ bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
if ( argMatches( flag ) )
{
if ( Arg::delimiter() != ' ' && value == "" )
throw( ArgParseException(
throw( ArgParseException(
"Couldn't find delimiter for this argument!",
toString() ) );
@@ -334,15 +334,15 @@ bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
else
throw( ArgParseException("Missing a value for this argument!",
toString() ) );
}
}
else
_extractValue( value );
/*
// continuing taking the args until we hit one with a start string
// continuing taking the args until we hit one with a start string
while ( (unsigned int)(*i)+1 < args.size() &&
args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
_extractValue( args[++(*i)] );
*/
@@ -395,7 +395,7 @@ bool MultiArg<T>::isRequired() const
}
template<class T>
void MultiArg<T>::_extractValue( const std::string& val )
void MultiArg<T>::_extractValue( const std::string& val )
{
try {
T tmp;
@@ -409,10 +409,10 @@ void MultiArg<T>::_extractValue( const std::string& val )
if ( ! _constraint->check( _values.back() ) )
throw( CmdLineParseException( "Value '" + val +
"' does not meet constraint: " +
_constraint->description(),
_constraint->description(),
toString() ) );
}
template<class T>
bool MultiArg<T>::allowMore()
{

View File

@@ -1,5 +1,5 @@
/******************************************************************************
/******************************************************************************
*
* file: MultiSwitchArg.h
*
@@ -61,12 +61,12 @@ class MultiSwitchArg : public SwitchArg
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param init - Optional. The initial/default value of this Arg.
* \param init - Optional. The initial/default value of this Arg.
* Defaults to 0.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiSwitchArg(const std::string& flag,
MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
int init = 0,
@@ -82,12 +82,12 @@ class MultiSwitchArg : public SwitchArg
* \param desc - A description of what the argument is for or
* does.
* \param parser - A CmdLine parser object to add this Arg to
* \param init - Optional. The initial/default value of this Arg.
* \param init - Optional. The initial/default value of this Arg.
* Defaults to 0.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
MultiSwitchArg(const std::string& flag,
MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
@@ -103,7 +103,7 @@ class MultiSwitchArg : public SwitchArg
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns int, the number of times the switch has been set.
@@ -119,7 +119,7 @@ class MultiSwitchArg : public SwitchArg
* Returns the longID for this Arg.
*/
std::string longID(const std::string& val) const;
void reset();
};
@@ -138,15 +138,15 @@ _default( init )
{ }
inline MultiSwitchArg::MultiSwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
int init,
Visitor* v )
: SwitchArg(flag, name, desc, false, v),
_value( init ),
_default( init )
{
{
parser.add( this );
}
@@ -178,7 +178,7 @@ inline bool MultiSwitchArg::processArg(int *i, std::vector<std::string>& args)
++_value;
// Check for more in argument and increment value.
while ( combinedSwitchesMatch( args[*i] ) )
while ( combinedSwitchesMatch( args[*i] ) )
++_value;
_checkWithVisitor();
@@ -189,13 +189,13 @@ inline bool MultiSwitchArg::processArg(int *i, std::vector<std::string>& args)
return false;
}
inline std::string
inline std::string
MultiSwitchArg::shortID(const std::string& val) const
{
return Arg::shortID(val) + " ... ";
}
inline std::string
inline std::string
MultiSwitchArg::longID(const std::string& val) const
{
return Arg::longID(val) + " (accepted multiple times)";

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: OptionalUnlabeledTracker.h
*
*
* Copyright (c) 2005, Michael E. Smoot .
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_OPTIONAL_UNLABELED_TRACKER_H
@@ -37,7 +37,7 @@ class OptionalUnlabeledTracker
static void gotOptional() { alreadyOptionalRef() = true; }
static bool& alreadyOptional() { return alreadyOptionalRef(); }
static bool& alreadyOptional() { return alreadyOptionalRef(); }
private:

View File

@@ -30,7 +30,7 @@
#include <config.h> // To check for long long
#endif
// If Microsoft has already typedef'd wchar_t as an unsigned
// If Microsoft has already typedef'd wchar_t as an unsigned
// short, then compiles will break because it's as if we're
// creating ArgTraits twice for unsigned short. Thus...
#ifdef _MSC_VER
@@ -123,7 +123,7 @@ struct ArgTraits<unsigned char> {
typedef ValueLike ValueCategory;
};
// Microsoft implements size_t awkwardly.
// Microsoft implements size_t awkwardly.
#if defined(_MSC_VER) && defined(_M_X64)
/**
* size_ts have value-like semantics.
@@ -205,4 +205,3 @@ void SetString(T &dst, const std::string &src)
} // namespace
#endif

View File

@@ -1,24 +1,24 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
/******************************************************************************
*
* file: StdOutput.h
*
*
* Copyright (c) 2004, Michael E. Smoot
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_STDCMDLINEOUTPUT_H
#define TCLAP_STDCMDLINEOUTPUT_H
@@ -46,77 +46,77 @@ class StdOutput : public CmdLineOutput
public:
/**
* Prints the usage to stdout. Can be overridden to
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
virtual void failure(CmdLineInterface& c,
ArgException& e );
protected:
/**
* Writes a brief usage message with short args.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
* \param os - The stream to write the message to.
*/
void _shortUsage( CmdLineInterface& c, std::ostream& os ) const;
/**
* Writes a longer usage message with long and short args,
* Writes a longer usage message with long and short args,
* provides descriptions and prints message.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
* \param os - The stream to write the message to.
*/
void _longUsage( CmdLineInterface& c, std::ostream& os ) const;
/**
* This function inserts line breaks and indents long strings
* according the params input. It will only break lines at spaces,
* This function inserts line breaks and indents long strings
* according the params input. It will only break lines at spaces,
* commas and pipes.
* \param os - The stream to be printed to.
* \param s - The string to be printed.
* \param maxWidth - The maxWidth allowed for the output line.
* \param indentSpaces - The number of spaces to indent the first line.
* \param maxWidth - The maxWidth allowed for the output line.
* \param indentSpaces - The number of spaces to indent the first line.
* \param secondLineOffset - The number of spaces to indent the second
* and all subsequent lines in addition to indentSpaces.
*/
void spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
void spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
int secondLineOffset ) const;
};
inline void StdOutput::version(CmdLineInterface& _cmd)
inline void StdOutput::version(CmdLineInterface& _cmd)
{
std::string progName = _cmd.getProgramName();
std::string xversion = _cmd.getVersion();
std::cout << std::endl << progName << " version: "
std::cout << std::endl << progName << " version: "
<< xversion << std::endl << std::endl;
}
inline void StdOutput::usage(CmdLineInterface& _cmd )
inline void StdOutput::usage(CmdLineInterface& _cmd )
{
std::cout << std::endl << "USAGE: " << std::endl << std::endl;
std::cout << std::endl << "USAGE: " << std::endl << std::endl;
_shortUsage( _cmd, std::cout );
@@ -124,12 +124,12 @@ inline void StdOutput::usage(CmdLineInterface& _cmd )
_longUsage( _cmd, std::cout );
std::cout << std::endl;
std::cout << std::endl;
}
inline void StdOutput::failure( CmdLineInterface& _cmd,
ArgException& e )
ArgException& e )
{
std::string progName = _cmd.getProgramName();
@@ -140,10 +140,10 @@ inline void StdOutput::failure( CmdLineInterface& _cmd,
{
std::cerr << "Brief USAGE: " << std::endl;
_shortUsage( _cmd, std::cerr );
_shortUsage( _cmd, std::cerr );
std::cerr << std::endl << "For complete USAGE and HELP type: "
<< std::endl << " " << progName << " --help"
std::cerr << std::endl << "For complete USAGE and HELP type: "
<< std::endl << " " << progName << " --help"
<< std::endl << std::endl;
}
else
@@ -152,8 +152,8 @@ inline void StdOutput::failure( CmdLineInterface& _cmd,
throw ExitException(1);
}
inline void
StdOutput::_shortUsage( CmdLineInterface& _cmd,
inline void
StdOutput::_shortUsage( CmdLineInterface& _cmd,
std::ostream& os ) const
{
std::list<Arg*> argList = _cmd.getArgList();
@@ -167,7 +167,7 @@ StdOutput::_shortUsage( CmdLineInterface& _cmd,
for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
{
s += " {";
for ( ArgVectorIterator it = xorList[i].begin();
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end(); it++ )
s += (*it)->shortID() + "|";
@@ -179,7 +179,7 @@ StdOutput::_shortUsage( CmdLineInterface& _cmd,
if ( !xorHandler.contains( (*it) ) )
s += " " + (*it)->shortID();
// if the program name is too long, then adjust the second line offset
// if the program name is too long, then adjust the second line offset
int secondLineOffset = static_cast<int>(progName.length()) + 2;
if ( secondLineOffset > 75/2 )
secondLineOffset = static_cast<int>(75/2);
@@ -187,8 +187,8 @@ StdOutput::_shortUsage( CmdLineInterface& _cmd,
spacePrint( os, s, 75, 3, secondLineOffset );
}
inline void
StdOutput::_longUsage( CmdLineInterface& _cmd,
inline void
StdOutput::_longUsage( CmdLineInterface& _cmd,
std::ostream& os ) const
{
std::list<Arg*> argList = _cmd.getArgList();
@@ -196,11 +196,11 @@ StdOutput::_longUsage( CmdLineInterface& _cmd,
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
// first the xor
// first the xor
for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
{
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end();
for ( ArgVectorIterator it = xorList[i].begin();
it != xorList[i].end();
it++ )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
@@ -216,8 +216,8 @@ StdOutput::_longUsage( CmdLineInterface& _cmd,
for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
if ( !xorHandler.contains( (*it) ) )
{
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
spacePrint( os, (*it)->longID(), 75, 3, 3 );
spacePrint( os, (*it)->getDescription(), 75, 5, 0 );
os << std::endl;
}
@@ -226,10 +226,10 @@ StdOutput::_longUsage( CmdLineInterface& _cmd,
spacePrint( os, message, 75, 3, 0 );
}
inline void StdOutput::spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
inline void StdOutput::spacePrint( std::ostream& os,
const std::string& s,
int maxWidth,
int indentSpaces,
int secondLineOffset ) const
{
int len = static_cast<int>(s.length());
@@ -242,19 +242,19 @@ inline void StdOutput::spacePrint( std::ostream& os,
{
// find the substring length
// int stringLen = std::min<int>( len - start, allowedLen );
// doing it this way to support a VisualC++ 2005 bug
using namespace std;
// doing it this way to support a VisualC++ 2005 bug
using namespace std;
int stringLen = min<int>( len - start, allowedLen );
// trim the length so it doesn't end in middle of a word
if ( stringLen == allowedLen )
while ( stringLen >= 0 &&
s[stringLen+start] != ' ' &&
s[stringLen+start] != ' ' &&
s[stringLen+start] != ',' &&
s[stringLen+start] != '|' )
s[stringLen+start] != '|' )
stringLen--;
// ok, the word is longer than the line, so just split
// ok, the word is longer than the line, so just split
// wherever the line ends
if ( stringLen <= 0 )
stringLen = allowedLen;
@@ -264,7 +264,7 @@ inline void StdOutput::spacePrint( std::ostream& os,
if ( s[start+i] == '\n' )
stringLen = i+1;
// print the indent
// print the indent
for ( int i = 0; i < indentSpaces; i++ )
os << " ";
@@ -282,7 +282,7 @@ inline void StdOutput::spacePrint( std::ostream& os,
// so we don't start a line with a space
while ( s[stringLen+start] == ' ' && start < len )
start++;
start += stringLen;
}
}
@@ -295,4 +295,4 @@ inline void StdOutput::spacePrint( std::ostream& os,
}
} //namespace TCLAP
#endif
#endif

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: SwitchArg.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_SWITCH_ARG_H
@@ -61,17 +61,17 @@ class SwitchArg : public Arg
* used as a long flag on the command line.
* \param desc - A description of what the argument is for or
* does.
* \param def - The default value for this Switch.
* \param def - The default value for this Switch.
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
SwitchArg(const std::string& flag,
const std::string& name,
SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool def = false,
Visitor* v = NULL);
/**
* SwitchArg constructor.
* \param flag - The one character flag that identifies this
@@ -85,14 +85,14 @@ class SwitchArg : public Arg
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
SwitchArg(const std::string& flag,
const std::string& name,
SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
bool def = false,
Visitor* v = NULL);
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
@@ -101,7 +101,7 @@ class SwitchArg : public Arg
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Checks a string to see if any of the chars in the string
@@ -113,7 +113,7 @@ class SwitchArg : public Arg
* Returns bool, whether or not the switch has been set.
*/
bool getValue();
virtual void reset();
private:
@@ -132,9 +132,9 @@ class SwitchArg : public Arg
//////////////////////////////////////////////////////////////////////
//BEGIN SwitchArg.cpp
//////////////////////////////////////////////////////////////////////
inline SwitchArg::SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
inline SwitchArg::SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool default_val,
Visitor* v )
: Arg(flag, name, desc, false, false, v),
@@ -142,27 +142,27 @@ inline SwitchArg::SwitchArg(const std::string& flag,
_default( default_val )
{ }
inline SwitchArg::SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
inline SwitchArg::SwitchArg(const std::string& flag,
const std::string& name,
const std::string& desc,
CmdLineInterface& parser,
bool default_val,
Visitor* v )
: Arg(flag, name, desc, false, false, v),
_value( default_val ),
_default(default_val)
{
{
parser.add( this );
}
inline bool SwitchArg::getValue() { return _value; }
inline bool SwitchArg::lastCombined(std::string& combinedSwitches )
inline bool SwitchArg::lastCombined(std::string& combinedSwitches )
{
for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
if ( combinedSwitches[i] != Arg::blankChar() )
return false;
return true;
}
@@ -173,32 +173,32 @@ inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
combinedSwitches[0] != Arg::flagStartString()[0] )
return false;
// make sure it isn't a long name
if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
// make sure it isn't a long name
if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
Arg::nameStartString() )
return false;
// make sure the delimiter isn't in the string
// make sure the delimiter isn't in the string
if ( combinedSwitches.find_first_of( Arg::delimiter() ) != std::string::npos )
return false;
// ok, we're not specifying a ValueArg, so we know that we have
// a combined switch list.
// a combined switch list.
for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
if ( _flag.length() > 0 &&
if ( _flag.length() > 0 &&
combinedSwitches[i] == _flag[0] &&
_flag[0] != Arg::flagStartString()[0] )
_flag[0] != Arg::flagStartString()[0] )
{
// update the combined switches so this one is no longer present
// this is necessary so that no unlabeled args are matched
// later in the processing.
//combinedSwitches.erase(i,1);
combinedSwitches[i] = Arg::blankChar();
combinedSwitches[i] = Arg::blankChar();
return true;
}
// none of the switches passed in the list match.
return false;
// none of the switches passed in the list match.
return false;
}
inline void SwitchArg::commonProcessing()
@@ -207,7 +207,7 @@ inline void SwitchArg::commonProcessing()
throw(CmdLineParseException(
"Mutually exclusive argument already set!", toString()));
if ( _alreadySet )
if ( _alreadySet )
throw(CmdLineParseException("Argument already set!", toString()));
_alreadySet = true;
@@ -235,16 +235,16 @@ inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
// if a substring matches the flag as part of a combination
else if ( combinedSwitchesMatch( args[*i] ) )
{
// check again to ensure we don't misinterpret
// this as a MultiSwitchArg
// check again to ensure we don't misinterpret
// this as a MultiSwitchArg
if ( combinedSwitchesMatch( args[*i] ) )
throw(CmdLineParseException("Argument already set!",
throw(CmdLineParseException("Argument already set!",
toString()));
commonProcessing();
// We only want to return true if we've found the last combined
// match in the string, otherwise we return true so that other
// match in the string, otherwise we return true so that other
// switches in the combination will have a chance to match.
return lastCombined( args[*i] );
}
@@ -255,7 +255,7 @@ inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
inline void SwitchArg::reset()
{
Arg::reset();
_value = _default;
_value = _default;
}
//////////////////////////////////////////////////////////////////////
//End SwitchArg.cpp

View File

@@ -1,23 +1,23 @@
/******************************************************************************
*
/******************************************************************************
*
* file: UnlabeledMultiArg.h
*
*
* Copyright (c) 2003, Michael E. Smoot.
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H
@@ -33,7 +33,7 @@ namespace TCLAP {
/**
* Just like a MultiArg, except that the arguments are unlabeled. Basically,
* this Arg will slurp up everything that hasn't been matched to another
* this Arg will slurp up everything that hasn't been matched to another
* Arg.
*/
template<class T>
@@ -52,9 +52,9 @@ class UnlabeledMultiArg : public MultiArg<T>
using MultiArg<T>::toString;
public:
/**
* Constructor.
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
@@ -77,7 +77,7 @@ class UnlabeledMultiArg : public MultiArg<T>
bool ignoreable = false,
Visitor* v = NULL );
/**
* Constructor.
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
@@ -101,9 +101,9 @@ class UnlabeledMultiArg : public MultiArg<T>
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL );
/**
* Constructor.
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
@@ -125,7 +125,7 @@ class UnlabeledMultiArg : public MultiArg<T>
Visitor* v = NULL );
/**
* Constructor.
* Constructor.
* \param name - The name of the Arg. Note that this is used for
* identification, not as a long flag.
* \param desc - A description of what the argument is for or
@@ -140,14 +140,14 @@ class UnlabeledMultiArg : public MultiArg<T>
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
UnlabeledMultiArg( const std::string& name,
const std::string& desc,
UnlabeledMultiArg( const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL );
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
@@ -156,7 +156,7 @@ class UnlabeledMultiArg : public MultiArg<T>
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns the a short id string. Used in the usage.
@@ -184,28 +184,28 @@ class UnlabeledMultiArg : public MultiArg<T>
};
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, typeDesc, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
}
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
const std::string& typeDesc,
CmdLineInterface& parser,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, typeDesc, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
parser.add( this );
@@ -213,28 +213,28 @@ UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, constraint, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
}
template<class T>
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
const std::string& desc,
bool req,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable,
Visitor* v)
: MultiArg<T>("", name, desc, req, constraint, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(true, toString());
parser.add( this );
@@ -242,7 +242,7 @@ UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
template<class T>
bool UnlabeledMultiArg<T>::processArg(int *i, std::vector<std::string>& args)
bool UnlabeledMultiArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _hasBlanks( args[*i] ) )
@@ -251,14 +251,14 @@ bool UnlabeledMultiArg<T>::processArg(int *i, std::vector<std::string>& args)
// never ignore an unlabeled multi arg
// always take the first value, regardless of the start string
// always take the first value, regardless of the start string
_extractValue( args[(*i)] );
/*
// continue taking args until we hit the end or a start string
// continue taking args until we hit the end or a start string
while ( (unsigned int)(*i)+1 < args.size() &&
args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
_extractValue( args[++(*i)] );
*/

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: UnlabeledValueArg.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_UNLABELED_VALUE_ARGUMENT_H
@@ -72,18 +72,18 @@ class UnlabeledValueArg : public ValueArg<T>
* of the program.
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
bool ignoreable = false,
Visitor* v = NULL);
Visitor* v = NULL);
/**
* UnlabeledValueArg constructor.
@@ -102,20 +102,20 @@ class UnlabeledValueArg : public ValueArg<T>
* \param parser - A CmdLine parser object to add this Arg to
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL );
Visitor* v = NULL );
/**
* UnlabeledValueArg constructor.
* \param name - A one word name for the argument. Note that this is used for
@@ -130,20 +130,20 @@ class UnlabeledValueArg : public ValueArg<T>
* to constrain this Arg.
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
bool ignoreable = false,
Visitor* v = NULL );
Visitor* v = NULL );
/**
* UnlabeledValueArg constructor.
* \param name - A one word name for the argument. Note that this is used for
@@ -159,29 +159,29 @@ class UnlabeledValueArg : public ValueArg<T>
* \param parser - A CmdLine parser object to add this Arg to
* \param ignoreable - Allows you to specify that this argument can be
* ignored if the '--' flag is set. This defaults to false (cannot
* be ignored) and should generally stay that way unless you have
* be ignored) and should generally stay that way unless you have
* some special need for certain arguments to be ignored.
* \param v - Optional Vistor. You should leave this blank unless
* you have a very good reason.
*/
UnlabeledValueArg( const std::string& name,
const std::string& desc,
UnlabeledValueArg( const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
CmdLineInterface& parser,
bool ignoreable = false,
Visitor* v = NULL);
/**
* Handles the processing of the argument.
* This re-implements the Arg version of this method to set the
* _value of the argument appropriately. Handling specific to
* unlabled arguments.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings.
* \param args - Mutable list of strings.
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Overrides shortID for specific behavior.
@@ -210,15 +210,15 @@ class UnlabeledValueArg : public ValueArg<T>
* Constructor implemenation.
*/
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, typeDesc, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
@@ -226,8 +226,8 @@ UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
}
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
@@ -235,7 +235,7 @@ UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, typeDesc, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
parser.add( this );
@@ -245,22 +245,22 @@ UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
* Constructor implemenation.
*/
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, constraint, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
}
template<class T>
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
@@ -268,7 +268,7 @@ UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
bool ignoreable,
Visitor* v)
: ValueArg<T>("", name, desc, req, val, constraint, v)
{
{
_ignoreable = ignoreable;
OptionalUnlabeledTracker::check(req, toString());
parser.add( this );
@@ -278,17 +278,17 @@ UnlabeledValueArg<T>::UnlabeledValueArg(const std::string& name,
* Implementation of processArg().
*/
template<class T>
bool UnlabeledValueArg<T>::processArg(int *i, std::vector<std::string>& args)
bool UnlabeledValueArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _alreadySet )
return false;
if ( _hasBlanks( args[*i] ) )
return false;
// never ignore an unlabeled arg
_extractValue( args[*i] );
_alreadySet = true;
return true;
@@ -313,8 +313,8 @@ std::string UnlabeledValueArg<T>::longID(const std::string& val) const
static_cast<void>(val); // Ignore input, don't warn
// Ideally we would like to be able to use RTTI to return the name
// of the type required for this argument. However, g++ at least,
// doesn't appear to return terribly useful "names" of the types.
// of the type required for this argument. However, g++ at least,
// doesn't appear to return terribly useful "names" of the types.
return std::string("<") + _typeDesc + ">";
}

View File

@@ -1,23 +1,23 @@
/******************************************************************************
*
/******************************************************************************
*
* file: ValueArg.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VALUE_ARGUMENT_H
@@ -40,7 +40,7 @@ namespace TCLAP {
* Instead use an UnlabeledValueArg.
*/
template<class T>
class ValueArg : public Arg
class ValueArg : public Arg
{
protected:
@@ -67,7 +67,7 @@ class ValueArg : public Arg
std::string _typeDesc;
/**
* A Constraint this Arg must conform to.
* A Constraint this Arg must conform to.
*/
Constraint<T>* _constraint;
@@ -75,7 +75,7 @@ class ValueArg : public Arg
* Extracts the value from the string.
* Attempts to parse string as type T, if this fails an exception
* is thrown.
* \param val - value to be parsed.
* \param val - value to be parsed.
*/
void _extractValue( const std::string& val );
@@ -83,9 +83,9 @@ class ValueArg : public Arg
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
@@ -104,20 +104,20 @@ class ValueArg : public Arg
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
Visitor* v = NULL);
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
@@ -137,20 +137,20 @@ class ValueArg : public Arg
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
const std::string& typeDesc,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
@@ -168,20 +168,20 @@ class ValueArg : public Arg
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
CmdLineInterface& parser,
Visitor* v = NULL );
/**
* Labeled ValueArg constructor.
* You could conceivably call this constructor with a blank flag,
* You could conceivably call this constructor with a blank flag,
* but that would make you a bad person. It would also cause
* an exception to be thrown. If you want an unlabeled argument,
* an exception to be thrown. If you want an unlabeled argument,
* use the other constructor.
* \param flag - The one character flag that identifies this
* argument on the command line.
@@ -198,10 +198,10 @@ class ValueArg : public Arg
* \param v - An optional visitor. You probably should not
* use this unless you have a very good reason.
*/
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg( const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T value,
Constraint<T>* constraint,
Visitor* v = NULL );
@@ -212,10 +212,10 @@ class ValueArg : public Arg
* _value of the argument appropriately. It knows the difference
* between labeled and unlabeled.
* \param i - Pointer the the current argument in the list.
* \param args - Mutable list of strings. Passed
* \param args - Mutable list of strings. Passed
* in from main().
*/
virtual bool processArg(int* i, std::vector<std::string>& args);
virtual bool processArg(int* i, std::vector<std::string>& args);
/**
* Returns the value of the argument.
@@ -233,7 +233,7 @@ class ValueArg : public Arg
* \param val - value to be used.
*/
virtual std::string longID(const std::string& val = "val") const;
virtual void reset() ;
private:
@@ -249,10 +249,10 @@ private:
* Constructor implementation.
*/
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
Visitor* v)
@@ -264,10 +264,10 @@ ValueArg<T>::ValueArg(const std::string& flag,
{ }
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
const std::string& typeDesc,
CmdLineInterface& parser,
@@ -277,15 +277,15 @@ ValueArg<T>::ValueArg(const std::string& flag,
_default( val ),
_typeDesc( typeDesc ),
_constraint( NULL )
{
{
parser.add( this );
}
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
Visitor* v)
@@ -297,10 +297,10 @@ ValueArg<T>::ValueArg(const std::string& flag,
{ }
template<class T>
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
ValueArg<T>::ValueArg(const std::string& flag,
const std::string& name,
const std::string& desc,
bool req,
T val,
Constraint<T>* constraint,
CmdLineInterface& parser,
@@ -310,7 +310,7 @@ ValueArg<T>::ValueArg(const std::string& flag,
_default( val ),
_typeDesc( constraint->shortID() ),
_constraint( constraint )
{
{
parser.add( this );
}
@@ -344,22 +344,22 @@ bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
{
if ( _xorSet )
throw( CmdLineParseException(
"Mutually exclusive argument already set!",
"Mutually exclusive argument already set!",
toString()) );
else
throw( CmdLineParseException("Argument already set!",
throw( CmdLineParseException("Argument already set!",
toString()) );
}
if ( Arg::delimiter() != ' ' && value == "" )
throw( ArgParseException(
throw( ArgParseException(
"Couldn't find delimiter for this argument!",
toString() ) );
if ( value == "" )
{
(*i)++;
if ( static_cast<unsigned int>(*i) < args.size() )
if ( static_cast<unsigned int>(*i) < args.size() )
_extractValue( args[*i] );
else
throw( ArgParseException("Missing a value for this argument!",
@@ -367,11 +367,11 @@ bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
}
else
_extractValue( value );
_alreadySet = true;
_checkWithVisitor();
return true;
}
}
else
return false;
}
@@ -383,7 +383,7 @@ template<class T>
std::string ValueArg<T>::shortID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return Arg::shortID( _typeDesc );
return Arg::shortID( _typeDesc );
}
/**
@@ -393,22 +393,22 @@ template<class T>
std::string ValueArg<T>::longID(const std::string& val) const
{
static_cast<void>(val); // Ignore input, don't warn
return Arg::longID( _typeDesc );
return Arg::longID( _typeDesc );
}
template<class T>
void ValueArg<T>::_extractValue( const std::string& val )
void ValueArg<T>::_extractValue( const std::string& val )
{
try {
ExtractValue(_value, val, typename ArgTraits<T>::ValueCategory());
} catch( ArgParseException &e) {
throw ArgParseException(e.error(), toString());
}
if ( _constraint != NULL )
if ( ! _constraint->check( _value ) )
throw( CmdLineParseException( "Value '" + val +
+ "' does not meet constraint: "
throw( CmdLineParseException( "Value '" + val +
+ "' does not meet constraint: "
+ _constraint->description(),
toString() ) );
}

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: ValuesConstraint.h
*
*
* Copyright (c) 2005, Michael E. Smoot
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VALUESCONSTRAINT_H
#define TCLAP_VALUESCONSTRAINT_H
@@ -54,10 +54,10 @@ class ValuesConstraint : public Constraint<T>
public:
/**
* Constructor.
* \param allowed - vector of allowed values.
* Constructor.
* \param allowed - vector of allowed values.
*/
ValuesConstraint(std::vector<T>& allowed);
ValuesConstraint(std::vector<T>& allowed);
/**
* Virtual destructor.
@@ -65,7 +65,7 @@ class ValuesConstraint : public Constraint<T>
virtual ~ValuesConstraint() {}
/**
* Returns a description of the Constraint.
* Returns a description of the Constraint.
*/
virtual std::string description() const;
@@ -77,14 +77,14 @@ class ValuesConstraint : public Constraint<T>
/**
* The method used to verify that the value parsed from the command
* line meets the constraint.
* \param value - The value that will be checked.
* \param value - The value that will be checked.
*/
virtual bool check(const T& value) const;
protected:
/**
* The list of valid values.
* The list of valid values.
*/
std::vector<T> _allowed;
@@ -99,7 +99,7 @@ template<class T>
ValuesConstraint<T>::ValuesConstraint(std::vector<T>& allowed)
: _allowed(allowed),
_typeDesc("")
{
{
for ( unsigned int i = 0; i < _allowed.size(); i++ )
{
@@ -113,7 +113,7 @@ ValuesConstraint<T>::ValuesConstraint(std::vector<T>& allowed)
os << _allowed[i];
std::string temp( os.str() );
std::string temp( os.str() );
if ( i > 0 )
_typeDesc += "|";
@@ -126,23 +126,22 @@ bool ValuesConstraint<T>::check( const T& val ) const
{
if ( std::find(_allowed.begin(),_allowed.end(),val) == _allowed.end() )
return false;
else
else
return true;
}
template<class T>
std::string ValuesConstraint<T>::shortID() const
{
return _typeDesc;
return _typeDesc;
}
template<class T>
std::string ValuesConstraint<T>::description() const
{
return _typeDesc;
return _typeDesc;
}
} //namespace TCLAP
#endif
#endif

View File

@@ -1,24 +1,24 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
/******************************************************************************
*
* file: VersionVisitor.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VERSION_VISITOR_H
@@ -51,7 +51,7 @@ class VersionVisitor: public Visitor
CmdLineInterface* _cmd;
/**
* The output object.
* The output object.
*/
CmdLineOutput** _out;
@@ -59,19 +59,19 @@ class VersionVisitor: public Visitor
/**
* Constructor.
* \param cmd - The CmdLine the output is generated for.
* \param out - The type of output.
* \param cmd - The CmdLine the output is generated for.
* \param out - The type of output.
*/
VersionVisitor( CmdLineInterface* cmd, CmdLineOutput** out )
VersionVisitor( CmdLineInterface* cmd, CmdLineOutput** out )
: Visitor(), _cmd( cmd ), _out( out ) { }
/**
* Calls the version method of the output object using the
* specified CmdLine.
*/
void visit() {
(*_out)->version(*_cmd);
throw ExitException(0);
void visit() {
(*_out)->version(*_cmd);
throw ExitException(0);
}
};

View File

@@ -1,23 +1,23 @@
/******************************************************************************
*
/******************************************************************************
*
* file: Visitor.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_VISITOR_H

View File

@@ -1,24 +1,24 @@
/******************************************************************************
*
/******************************************************************************
*
* file: XorHandler.h
*
*
* Copyright (c) 2003, Michael E. Smoot .
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TCLAP_XORHANDLER_H
#define TCLAP_XORHANDLER_H
@@ -56,12 +56,12 @@ class XorHandler
* \param ors - list of Arg* that will be xor'd.
*/
void add( std::vector<Arg*>& ors );
/**
* Checks whether the specified Arg is in one of the xor lists and
* if it does match one, returns the size of the xor list that the
* Arg matched. If the Arg matches, then it also sets the rest of
* the Arg's in the list. You shouldn't use this.
* the Arg's in the list. You shouldn't use this.
* \param a - The Arg to be checked.
*/
int check( const Arg* a );
@@ -84,7 +84,7 @@ class XorHandler
*/
bool contains( const Arg* a );
std::vector< std::vector<Arg*> >& getXorList();
std::vector< std::vector<Arg*> >& getXorList();
};
@@ -93,24 +93,24 @@ class XorHandler
//BEGIN XOR.cpp
//////////////////////////////////////////////////////////////////////
inline void XorHandler::add( std::vector<Arg*>& ors )
{
{
_orList.push_back( ors );
}
inline int XorHandler::check( const Arg* a )
inline int XorHandler::check( const Arg* a )
{
// iterate over each XOR list
for ( int i = 0; static_cast<unsigned int>(i) < _orList.size(); i++ )
{
// if the XOR list contains the arg..
ArgVectorIterator ait = std::find( _orList[i].begin(),
ArgVectorIterator ait = std::find( _orList[i].begin(),
_orList[i].end(), a );
if ( ait != _orList[i].end() )
{
// first check to see if a mutually exclusive switch
// has not already been set
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a != (*it) && (*it)->isSet() )
throw(CmdLineParseException(
@@ -118,8 +118,8 @@ inline int XorHandler::check( const Arg* a )
(*it)->toString()));
// go through and set each arg that is not a
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a != (*it) )
(*it)->xorSet();
@@ -141,16 +141,16 @@ inline int XorHandler::check( const Arg* a )
inline bool XorHandler::contains( const Arg* a )
{
for ( int i = 0; static_cast<unsigned int>(i) < _orList.size(); i++ )
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a == (*it) )
return true;
return false;
}
inline std::vector< std::vector<Arg*> >& XorHandler::getXorList()
inline std::vector< std::vector<Arg*> >& XorHandler::getXorList()
{
return _orList;
}
@@ -163,4 +163,4 @@ inline std::vector< std::vector<Arg*> >& XorHandler::getXorList()
} //namespace TCLAP
#endif
#endif

View File

@@ -1,24 +1,24 @@
// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
/******************************************************************************
*
/******************************************************************************
*
* file: ZshCompletionOutput.h
*
*
* Copyright (c) 2006, Oliver Kiddle
* All rights reverved.
*
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
*
*****************************************************************************/
#ifndef TCLAP_ZSHCOMPLETIONOUTPUT_H
#define TCLAP_ZSHCOMPLETIONOUTPUT_H
@@ -48,24 +48,24 @@ class ZshCompletionOutput : public CmdLineOutput
ZshCompletionOutput();
/**
* Prints the usage to stdout. Can be overridden to
* Prints the usage to stdout. Can be overridden to
* produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
*/
virtual void usage(CmdLineInterface& c);
/**
* Prints the version to stdout. Can be overridden
* Prints the version to stdout. Can be overridden
* to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param c - The CmdLine object the output is generated for.
*/
virtual void version(CmdLineInterface& c);
/**
* Prints (to stderr) an error message, short usage
* Prints (to stderr) an error message, short usage
* Can be overridden to produce alternative behavior.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
* \param c - The CmdLine object the output is generated for.
* \param e - The ArgException that caused the failure.
*/
virtual void failure(CmdLineInterface& c,
ArgException& e );
@@ -272,7 +272,7 @@ inline std::string ZshCompletionOutput::getMutexList( CmdLineInterface& _cmd, Ar
{
XorHandler xorHandler = _cmd.getXorHandler();
std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
if (a->getName() == "help" || a->getName() == "version")
{
return "(-)";
@@ -309,13 +309,13 @@ inline std::string ZshCompletionOutput::getMutexList( CmdLineInterface& _cmd, Ar
return list.str();
}
}
// wasn't found in xor list
if (!a->getFlag().empty()) {
list << "(" << a->flagStartChar() << a->getFlag() << ' ' <<
a->nameStartString() << a->getName() << ')';
}
return list.str();
}