diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..06628d5 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,56 @@ +project(src) + + +cmake_minimum_required (VERSION 2.6) + +IF (WIN32) + add_definitions( -DWINDOWS) + add_definitions( -DNOMINMAX) + + SET(OpenCV_DIR "C:\\projects\\alpr\\libraries\\opencv") + SET(Tesseract_DIR "C:\\projects\\alpr\\libraries\\tesseract-3.02") + + include_directories( + ${Tesseract_DIR}/include/tesseract + + ) + link_directories( ${Tesseract_DIR}/lib/ ) +ELSE() + + SET(OpenCV_DIR "../libraries/opencv/") + SET(Tesseract_DIR "/home/mhill/projects/alpr/libraries/tesseract-ocr") + + include_directories( + ${Tesseract_DIR}/api + ${Tesseract_DIR}/ccutil/ + ${Tesseract_DIR}/ccstruct/ + ${Tesseract_DIR}/ccmain/ + + ) + link_directories( ${Tesseract_DIR}/api/.libs/ ) +ENDIF() + + +# Opencv Package +FIND_PACKAGE( OpenCV REQUIRED ) +IF (${OpenCV_VERSION} VERSION_LESS 2.3.0) + MESSAGE(FATAL_ERROR "OpenCV version is not compatible : ${OpenCV_VERSION}") +ENDIF() + + +include_directories(./openalpr ) + + +set(CMAKE_CSS_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall ") +ADD_EXECUTABLE( alpr main.cpp ) +TARGET_LINK_LIBRARIES(alpr + openalpr + support + ${OpenCV_LIBS} + tesseract + ) + + +add_subdirectory(openalpr) +add_subdirectory(misc_utilities) + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..0386964 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,255 @@ +/* + * 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 + * + * 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 . +*/ + + + + #include + #include + #include + + #include "opencv2/highgui/highgui.hpp" + #include "opencv2/imgproc/imgproc.hpp" + + + #include "tclap/CmdLine.h" + #include "support/filesystem.h" + #include "support/timing.h" + #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; + std::string runtimePath = ""; + bool outputJson = false; + int seektoms = 0; + bool detectRegion = false; + std::string templateRegion; + std::string country; + int topn; + + try { + + TCLAP::CmdLine cmd("OpenAlpr Command Line Utility", ' ', OPENALPR_VERSION); + + TCLAP::UnlabeledValueArg fileArg( "image_file", "Image containing license plates", true, "", "image_file_path" ); + + TCLAP::ValueArg countryCodeArg("c","country","Country code to identify (either us for USA or eu for Europe). Default=us",false, "us" ,"country_code"); + TCLAP::ValueArg seekToMsArg("","seek","Seek to the specied millisecond in a video file. Default=0",false, 0 ,"integer_ms"); + TCLAP::ValueArg runtimeDirArg("r","runtime_dir","Path to the OpenAlpr runtime data directory",false, "" ,"runtime_dir"); + TCLAP::ValueArg 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 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); + + cmd.add( fileArg ); + cmd.add( countryCodeArg ); + cmd.add( seekToMsArg ); + cmd.add( topNArg ); + cmd.add( runtimeDirArg ); + cmd.add( templateRegionArg ); + + cmd.parse( argc, argv ); + + filename = fileArg.getValue(); + + country = countryCodeArg.getValue(); + seektoms = seekToMsArg.getValue(); + outputJson = jsonSwitch.getValue(); + runtimePath = runtimeDirArg.getValue(); + detectRegion = detectRegionSwitch.getValue(); + 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; + 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; + cv::VideoCapture cap(0); + if (!cap.isOpened()) + { + std::cout << "Error opening webcam" << std::endl; + return 1; + } + + while (cap.read(frame) == true) + { + detectandshow(&alpr, frame, "", outputJson); + cv::waitKey(1); + framenum++; + } + } + else if (hasEnding(filename, ".avi") || hasEnding(filename, ".mp4") || hasEnding(filename, ".webm") || hasEnding(filename, ".flv")) + { + 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) + { + cv::imwrite(LAST_VIDEO_STILL_LOCATION, frame); + } + std::cout << "Frame: " << framenum << std::endl; + + detectandshow( &alpr, frame, "", outputJson); + //create a 1ms delay + cv::waitKey(1); + framenum++; + } + + } + else if (hasEnding(filename, ".png") || hasEnding(filename, ".jpg") || hasEnding(filename, ".gif")) + { + frame = cv::imread( filename ); + + detectandshow( &alpr, frame, "", outputJson); + + + } + else if (DirectoryExists(filename.c_str())) + { + std::vector 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")) + { + std::string fullpath = filename + "/" + files[i]; + std::cout << fullpath << std::endl; + frame = cv::imread( fullpath.c_str() ); + if (detectandshow( &alpr, frame, "", outputJson)) + { + //while ((char) cv::waitKey(50) != 'c') { } + } + else + { + //cv::waitKey(50); + } + } + + } + } + else + { + 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 buffer; + cv::imencode(".bmp", frame, buffer ); + + + timespec startTime; + getTime(&startTime); + + + std::vector results = alpr->recognize(buffer); + + + if (writeJson) + { + std::cout << alpr->toJson(results) << std::endl; + } + else + { + 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; + } + + } + } + + timespec endTime; + 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; + + } + + + +