From d5bc3157448a3de028e4d27bb0e25e2547fc854b Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 21 Jul 2015 19:53:36 -0400 Subject: [PATCH 01/50] re2 fixes for Windows --- src/openalpr/support/re2/re2.cc | 2 ++ src/openalpr/support/re2/util/mutex.h | 6 ++++-- src/openalpr/support/re2/util/stringprintf.cc | 6 +++++- src/openalpr/support/re2/util/strutil.cc | 9 +++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/openalpr/support/re2/re2.cc b/src/openalpr/support/re2/re2.cc index 28581b6..aea5f6e 100644 --- a/src/openalpr/support/re2/re2.cc +++ b/src/openalpr/support/re2/re2.cc @@ -11,7 +11,9 @@ #include #include +#ifndef WIN32 #include +#endif #include #include "util/atomicops.h" #include "util/util.h" diff --git a/src/openalpr/support/re2/util/mutex.h b/src/openalpr/support/re2/util/mutex.h index f64acb1..19a49d5 100644 --- a/src/openalpr/support/re2/util/mutex.h +++ b/src/openalpr/support/re2/util/mutex.h @@ -14,8 +14,10 @@ namespace re2 { -#define HAVE_PTHREAD 1 -#define HAVE_RWLOCK 1 +#ifndef WIN32 + #define HAVE_PTHREAD 1 + #define HAVE_RWLOCK 1 +#endif #if defined(NO_THREADS) typedef int MutexType; // to keep a lock-count diff --git a/src/openalpr/support/re2/util/stringprintf.cc b/src/openalpr/support/re2/util/stringprintf.cc index e15c550..3c9c14b 100644 --- a/src/openalpr/support/re2/util/stringprintf.cc +++ b/src/openalpr/support/re2/util/stringprintf.cc @@ -38,7 +38,11 @@ static void StringAppendV(string* dst, const char* format, va_list ap) { // Restore the va_list before we use it again va_copy(backup_ap, ap); - result = vsnprintf(buf, length, format, backup_ap); + #ifdef WIN32 + result = vsnprintf_s(buf, length, length, format, backup_ap); + #else + result = vsnprintf(buf, length, format, backup_ap); + #endif va_end(backup_ap); if ((result >= 0) && (result < length)) { diff --git a/src/openalpr/support/re2/util/strutil.cc b/src/openalpr/support/re2/util/strutil.cc index 74116ce..ab28df7 100644 --- a/src/openalpr/support/re2/util/strutil.cc +++ b/src/openalpr/support/re2/util/strutil.cc @@ -1,7 +1,7 @@ // Copyright 1999-2005 The RE2 Authors. All Rights Reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. - +#include #include "re2/util/util.h" #include "re2/stringpiece.h" @@ -38,7 +38,12 @@ int CEscapeString(const char* src, int src_len, char* dest, if (c < ' ' || c > '~') { if (dest_len - used < 5) // space for four-character escape + \0 return -1; - sprintf(dest + used, "\\%03o", c); + #ifdef WIN32 + sprintf_s(dest + used, dest_len, "\\%03o", c); + #else + std::sprintf(dest + used, "\\%03o", c); + #endif + used += 4; } else { dest[used++] = c; break; From f4bf470fa9b49cf23cf3cc5458f989d652b64235 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 21 Jul 2015 20:01:17 -0400 Subject: [PATCH 02/50] Removed accidental std:: prefix --- src/openalpr/support/re2/util/strutil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openalpr/support/re2/util/strutil.cc b/src/openalpr/support/re2/util/strutil.cc index ab28df7..215923a 100644 --- a/src/openalpr/support/re2/util/strutil.cc +++ b/src/openalpr/support/re2/util/strutil.cc @@ -1,7 +1,7 @@ // Copyright 1999-2005 The RE2 Authors. All Rights Reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include + #include "re2/util/util.h" #include "re2/stringpiece.h" @@ -41,7 +41,7 @@ int CEscapeString(const char* src, int src_len, char* dest, #ifdef WIN32 sprintf_s(dest + used, dest_len, "\\%03o", c); #else - std::sprintf(dest + used, "\\%03o", c); + sprintf(dest + used, "\\%03o", c); #endif used += 4; From 49e0c23c6b1da9fc1d22155cd82d1bd3538aace0 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Wed, 22 Jul 2015 08:08:31 +0200 Subject: [PATCH 03/50] Bugfix: Build fix for Debug|x64 --- src/bindings/csharp/openalpr-net/openalpr-net.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj index 091d751..482745b 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj +++ b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj @@ -118,7 +118,7 @@ true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib From dd36e294d61affdaaa5fe85b0947918c6a82f043 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Wed, 22 Jul 2015 08:10:37 +0200 Subject: [PATCH 04/50] Conditional set of PlatformToolset if using visual studio 2015. --- src/bindings/csharp/openalpr-net/openalpr-net.vcxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj index 482745b..3e733e9 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj +++ b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj @@ -25,6 +25,7 @@ openalprnet 2.1.0 v120 + v140 ..\..\..\..\windows None $(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform) From f8abdf2a6fc732a26c1f8223bc2a84900b1ae8cd Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Wed, 22 Jul 2015 08:56:02 +0200 Subject: [PATCH 05/50] CamelCase. --- src/bindings/csharp/openalpr-net/openalpr-net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.cpp b/src/bindings/csharp/openalpr-net/openalpr-net.cpp index 4988653..e2e114a 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.cpp +++ b/src/bindings/csharp/openalpr-net/openalpr-net.cpp @@ -326,7 +326,7 @@ namespace openalprnet { event EventHandler^ FrameProcessed; - void recognizeFromVideo(System::String^ videoPath) { + void RecognizeFromVideo(System::String^ videoPath) { if (System::IO::File::Exists(videoPath)) { int framenum = 0; cv::VideoCapture cap = cv::VideoCapture(); From dda263edb261906d329de2f53aced0eb3b3e3f78 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Wed, 22 Jul 2015 09:43:53 +0200 Subject: [PATCH 06/50] Bugfix: Bitmap ctor throws an exception if we attempt to create an empty bitmap (0, 0). --- src/bindings/csharp/openalpr-net/helper-net.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bindings/csharp/openalpr-net/helper-net.h b/src/bindings/csharp/openalpr-net/helper-net.h index ce93a1b..806ace0 100644 --- a/src/bindings/csharp/openalpr-net/helper-net.h +++ b/src/bindings/csharp/openalpr-net/helper-net.h @@ -50,6 +50,11 @@ namespace openalprnet static Bitmap^ MatToBitmap(cv::Mat mat) { + if (mat.empty()) + { + return nullptr; + } + const int width = mat.size().width; const int height = mat.size().height; const int channels = mat.channels(); From f7f1337757fd0a1ffad0bb5ced6454e290189306 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Wed, 22 Jul 2015 09:44:41 +0200 Subject: [PATCH 07/50] Throw a more descriptive exception when pixelformat is unsupported. --- src/bindings/csharp/openalpr-net/bitmapmat-net.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/csharp/openalpr-net/bitmapmat-net.h b/src/bindings/csharp/openalpr-net/bitmapmat-net.h index a65acf3..cedbf94 100644 --- a/src/bindings/csharp/openalpr-net/bitmapmat-net.h +++ b/src/bindings/csharp/openalpr-net/bitmapmat-net.h @@ -65,7 +65,7 @@ namespace openalprnet { channels = 4; break; default: - throw gcnew NotImplementedException(); + throw gcnew NotSupportedException(bitmap->PixelFormat.ToString()); } BitmapData^ bitmapData = bitmap->LockBits( From 547cc3276110a35656b2776a90d289a63e0927a4 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 22 Jul 2015 11:04:10 -0400 Subject: [PATCH 08/50] minor accuracy tweak --- src/openalpr/segmentation/charactersegmenter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openalpr/segmentation/charactersegmenter.cpp b/src/openalpr/segmentation/charactersegmenter.cpp index 2871d10..d63cc01 100644 --- a/src/openalpr/segmentation/charactersegmenter.cpp +++ b/src/openalpr/segmentation/charactersegmenter.cpp @@ -159,7 +159,6 @@ namespace alpr getTimeMonotonic(&startTime); filterEdgeBoxes(pipeline_data->thresholds, candidateBoxes, medianCharWidth, avgCharHeight); - candidateBoxes = filterMostlyEmptyBoxes(pipeline_data->thresholds, candidateBoxes); candidateBoxes = combineCloseBoxes(candidateBoxes, medianCharWidth); candidateBoxes = filterMostlyEmptyBoxes(pipeline_data->thresholds, candidateBoxes); From a1c76467b3c6d3004dd4d506a92502cfcc9ec621 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Thu, 23 Jul 2015 18:05:23 -0400 Subject: [PATCH 09/50] Minor tweaks to kr.conf --- runtime_data/config/kr.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime_data/config/kr.conf b/runtime_data/config/kr.conf index cd4b846..84b2b4d 100644 --- a/runtime_data/config/kr.conf +++ b/runtime_data/config/kr.conf @@ -5,7 +5,7 @@ char_analysis_height_range = 0.15 char_analysis_height_step_size = 0.10 char_analysis_height_num_steps = 5 -segmentation_min_box_width_px = 5 +segmentation_min_box_width_px = 4 segmentation_min_charheight_percent = 0.4; segmentation_max_segment_width_percent_vs_average = 2.0; @@ -15,7 +15,7 @@ plate_height_mm = 110 multiline = 0 char_height_mm = 80 -char_width_mm = 53 +char_width_mm = 43 char_whitespace_top_mm = 10 char_whitespace_bot_mm = 10 From 9e5995d20a56df9895661db94a284cb63107f9b2 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Thu, 23 Jul 2015 18:29:39 -0400 Subject: [PATCH 10/50] Tweaked debug output for scores --- src/openalpr/edges/scorekeeper.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/openalpr/edges/scorekeeper.cpp b/src/openalpr/edges/scorekeeper.cpp index b1ad8f8..370c3b2 100644 --- a/src/openalpr/edges/scorekeeper.cpp +++ b/src/openalpr/edges/scorekeeper.cpp @@ -69,18 +69,19 @@ namespace alpr float total = getTotal(); + std::cout << "--------------------" << std::endl; + std::cout << "Total: " << total << std::endl; for (unsigned int i = 0; i < weight_ids.size(); i++) { float percent_of_total = (scores[i] * weights[i]) / total * 100; - std::cout << " - " << std::setw(longest_weight_id + 1) << std::left << weight_ids[i] << + std::cout << " - " << std::setw(longest_weight_id + 1) << std::left << weight_ids[i] << " Weighted Score: " << std::setw(10) << std::left << (scores[i] * weights[i]) << " Orig Score: " << std::setw(10) << std::left << scores[i] << " (" << percent_of_total << "% of total)" << std::endl; } - - std::cout << "Total: " << total << std::endl; + std::cout << "--------------------" << std::endl; } } \ No newline at end of file From 9a00969e32e6099cf7cc4f06586aeb72d2305ff0 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Thu, 23 Jul 2015 23:31:21 -0400 Subject: [PATCH 11/50] Removed unused function from header --- src/openalpr/segmentation/charactersegmenter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openalpr/segmentation/charactersegmenter.h b/src/openalpr/segmentation/charactersegmenter.h index 76ec3f4..29376b0 100644 --- a/src/openalpr/segmentation/charactersegmenter.h +++ b/src/openalpr/segmentation/charactersegmenter.h @@ -74,7 +74,6 @@ namespace alpr void cleanCharRegions(std::vector thresholds, std::vector charRegions); void cleanBasedOnColor(std::vector thresholds, cv::Mat colorMask, std::vector charRegions); - void cleanMostlyFullBoxes(std::vector thresholds, const std::vector charRegions); std::vector filterMostlyEmptyBoxes(std::vector thresholds, const std::vector charRegions); void filterEdgeBoxes(std::vector thresholds, const std::vector charRegions, float avgCharWidth, float avgCharHeight); From 3b329e046ba095746800399fc873a1f10bf6d176 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Fri, 24 Jul 2015 04:19:28 -0400 Subject: [PATCH 12/50] Added mkv to the list of video extensions --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index fd9b429..4106c5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -198,7 +198,9 @@ int main( int argc, const char** argv ) std::cout << "Video processing ended" << std::endl; } else if (hasEndingInsensitive(filename, ".avi") || hasEndingInsensitive(filename, ".mp4") || hasEndingInsensitive(filename, ".webm") || - hasEndingInsensitive(filename, ".flv") || hasEndingInsensitive(filename, ".mjpg") || hasEndingInsensitive(filename, ".mjpeg")) + hasEndingInsensitive(filename, ".flv") || hasEndingInsensitive(filename, ".mjpg") || hasEndingInsensitive(filename, ".mjpeg") || + hasEndingInsensitive(filename, ".mkv") + ) { if (fileExists(filename.c_str())) { From 6f4c419a5002348d40d7b44df8e8b17ef71fe2a2 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Fri, 24 Jul 2015 04:32:03 -0400 Subject: [PATCH 13/50] Changed a hardcoded value to the config parameter --- src/openalpr/segmentation/charactersegmenter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openalpr/segmentation/charactersegmenter.cpp b/src/openalpr/segmentation/charactersegmenter.cpp index d63cc01..7a14956 100644 --- a/src/openalpr/segmentation/charactersegmenter.cpp +++ b/src/openalpr/segmentation/charactersegmenter.cpp @@ -259,7 +259,7 @@ namespace alpr vector CharacterSegmenter::getBestCharBoxes(Mat img, vector charBoxes, float avgCharWidth) { - float MAX_SEGMENT_WIDTH = avgCharWidth * 1.65; + float MAX_SEGMENT_WIDTH = avgCharWidth * config->segmentationMaxCharWidthvsAverage; // This histogram is based on how many char boxes (from ALL of the many thresholded images) are covering each column // Makes a sort of histogram from all the previous char boxes. Figures out the best fit from that. From f3c91096e53112f494743c035792093abb3700ec Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Tue, 28 Jul 2015 18:22:25 -0400 Subject: [PATCH 14/50] Removed unused functions from postprocess --- src/openalpr/postprocess/postprocess.cpp | 6 ------ src/openalpr/postprocess/postprocess.h | 3 +-- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/openalpr/postprocess/postprocess.cpp b/src/openalpr/postprocess/postprocess.cpp index 2feb757..2733a7b 100644 --- a/src/openalpr/postprocess/postprocess.cpp +++ b/src/openalpr/postprocess/postprocess.cpp @@ -386,12 +386,6 @@ namespace alpr return true; } - bool wordCompare( const PPResult &left, const PPResult &right ) - { - if (left.totalscore < right.totalscore) - return false; - return true; - } bool letterCompare( const Letter &left, const Letter &right ) { diff --git a/src/openalpr/postprocess/postprocess.h b/src/openalpr/postprocess/postprocess.h index ee25c64..5eddc08 100644 --- a/src/openalpr/postprocess/postprocess.h +++ b/src/openalpr/postprocess/postprocess.h @@ -53,7 +53,6 @@ namespace alpr std::vector letter_details; }; - bool wordCompare( const PPResult &left, const PPResult &right ); bool letterCompare( const Letter &left, const Letter &right ); @@ -77,7 +76,7 @@ namespace alpr private: Config* config; - //void getTopN(); + void findAllPermutations(std::string templateregion, int topn); bool analyzePermutation(std::vector letterIndices, std::string templateregion, int topn); From b579f931d8f5834f00854a061da37388a3ce454f Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 29 Jul 2015 00:04:53 -0400 Subject: [PATCH 15/50] initializing memory before copying to the buffer for getExeDir() --- src/openalpr/support/platform.cpp | 3 ++- src/openalpr/support/platform.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/openalpr/support/platform.cpp b/src/openalpr/support/platform.cpp index 185e257..a8db239 100644 --- a/src/openalpr/support/platform.cpp +++ b/src/openalpr/support/platform.cpp @@ -30,8 +30,9 @@ namespace alpr return directory; #else char buffer[2048]; + memset(buffer, 0, sizeof(buffer)); - readlink("/proc/self/exe", buffer, 2048); + readlink("/proc/self/exe", buffer, sizeof(buffer)); std::stringstream ss; ss << buffer; diff --git a/src/openalpr/support/platform.h b/src/openalpr/support/platform.h index 07b15a4..4100ecd 100644 --- a/src/openalpr/support/platform.h +++ b/src/openalpr/support/platform.h @@ -1,7 +1,7 @@ #ifndef OPENALPR_PLATFORM_H #define OPENALPR_PLATFORM_H -#include +#include #include #ifdef WINDOWS From 7e54db681e949ba6e81acd81978bd03e66cbc4cd Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 29 Jul 2015 18:45:23 -0400 Subject: [PATCH 16/50] Using a different sort to resolve unstable behavior on OS X Yosemite --- src/openalpr/postprocess/postprocess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openalpr/postprocess/postprocess.cpp b/src/openalpr/postprocess/postprocess.cpp index 2733a7b..dcdf043 100644 --- a/src/openalpr/postprocess/postprocess.cpp +++ b/src/openalpr/postprocess/postprocess.cpp @@ -170,7 +170,7 @@ namespace alpr for (int i = 0; i < letters.size(); i++) { if (letters[i].size() > 0) - sort(letters[i].begin(), letters[i].end(), letterCompare); + std::stable_sort(letters[i].begin(), letters[i].end(), letterCompare); } if (this->config->debugPostProcess) From 91f0dd08e563b44a39971d720b5c554d9b85b9d6 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 2 Aug 2015 11:41:29 -0400 Subject: [PATCH 17/50] Fixed thread safety issue in Python binding --- src/bindings/python/openalpr.py | 34 +++++++++++++++++------------- src/bindings/python/openalprpy.cpp | 33 ++++++++++++----------------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/bindings/python/openalpr.py b/src/bindings/python/openalpr.py index 3cb8883..2f63650 100644 --- a/src/bindings/python/openalpr.py +++ b/src/bindings/python/openalpr.py @@ -9,52 +9,56 @@ class Alpr(): if platform.system().lower().find("windows") != -1: self._openalprpy_lib = ctypes.cdll.LoadLibrary("openalprpy.dll") else: - self._openalprpy_lib = ctypes.cdll.LoadLibrary("libopenalprpy.so") + self._openalprpy_lib = ctypes.cdll.LoadLibrary("/storage/projects/alpr/src/build/Debug/libopenalprpy.so") self._initialize_func = self._openalprpy_lib.initialize + self._initialize_func.restype = ctypes.c_void_p self._initialize_func.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p] self._dispose_func = self._openalprpy_lib.dispose + self._dispose_func.argtypes = [ctypes.c_void_p] self._is_loaded_func = self._openalprpy_lib.isLoaded + self._is_loaded_func.argtypes = [ctypes.c_void_p] self._is_loaded_func.restype = ctypes.c_bool self._recognize_file_func = self._openalprpy_lib.recognizeFile self._recognize_file_func.restype = ctypes.c_void_p - self._recognize_file_func.argtypes = [ctypes.c_char_p] + self._recognize_file_func.argtypes = [ctypes.c_void_p, ctypes.c_char_p] self._recognize_array_func = self._openalprpy_lib.recognizeArray self._recognize_array_func.restype = ctypes.c_void_p - self._recognize_array_func.argtypes = [ctypes.POINTER(ctypes.c_ubyte), ctypes.c_uint] + self._recognize_array_func.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_uint] self._free_json_mem_func = self._openalprpy_lib.freeJsonMem self._set_default_region_func = self._openalprpy_lib.setDefaultRegion - self._set_default_region_func.argtypes = [ctypes.c_char_p] + self._set_default_region_func.argtypes = [ctypes.c_void_p, ctypes.c_char_p] self._set_detect_region_func = self._openalprpy_lib.setDetectRegion - self._set_detect_region_func.argtypes = [ctypes.c_bool] + self._set_detect_region_func.argtypes = [ctypes.c_void_p, ctypes.c_bool] self._set_top_n_func = self._openalprpy_lib.setTopN - self._set_top_n_func.argtypes = [ctypes.c_int] + self._set_top_n_func.argtypes = [ctypes.c_void_p, ctypes.c_int] self._get_version_func = self._openalprpy_lib.getVersion + self._get_version_func.argtypes = [ctypes.c_void_p] self._get_version_func.restype = ctypes.c_void_p - self._initialize_func(country, config_file, runtime_dir) + self.alpr_pointer = self._initialize_func(country, config_file, runtime_dir) def unload(self): - self._openalprpy_lib.dispose() + self._openalprpy_lib.dispose(self.alpr_pointer) def is_loaded(self): - return self._is_loaded_func() + return self._is_loaded_func(self.alpr_pointer) def recognize_file(self, file_path): - ptr = self._recognize_file_func(file_path) + ptr = self._recognize_file_func(self.alpr_pointer, file_path) json_data = ctypes.cast(ptr, ctypes.c_char_p).value response_obj = json.loads(json_data) self._free_json_mem_func(ctypes.c_void_p(ptr)) @@ -64,7 +68,7 @@ class Alpr(): def recognize_array(self, byte_array): pb = ctypes.cast(byte_array, ctypes.POINTER(ctypes.c_ubyte)) - ptr = self._recognize_array_func(pb, len(byte_array)) + ptr = self._recognize_array_func(self.alpr_pointer, pb, len(byte_array)) json_data = ctypes.cast(ptr, ctypes.c_char_p).value response_obj = json.loads(json_data) self._free_json_mem_func(ctypes.c_void_p(ptr)) @@ -73,19 +77,19 @@ class Alpr(): def get_version(self): - ptr = self._get_version_func() + ptr = self._get_version_func(self.alpr_pointer) version_number = ctypes.cast(ptr, ctypes.c_char_p).value self._free_json_mem_func(ctypes.c_void_p(ptr)) return version_number def set_top_n(self, topn): - self._set_top_n_func(topn) + self._set_top_n_func(self.alpr_pointer, topn) def set_default_region(self, region): - self._set_default_region_func(region) + self._set_default_region_func(self.alpr_pointer, region) def set_detect_region(self, enabled): - self._set_detect_region_func(enabled) + self._set_detect_region_func(self.alpr_pointer, enabled) diff --git a/src/bindings/python/openalprpy.cpp b/src/bindings/python/openalprpy.cpp index a2ca3f6..331df29 100644 --- a/src/bindings/python/openalprpy.cpp +++ b/src/bindings/python/openalprpy.cpp @@ -16,10 +16,8 @@ extern "C" { using namespace alpr; - bool initialized = false; - static Alpr* nativeAlpr; - OPENALPR_EXPORT void initialize(char* ccountry, char* cconfigFile, char* cruntimeDir) + OPENALPR_EXPORT Alpr* initialize(char* ccountry, char* cconfigFile, char* cruntimeDir) { //printf("Initialize"); @@ -29,35 +27,29 @@ extern "C" { std::string runtimeDir(cruntimeDir); //std::cout << country << std::endl << configFile << std::endl << runtimeDir << std::endl; - nativeAlpr = new alpr::Alpr(country, configFile, runtimeDir); + Alpr* nativeAlpr = new alpr::Alpr(country, configFile, runtimeDir); - initialized = true; - return; + return nativeAlpr; } - OPENALPR_EXPORT void dispose() + OPENALPR_EXPORT void dispose(Alpr* nativeAlpr) { - //printf("Dispose"); - initialized = false; delete nativeAlpr; } - OPENALPR_EXPORT bool isLoaded() + OPENALPR_EXPORT bool isLoaded(Alpr* nativeAlpr) { //printf("IS LOADED"); - if (!initialized) - return false; - return nativeAlpr->isLoaded(); } - OPENALPR_EXPORT char* recognizeFile(char* cimageFile) + OPENALPR_EXPORT char* recognizeFile(Alpr* nativeAlpr, char* cimageFile) { //printf("Recognize file"); @@ -83,12 +75,13 @@ extern "C" { } - OPENALPR_EXPORT char* recognizeArray(unsigned char* buf, int len) + OPENALPR_EXPORT char* recognizeArray(Alpr* nativeAlpr, unsigned char* buf, int len) { //printf("Recognize byte array"); //printf("buffer pointer: %p\n", buf); //printf("buffer length: %d\n", len); - + + //std::cout << "Using instance: " << nativeAlpr << std::endl; std::vector cvec(buf, buf+len); @@ -103,7 +96,7 @@ extern "C" { return membuffer; } - OPENALPR_EXPORT void setDefaultRegion(char* cdefault_region) + OPENALPR_EXPORT void setDefaultRegion(Alpr* nativeAlpr, char* cdefault_region) { // Convert strings from java to C++ and release resources std::string default_region(cdefault_region); @@ -111,17 +104,17 @@ extern "C" { nativeAlpr->setDefaultRegion(default_region); } - OPENALPR_EXPORT void setDetectRegion(bool detect_region) + OPENALPR_EXPORT void setDetectRegion(Alpr* nativeAlpr, bool detect_region) { nativeAlpr->setDetectRegion(detect_region); } - OPENALPR_EXPORT void setTopN(int top_n) + OPENALPR_EXPORT void setTopN(Alpr* nativeAlpr, int top_n) { nativeAlpr->setTopN(top_n); } - OPENALPR_EXPORT char* getVersion() + OPENALPR_EXPORT char* getVersion(Alpr* nativeAlpr) { std::string version = nativeAlpr->getVersion(); From 6b42d2eab18288c542d787fecd3918b42c0cd99d Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 2 Aug 2015 11:43:08 -0400 Subject: [PATCH 18/50] Using generic library path for Python binding --- src/bindings/python/openalpr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/python/openalpr.py b/src/bindings/python/openalpr.py index 2f63650..73801bf 100644 --- a/src/bindings/python/openalpr.py +++ b/src/bindings/python/openalpr.py @@ -9,7 +9,7 @@ class Alpr(): if platform.system().lower().find("windows") != -1: self._openalprpy_lib = ctypes.cdll.LoadLibrary("openalprpy.dll") else: - self._openalprpy_lib = ctypes.cdll.LoadLibrary("/storage/projects/alpr/src/build/Debug/libopenalprpy.so") + self._openalprpy_lib = ctypes.cdll.LoadLibrary("libopenalprpy.so") self._initialize_func = self._openalprpy_lib.initialize From 7652e8107f191856518de178ed8a9222ac1eeb2f Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 2 Aug 2015 21:56:33 -0400 Subject: [PATCH 19/50] Added wisconsin pattern --- runtime_data/postprocess/us.patterns | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime_data/postprocess/us.patterns b/runtime_data/postprocess/us.patterns index ea5df8c..45f1caf 100644 --- a/runtime_data/postprocess/us.patterns +++ b/runtime_data/postprocess/us.patterns @@ -203,6 +203,8 @@ va ####@@ va #####[JY] wa ###@@@ wa @@@#### +wi ###@@@ +wi @@@### wv [1-9DON]@@### wv [1-9DON]@#### wy ###### From 840df39cc869a974fb215e2769aa7d52cf26b333 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 3 Aug 2015 18:52:08 -0400 Subject: [PATCH 20/50] Fixed regex issue in classifychars --- src/misc_utilities/classifychars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc_utilities/classifychars.cpp b/src/misc_utilities/classifychars.cpp index ec403a2..fa0b58f 100644 --- a/src/misc_utilities/classifychars.cpp +++ b/src/misc_utilities/classifychars.cpp @@ -324,7 +324,7 @@ vector showCharSelection(Mat image, vector charRegions, string sta for (int i = 0; i < charRegions.size(); i++) humanInputs[i] = SPACE; - RegexRule regex_rule("", "[\\p{Digit}\\p{Alpha}]"); + RegexRule regex_rule("", "[\\pL\\pN]"); int16_t waitkey = waitKey(50); while (waitkey != ENTER_KEY && waitkey != ESCAPE_KEY) From eb9d2fd5b477c7ffbf836123286b553ac9a7f930 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 3 Aug 2015 18:52:58 -0400 Subject: [PATCH 21/50] Hiding Tesseract debug output --- src/openalpr/ocr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openalpr/ocr.cpp b/src/openalpr/ocr.cpp index c589b70..0fda772 100644 --- a/src/openalpr/ocr.cpp +++ b/src/openalpr/ocr.cpp @@ -42,6 +42,7 @@ namespace alpr // Tesseract requires the prefix directory to be set as an env variable tesseract.Init(config->getTessdataPrefix().c_str(), config->ocrLanguage.c_str() ); tesseract.SetVariable("save_blob_choices", "T"); + tesseract.SetVariable("debug_file", "/dev/null"); tesseract.SetPageSegMode(PSM_SINGLE_CHAR); } From 891e13dbf9e71ac6acac01197194529ba01fe0c9 Mon Sep 17 00:00:00 2001 From: ShaneQful Date: Tue, 4 Aug 2015 12:24:48 +0100 Subject: [PATCH 22/50] Changed patterns so more much more likely to find valid county code (could still find invalid on two letter codes but much less likely) --- runtime_data/postprocess/eu.patterns | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/runtime_data/postprocess/eu.patterns b/runtime_data/postprocess/eu.patterns index 3e30861..d5fae76 100644 --- a/runtime_data/postprocess/eu.patterns +++ b/runtime_data/postprocess/eu.patterns @@ -36,22 +36,22 @@ gi [G]####@ gr @@@#### hu @@@### is @@@## -ie [12]##@###### -ie [12]##@@###### -ie [12]##@##### -ie [12]##@@##### -ie [12]##@#### -ie [12]##@@#### -ie [12]##@### -ie [12]##@@### -ie ##@###### -ie ##@@###### -ie ##@##### -ie ##@@##### -ie ##@#### -ie ##@@#### -ie ##@### -ie ##@@### +ie [12]##[CDGLTW]###### +ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]###### +ie [12]##[CDGLTW]##### +ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]##### +ie [12]##[CDGLTW]#### +ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]#### +ie [12]##[CDGLTW]### +ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]### +ie ##[CDGLTW]###### +ie ##[CDGKLMORSTW][DEHKLMNOSWXY]###### +ie ##[CDGLTW]##### +ie ##[CDGKLMORSTW][DEHKLMNOSWXY]##### +ie ##[CDGLTW]#### +ie ##[CDGKLMORSTW][DEHKLMNOSWXY]#### +ie ##[CDGLTW]### +ie ##[CDGKLMORSTW][DEHKLMNOSWXY]### it @@###@@ kz ###@@@ lv @@#### From d908c262450e385fa309413647b0ea75abddc8c1 Mon Sep 17 00:00:00 2001 From: ShaneQful Date: Tue, 4 Aug 2015 12:41:48 +0100 Subject: [PATCH 23/50] Fixed the half year appendage to be on the RHS of the year --- runtime_data/postprocess/eu.patterns | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/runtime_data/postprocess/eu.patterns b/runtime_data/postprocess/eu.patterns index d5fae76..b528f21 100644 --- a/runtime_data/postprocess/eu.patterns +++ b/runtime_data/postprocess/eu.patterns @@ -36,14 +36,14 @@ gi [G]####@ gr @@@#### hu @@@### is @@@## -ie [12]##[CDGLTW]###### -ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]###### -ie [12]##[CDGLTW]##### -ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]##### -ie [12]##[CDGLTW]#### -ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]#### -ie [12]##[CDGLTW]### -ie [12]##[CDGKLMORSTW][DEHKLMNOSWXY]### +ie ##[12][CDGLTW]###### +ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]###### +ie ##[12][CDGLTW]##### +ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]##### +ie ##[12][CDGLTW]#### +ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]#### +ie ##[12][CDGLTW]### +ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]### ie ##[CDGLTW]###### ie ##[CDGKLMORSTW][DEHKLMNOSWXY]###### ie ##[CDGLTW]##### From 7061db554833640c098e140c4830b7eb40089087 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 5 Aug 2015 18:47:29 -0400 Subject: [PATCH 24/50] Cleaned up Python bindings. Moved to openalpr package and added import in __init__ --- src/bindings/python/openalpr/__init__.py | 1 + src/bindings/python/{ => openalpr}/openalpr.py | 0 src/bindings/python/setup.py | 12 ++++++++++++ src/bindings/python/test.py | 2 +- 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/bindings/python/openalpr/__init__.py rename src/bindings/python/{ => openalpr}/openalpr.py (100%) create mode 100644 src/bindings/python/setup.py diff --git a/src/bindings/python/openalpr/__init__.py b/src/bindings/python/openalpr/__init__.py new file mode 100644 index 0000000..2871d69 --- /dev/null +++ b/src/bindings/python/openalpr/__init__.py @@ -0,0 +1 @@ +from openalpr import Alpr diff --git a/src/bindings/python/openalpr.py b/src/bindings/python/openalpr/openalpr.py similarity index 100% rename from src/bindings/python/openalpr.py rename to src/bindings/python/openalpr/openalpr.py diff --git a/src/bindings/python/setup.py b/src/bindings/python/setup.py new file mode 100644 index 0000000..5c503d3 --- /dev/null +++ b/src/bindings/python/setup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +from distutils.core import setup + +setup(name='openalpr', + version='1.0', + description='OpenALPR Python Bindings', + author='Matt Hill', + author_email='matthill@openalpr.com', + url='http://www.openalpr.com/', + packages=['openalpr'] + ) diff --git a/src/bindings/python/test.py b/src/bindings/python/test.py index 5a068f6..e350f07 100644 --- a/src/bindings/python/test.py +++ b/src/bindings/python/test.py @@ -54,4 +54,4 @@ try: finally: if alpr: - alpr.unload() \ No newline at end of file + alpr.unload() From e640c99310bc5be14aa113e95e0f319ee939a569 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 5 Aug 2015 18:48:00 -0400 Subject: [PATCH 25/50] Added Python binding installer/deb package --- distros/debian/control | 10 ++++++++++ distros/debian/python-openalpr.install | 1 + src/bindings/python/CMakeLists.txt | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 distros/debian/python-openalpr.install diff --git a/distros/debian/control b/distros/debian/control index 78b8301..91ecc80 100644 --- a/distros/debian/control +++ b/distros/debian/control @@ -69,3 +69,13 @@ Description: Utilities for the OpenALPR library OpenALPR is an open source Automatic License Plate Recognition library written in C++. The library analyzes images and identifies license plates. The output is the text representation of any license plate characters found in the image. + +Package: python-openalpr +Section: libdevel +Architecture: amd64 +Depends: libopenalpr-dev (= ${binary:Version}), ${misc:Depends} +Description: Python binding for OpenALPR library + OpenALPR is an open source Automatic License Plate Recognition library written + in C++. The library analyzes images and identifies license plates. The output + is the text representation of any license plate characters found in the image. + diff --git a/distros/debian/python-openalpr.install b/distros/debian/python-openalpr.install new file mode 100644 index 0000000..4d43ce6 --- /dev/null +++ b/distros/debian/python-openalpr.install @@ -0,0 +1 @@ +usr/lib/python2.7/dist-packages/openalpr \ No newline at end of file diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 6466d87..91d4fe5 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -17,4 +17,7 @@ set_target_properties(openalprpy PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSION}) TARGET_LINK_LIBRARIES(openalprpy openalpr) -install (TARGETS openalprpy DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) \ No newline at end of file +install (TARGETS openalprpy DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) +install (DIRECTORY openalpr DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages + USE_SOURCE_PERMISSIONS +) From 57986b0685d8529c1f0c8469bd2f8792cd888188 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 5 Aug 2015 19:06:41 -0400 Subject: [PATCH 26/50] Changed section for python package --- distros/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distros/debian/control b/distros/debian/control index 91ecc80..90a676b 100644 --- a/distros/debian/control +++ b/distros/debian/control @@ -71,7 +71,7 @@ Description: Utilities for the OpenALPR library is the text representation of any license plate characters found in the image. Package: python-openalpr -Section: libdevel +Section: python Architecture: amd64 Depends: libopenalpr-dev (= ${binary:Version}), ${misc:Depends} Description: Python binding for OpenALPR library From 2fc60ae0bea84c944d02ff5e2b23f20eda5dfe3a Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Fri, 7 Aug 2015 11:21:22 +0200 Subject: [PATCH 27/50] Add overload for regionsOfInterest. --- src/openalpr/alpr.cpp | 5 +++++ src/openalpr/alpr.h | 7 +++++-- src/openalpr/alpr_impl.cpp | 7 +++++++ src/openalpr/alpr_impl.h | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/openalpr/alpr.cpp b/src/openalpr/alpr.cpp index 840b96b..a89ce21 100644 --- a/src/openalpr/alpr.cpp +++ b/src/openalpr/alpr.cpp @@ -68,6 +68,11 @@ namespace alpr return impl->recognize(imageBytes); } + AlprResults Alpr::recognize(std::vector imageBytes, std::vector regionsOfInterest) + { + return impl->recognize(imageBytes, regionsOfInterest); + } + AlprResults Alpr::recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector regionsOfInterest) { return impl->recognize(pixelData, bytesPerPixel, imgWidth, imgHeight, regionsOfInterest); diff --git a/src/openalpr/alpr.h b/src/openalpr/alpr.h index 7146322..c94ed9b 100644 --- a/src/openalpr/alpr.h +++ b/src/openalpr/alpr.h @@ -132,8 +132,11 @@ namespace alpr // Recognize from an image on disk AlprResults recognize(std::string filepath); - // Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). - AlprResults recognize(std::vector imageBytes); + // Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). + AlprResults recognize(std::vector imageBytes); + + // Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc). + AlprResults recognize(std::vector imageBytes, std::vector regionsOfInterest); // Recognize from raw pixel data. AlprResults recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector regionsOfInterest); diff --git a/src/openalpr/alpr_impl.cpp b/src/openalpr/alpr_impl.cpp index fc8ca37..aa10796 100644 --- a/src/openalpr/alpr_impl.cpp +++ b/src/openalpr/alpr_impl.cpp @@ -345,6 +345,13 @@ namespace alpr return this->recognize(img); } + AlprResults AlprImpl::recognize(std::vector imageBytes, std::vector regionsOfInterest) + { + cv::Mat img = cv::imdecode(cv::Mat(imageBytes), 1); + + return this->recognize(img, regionsOfInterest); + } + AlprResults AlprImpl::recognize( unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector regionsOfInterest) { diff --git a/src/openalpr/alpr_impl.h b/src/openalpr/alpr_impl.h index f5fcbd9..776807b 100644 --- a/src/openalpr/alpr_impl.h +++ b/src/openalpr/alpr_impl.h @@ -76,6 +76,7 @@ namespace alpr AlprFullDetails recognizeFullDetails(cv::Mat img, std::vector regionsOfInterest); AlprResults recognize( std::vector imageBytes ); + AlprResults recognize( std::vector imageBytes, std::vector regionsOfInterest ); AlprResults recognize( unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector regionsOfInterest ); AlprResults recognize( cv::Mat img ); AlprResults recognize( cv::Mat img, std::vector regionsOfInterest ); From 3f63dab7e1a857d474ace3ec5e80fcc5b390bb11 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Fri, 7 Aug 2015 11:23:12 +0200 Subject: [PATCH 28/50] Bugfix: Regions of interest. --- src/bindings/csharp/openalpr-net/openalpr-net.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.cpp b/src/bindings/csharp/openalpr-net/openalpr-net.cpp index e2e114a..f109740 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.cpp +++ b/src/bindings/csharp/openalpr-net/openalpr-net.cpp @@ -428,7 +428,8 @@ namespace openalprnet { /// Bytes representing image data AlprResultsNet^ Recognize(cli::array^ imageBuffer, List^ regionsOfInterest) { std::vector p = AlprHelper::ToVector(imageBuffer); - AlprResults results = m_Impl->recognize(p); + std::vector rois = AlprHelper::ToVector(regionsOfInterest); + AlprResults results = m_Impl->recognize(p, rois); return gcnew AlprResultsNet(results); } From 1729f48ba8ab790a00d5acb75f41d6f073dd8f6a Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Fri, 7 Aug 2015 14:30:17 +0200 Subject: [PATCH 29/50] Fix visual studio deprecation warning. --- src/bindings/csharp/openalpr-net/AssemblyInfo.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp b/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp index ac5af8d..cc20aa3 100644 --- a/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp +++ b/src/bindings/csharp/openalpr-net/AssemblyInfo.cpp @@ -38,5 +38,3 @@ using namespace System::Security::Permissions; [assembly:ComVisible(false)]; [assembly:CLSCompliantAttribute(true)]; - -[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)]; From 3ff3e31bf87247a85f511ec042c765ec026bce66 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Fri, 7 Aug 2015 14:33:39 +0200 Subject: [PATCH 30/50] Bugfix: Stackoverflow. --- src/openalpr/alpr_impl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/openalpr/alpr_impl.cpp b/src/openalpr/alpr_impl.cpp index aa10796..02975c2 100644 --- a/src/openalpr/alpr_impl.cpp +++ b/src/openalpr/alpr_impl.cpp @@ -349,7 +349,10 @@ namespace alpr { cv::Mat img = cv::imdecode(cv::Mat(imageBytes), 1); - return this->recognize(img, regionsOfInterest); + std::vector rois = convertRects(regionsOfInterest); + + AlprFullDetails fullDetails = recognizeFullDetails(img, rois); + return fullDetails.results; } AlprResults AlprImpl::recognize( unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector regionsOfInterest) From 31d502194aa874e617b73f6cc2c2b41fe5d93835 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Fri, 7 Aug 2015 14:34:22 +0200 Subject: [PATCH 31/50] Bugfix: Region of interest. --- src/bindings/csharp/openalpr-net/openalpr-net.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.cpp b/src/bindings/csharp/openalpr-net/openalpr-net.cpp index f109740..a691f20 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.cpp +++ b/src/bindings/csharp/openalpr-net/openalpr-net.cpp @@ -409,8 +409,9 @@ namespace openalprnet { /// AlprResultsNet^ Recognize(MemoryStream^ memoryStream, List^ regionsOfInterest) { - std::vector p = AlprHelper::MemoryStreamToVector(memoryStream); - AlprResults results = m_Impl->recognize(p); + std::vector buffer = AlprHelper::MemoryStreamToVector(memoryStream); + std::vector rois = AlprHelper::ToVector(regionsOfInterest); + AlprResults results = m_Impl->recognize(buffer, rois); return gcnew AlprResultsNet(results); } @@ -427,9 +428,9 @@ namespace openalprnet { /// /// Bytes representing image data AlprResultsNet^ Recognize(cli::array^ imageBuffer, List^ regionsOfInterest) { - std::vector p = AlprHelper::ToVector(imageBuffer); + std::vector buffer = AlprHelper::ToVector(imageBuffer); std::vector rois = AlprHelper::ToVector(regionsOfInterest); - AlprResults results = m_Impl->recognize(p, rois); + AlprResults results = m_Impl->recognize(buffer, rois); return gcnew AlprResultsNet(results); } From 5101e2b9b4898fc6b7ec7bd118f3d081fb3be010 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:19:59 -0400 Subject: [PATCH 32/50] Moved featurematcher into separate library --- .../featurematcher.cpp | 38 +++++++++---------- .../featurematcher.h | 8 ++-- 2 files changed, 24 insertions(+), 22 deletions(-) rename src/{openalpr => statedetection}/featurematcher.cpp (92%) rename src/{openalpr => statedetection}/featurematcher.h (94%) diff --git a/src/openalpr/featurematcher.cpp b/src/statedetection/featurematcher.cpp similarity index 92% rename from src/openalpr/featurematcher.cpp rename to src/statedetection/featurematcher.cpp index e03275e..42f1b33 100644 --- a/src/openalpr/featurematcher.cpp +++ b/src/statedetection/featurematcher.cpp @@ -29,10 +29,8 @@ namespace alpr //const int DEFAULT_TRAINING_FEATURES = 305; const float MAX_DISTANCE_TO_MATCH = 100.0f; - FeatureMatcher::FeatureMatcher(Config* config) + FeatureMatcher::FeatureMatcher() { - this->config = config; - //this->descriptorMatcher = DescriptorMatcher::create( "BruteForce-HammingLUT" ); this->descriptorMatcher = new BFMatcher(NORM_HAMMING, false); @@ -152,8 +150,8 @@ namespace alpr // We assume that license plates won't be upside-down or backwards. So expect lines to be closely parallel void FeatureMatcher::crisscrossFiltering(const vector queryKeypoints, const vector inputMatches, vector &outputMatches) { - Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2); - Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx); + Rect crissCrossAreaVertical(0, 0, w, h * 2); + Rect crissCrossAreaHorizontal(0, 0, w * 2, h); for (unsigned int i = 0; i < billMapping.size(); i++) { @@ -175,8 +173,8 @@ namespace alpr 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)); + vlines.push_back(LineSegment(tkp.pt.x, tkp.pt.y + h, qkp.pt.x, qkp.pt.y)); + hlines.push_back(LineSegment(tkp.pt.x, tkp.pt.y, qkp.pt.x + w, qkp.pt.y)); matchIdx.push_back(j); } @@ -215,8 +213,8 @@ namespace alpr if (mostIntersectionsIndex >= 0) { - if (this->config->debugStateId) - cout << "Filtered intersection! " << billMapping[i] << endl; +// if (this->config->debugStateId) +// cout << "Filtered intersection! " << billMapping[i] << endl; vlines.erase(vlines.begin() + mostIntersectionsIndex); hlines.erase(hlines.begin() + mostIntersectionsIndex); matchIdx.erase(matchIdx.begin() + mostIntersectionsIndex); @@ -232,10 +230,10 @@ namespace alpr } // Returns true if successful, false otherwise - bool FeatureMatcher::loadRecognitionSet(string country) + bool FeatureMatcher::loadRecognitionSet(string directory, string country) { std::ostringstream out; - out << config->getKeypointsRuntimeDir() << "/" << country << "/"; + out << directory << "/keypoints/" << country << "/"; string country_dir = out.str(); if (DirectoryExists(country_dir.c_str())) @@ -253,7 +251,6 @@ namespace alpr // 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() ) { @@ -290,6 +287,9 @@ namespace alpr { RecognitionResult result; + this->w = queryImg.cols; + this->h = queryImg.rows; + result.haswinner = false; result.confidence = 0; @@ -381,13 +381,13 @@ namespace alpr } } - if (this->config->debugStateId) - { - for (unsigned int i = 0; i < billMapping.size(); i++) - { - cout << billMapping[i] << " : " << bill_match_counts[i] << endl; - } - } +// if (this->config->debugStateId) +// { +// for (unsigned int i = 0; i < billMapping.size(); i++) +// { +// cout << billMapping[i] << " : " << bill_match_counts[i] << endl; +// } +// } return result; } diff --git a/src/openalpr/featurematcher.h b/src/statedetection/featurematcher.h similarity index 94% rename from src/openalpr/featurematcher.h rename to src/statedetection/featurematcher.h index 98c5938..1319b9a 100644 --- a/src/openalpr/featurematcher.h +++ b/src/statedetection/featurematcher.h @@ -44,20 +44,19 @@ namespace alpr { public: - FeatureMatcher(Config* config); + FeatureMatcher(); virtual ~FeatureMatcher(); RecognitionResult recognize( const cv::Mat& queryImg, bool drawOnImage, cv::Mat* outputImage, bool debug_on, std::vector debug_matches_array ); - bool loadRecognitionSet(std::string country); + bool loadRecognitionSet(std::string runtime_dir, std::string country); bool isLoaded(); int numTrainingElements(); private: - Config* config; cv::Ptr descriptorMatcher; cv::Ptr detector; @@ -74,6 +73,9 @@ namespace alpr void surfStyleMatching( const cv::Mat& queryDescriptors, std::vector queryKeypoints, std::vector& matches12 ); + + int w; + int h; }; } From 226ff9eb03145ea8108e80d3aef2013259f831c5 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:21:07 -0400 Subject: [PATCH 33/50] moved existing state detection code into separate library --- src/openalpr/stateidentifier.cpp | 94 ------------------- src/statedetection/CMakeLists.txt | 23 +++++ src/statedetection/state_detector.cpp | 52 ++++++++++ src/statedetection/state_detector.h | 55 +++++++++++ src/statedetection/state_detector_impl.cpp | 83 ++++++++++++++++ .../state_detector_impl.h} | 41 ++++---- 6 files changed, 231 insertions(+), 117 deletions(-) delete mode 100644 src/openalpr/stateidentifier.cpp create mode 100644 src/statedetection/CMakeLists.txt create mode 100644 src/statedetection/state_detector.cpp create mode 100644 src/statedetection/state_detector.h create mode 100644 src/statedetection/state_detector_impl.cpp rename src/{openalpr/stateidentifier.h => statedetection/state_detector_impl.h} (52%) diff --git a/src/openalpr/stateidentifier.cpp b/src/openalpr/stateidentifier.cpp deleted file mode 100644 index 9e02ffb..0000000 --- a/src/openalpr/stateidentifier.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2015 OpenALPR Technology, Inc. - * Open source 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 "stateidentifier.h" - - -using namespace cv; -using namespace std; - -namespace alpr -{ - - 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); - } - - StateIdentifier::~StateIdentifier() - { - delete featureMatcher; - } - - - // Attempts to recognize the plate. Returns a confidence level. Updates the region code and confidence - // If region is found, returns true. - bool StateIdentifier::recognize(PipelineData* pipeline_data) - { - timespec startTime; - getTimeMonotonic(&startTime); - - Mat plateImg = Mat(pipeline_data->grayImg, pipeline_data->regionOfInterest); - - resize(plateImg, plateImg, getSizeMaintainingAspect(plateImg, config->stateIdImageWidthPx, config->stateIdimageHeightPx)); - - - Mat debugImg(plateImg.size(), plateImg.type()); - plateImg.copyTo(debugImg); - vector 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; - getTimeMonotonic(&endTime); - cout << "State Identification Time: " << diffclock(startTime, endTime) << "ms." << endl; - } - - if (result.haswinner == false) - return 0; - - pipeline_data->region_code = result.winner; - pipeline_data->region_confidence = result.confidence; - - if (result.confidence >= 10) - return true; - - return false; - } - -} \ No newline at end of file diff --git a/src/statedetection/CMakeLists.txt b/src/statedetection/CMakeLists.txt new file mode 100644 index 0000000..3c15c6d --- /dev/null +++ b/src/statedetection/CMakeLists.txt @@ -0,0 +1,23 @@ + + + +set(statedetector_source_files + state_detector.cpp + featurematcher.cpp + state_detector_impl.cpp +) + + +add_library(statedetection SHARED ${statedetector_source_files} ) + +set_target_properties(statedetection PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSION}) + +TARGET_LINK_LIBRARIES(statedetection + ${OpenCV_LIBS} +) + + +install (FILES state_detector.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) +install (TARGETS statedetection DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) + + diff --git a/src/statedetection/state_detector.cpp b/src/statedetection/state_detector.cpp new file mode 100644 index 0000000..8c27045 --- /dev/null +++ b/src/statedetection/state_detector.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015 OpenALPR Technology, Inc. + * Open source 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 "state_detector.h" +#include "state_detector_impl.h" + +using namespace std; + +namespace alpr { + + StateDetector::StateDetector(const std::string country, const std::string runtimeDir) { + impl = new StateDetectorImpl(country, runtimeDir); + } + + StateDetector::~StateDetector() { + delete impl; + } + + bool StateDetector::isLoaded() { + return impl->isLoaded(); + } + + void StateDetector::setTopN(int topN) { + impl->setTopN(topN); + } + + vector StateDetector::detect(vector imageBytes) { + return impl->detect(imageBytes); + } + + vector StateDetector::detect(unsigned char *pixelData, int bytesPerPixel, int imgWidth, + int imgHeight) { + return impl->detect(pixelData, bytesPerPixel, imgWidth, imgHeight); + } + +} diff --git a/src/statedetection/state_detector.h b/src/statedetection/state_detector.h new file mode 100644 index 0000000..4cd29b6 --- /dev/null +++ b/src/statedetection/state_detector.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015 OpenALPR Technology, Inc. + * Open source 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 . +*/ + +#ifndef OPENALPR_STATE_DETECTOR_H +#define OPENALPR_STATE_DETECTOR_H + +#include +#include + +namespace alpr { + + struct StateCandidate + { + std::string state_code; + float confidence; + }; + + class StateDetectorImpl; + class StateDetector { + + public: + StateDetector(const std::string country, const std::string runtimeDir); + virtual ~StateDetector(); + + bool isLoaded(); + + // Maximum number of candidates to return + void setTopN(int topN); + + // Given an image of a license plate, provide the likely state candidates + std::vector detect(std::vector imageBytes); + std::vector detect(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight); + + StateDetectorImpl* impl; + }; + +} + +#endif //OPENALPR_STATE_DETECTOR_H diff --git a/src/statedetection/state_detector_impl.cpp b/src/statedetection/state_detector_impl.cpp new file mode 100644 index 0000000..e4daa66 --- /dev/null +++ b/src/statedetection/state_detector_impl.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015 OpenALPR Technology, Inc. + * Open source 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 "state_detector_impl.h" + +namespace alpr +{ + StateDetectorImpl::StateDetectorImpl(const std::string country, const std::string runtimeDir) + { + + + if (featureMatcher.isLoaded() == false) + { + std::cout << "Can not create detector or descriptor extractor or descriptor matcher of given types" << std::endl; + return; + } + + featureMatcher.loadRecognitionSet(runtimeDir, country); + } + + StateDetectorImpl::~StateDetectorImpl() { } + + bool StateDetectorImpl::isLoaded() { + return false; + } + + void StateDetectorImpl::setTopN(int topN) { + } + + std::vector StateDetectorImpl::detect(std::vector imageBytes) { + cv::Mat img = cv::imdecode(cv::Mat(imageBytes), 1); + + return this->detect(img); + } + + std::vector StateDetectorImpl::detect(unsigned char *pixelData, int bytesPerPixel, int imgWidth, + int imgHeight) { + int arraySize = imgWidth * imgHeight * bytesPerPixel; + cv::Mat imgData = cv::Mat(arraySize, 1, CV_8U, pixelData); + cv::Mat img = imgData.reshape(bytesPerPixel, imgHeight); + + return this->detect(img); + + } + + std::vector StateDetectorImpl::detect(cv::Mat image) { + std::vector results; + + + cv::Mat debugImg(image.size(), image.type()); + image.copyTo(debugImg); + std::vector matchesArray(featureMatcher.numTrainingElements()); + + RecognitionResult result = featureMatcher.recognize(image, true, &debugImg, true, matchesArray ); + + if (result.haswinner == false) + return results; + + StateCandidate top_candidate; + top_candidate.confidence = result.confidence; + top_candidate.state_code = result.winner; + + results.push_back(top_candidate); + + return results; + } +} \ No newline at end of file diff --git a/src/openalpr/stateidentifier.h b/src/statedetection/state_detector_impl.h similarity index 52% rename from src/openalpr/stateidentifier.h rename to src/statedetection/state_detector_impl.h index c7680c0..273fbcb 100644 --- a/src/openalpr/stateidentifier.h +++ b/src/statedetection/state_detector_impl.h @@ -17,38 +17,33 @@ * along with this program. If not, see . */ -#ifndef OPENALPR_STATEIDENTIFIER_H -#define OPENALPR_STATEIDENTIFIER_H +#ifndef SRC_STATE_DETECTOR_IMPL_H +#define SRC_STATE_DETECTOR_IMPL_H -#include "opencv2/imgproc/imgproc.hpp" -#include "constants.h" +#include "state_detector.h" #include "featurematcher.h" -#include "utility.h" -#include "config.h" -#include "pipeline_data.h" +#include +#include -namespace alpr -{ - - class StateIdentifier - { +namespace alpr { + class StateDetectorImpl { public: - StateIdentifier(Config* config); - virtual ~StateIdentifier(); + StateDetectorImpl(const std::string country, const std::string runtimeDir); + virtual ~StateDetectorImpl(); - bool recognize(PipelineData* pipeline_data); + bool isLoaded(); - //int confidence; + // Maximum number of candidates to return + void setTopN(int topN); - protected: - Config* config; - - private: - - FeatureMatcher* featureMatcher; + std::vector detect(std::vector imageBytes); + std::vector detect(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight); + std::vector detect(cv::Mat image); + FeatureMatcher featureMatcher; }; } -#endif // OPENALPR_STATEIDENTIFIER_H + +#endif //SRC_STATE_DETECTOR_IMPL_H From 123f3a8fbf2014011cd4d1f39445b51870b48588 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:22:39 -0400 Subject: [PATCH 34/50] Updated misc libraries to work with external state id library --- src/CMakeLists.txt | 1 + src/misc_utilities/CMakeLists.txt | 2 +- src/misc_utilities/benchmarks/benchmark.cpp | 6 +++--- src/misc_utilities/classifychars.cpp | 1 - src/misc_utilities/sortstate.cpp | 23 ++++++++------------- src/openalpr/CMakeLists.txt | 3 +-- 6 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e898647..1a777aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -134,6 +134,7 @@ add_subdirectory(tests) ENDIF() add_subdirectory(openalpr) +add_subdirectory(statedetection) add_subdirectory(video) if (WITH_BINDING_JAVA) diff --git a/src/misc_utilities/CMakeLists.txt b/src/misc_utilities/CMakeLists.txt index 969cb9d..8c904cd 100644 --- a/src/misc_utilities/CMakeLists.txt +++ b/src/misc_utilities/CMakeLists.txt @@ -23,6 +23,7 @@ ADD_EXECUTABLE(openalpr-utils-benchmark ) TARGET_LINK_LIBRARIES(openalpr-utils-benchmark ${OPENALPR_LIB} + statedetection support pthread ${OpenCV_LIBS} @@ -72,4 +73,3 @@ ENDIF() install (TARGETS openalpr-utils-prepcharsfortraining DESTINATION bin) install (TARGETS openalpr-utils-tagplates DESTINATION bin) install (TARGETS openalpr-utils-calibrate DESTINATION bin) - diff --git a/src/misc_utilities/benchmarks/benchmark.cpp b/src/misc_utilities/benchmarks/benchmark.cpp index ecde796..fa71ce2 100644 --- a/src/misc_utilities/benchmarks/benchmark.cpp +++ b/src/misc_utilities/benchmarks/benchmark.cpp @@ -167,7 +167,7 @@ int main( int argc, const char** argv ) alpr.setDetectRegion(true); Detector* plateDetector = createDetector(&config); - StateIdentifier stateIdentifier(&config); + StateDetector stateDetector(country, config.runtimeBaseDir); OCR ocr(&config); vector endToEndTimes; @@ -210,8 +210,8 @@ int main( int argc, const char** argv ) PipelineData pipeline_data(frame, regions[z].rect, &config); getTimeMonotonic(&startTime); - - stateIdentifier.recognize(&pipeline_data); + + //stateDetector.detect(&pipeline_data); getTimeMonotonic(&endTime); double stateidTime = diffclock(startTime, endTime); cout << "\tRegion " << z << ": State ID time: " << stateidTime << "ms." << endl; diff --git a/src/misc_utilities/classifychars.cpp b/src/misc_utilities/classifychars.cpp index fa0b58f..3d7e61c 100644 --- a/src/misc_utilities/classifychars.cpp +++ b/src/misc_utilities/classifychars.cpp @@ -26,7 +26,6 @@ #include "postprocess/regexrule.h" #include "licenseplatecandidate.h" -#include "stateidentifier.h" #include "utility.h" #include "support/filesystem.h" #include "ocr.h" diff --git a/src/misc_utilities/sortstate.cpp b/src/misc_utilities/sortstate.cpp index 7db2a33..d963176 100644 --- a/src/misc_utilities/sortstate.cpp +++ b/src/misc_utilities/sortstate.cpp @@ -25,7 +25,7 @@ #include #include "licenseplatecandidate.h" -#include "stateidentifier.h" +#include "../statedetection/state_detector.h" #include "utility.h" #include "support/filesystem.h" @@ -36,7 +36,7 @@ using namespace alpr; // Given a directory full of pre-cropped images, identify the state that each image belongs to. // 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); +bool detectPlate( StateDetector* identifier, Mat frame); int main( int argc, const char** argv ) { @@ -59,7 +59,7 @@ int main( int argc, const char** argv ) } Config config("us"); - StateIdentifier identifier(&config); + StateDetector identifier(config.country, config.runtimeBaseDir); if (DirectoryExists(outDir.c_str()) == false) { @@ -79,22 +79,17 @@ int main( int argc, const char** argv ) cout << fullpath << endl; frame = imread( fullpath.c_str() ); - PipelineData pipeline_data(frame, Rect(0, 0, frame.cols, frame.rows), &config); - identifier.recognize(&pipeline_data); - if (pipeline_data.region_confidence <= 20) + vector candidates = identifier.detect(frame.data, frame.elemSize(), frame.cols, frame.rows); + + if (candidates.size() > 0) { - pipeline_data.region_code = "zz"; - pipeline_data.region_confidence = 100; - } - else - { - cout << pipeline_data.region_confidence << " : " << pipeline_data.region_code; + cout << candidates[0].confidence << " : " << candidates[0].state_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 + pipeline_data.region_code + convert.str() + ".png"; + string copyCommand = "cp \"" + fullpath + "\" " + outDir + candidates[0].state_code + convert.str() + ".png"; system( copyCommand.c_str() ); waitKey(50); //while ((char) waitKey(50) != 'c') { } @@ -104,4 +99,4 @@ int main( int argc, const char** argv ) } } -bool detectPlate( StateIdentifier* identifier, Mat frame); +bool detectPlate( StateDetector* identifier, Mat frame); diff --git a/src/openalpr/CMakeLists.txt b/src/openalpr/CMakeLists.txt index 6ec14b9..e8556e6 100644 --- a/src/openalpr/CMakeLists.txt +++ b/src/openalpr/CMakeLists.txt @@ -12,8 +12,6 @@ set(lpr_source_files detection/detectormorph.cpp licenseplatecandidate.cpp utility.cpp - stateidentifier.cpp - featurematcher.cpp ocr.cpp postprocess/postprocess.cpp postprocess/regexrule.cpp @@ -51,6 +49,7 @@ set_target_properties(openalpr PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSION}) TARGET_LINK_LIBRARIES(openalpr support + statedetection ${OpenCV_LIBS} ${Tesseract_LIBRARIES} ) From 443477402ac182ead32ebbbbab80bad8b3c85d02 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:23:08 -0400 Subject: [PATCH 35/50] Added prewarp pointer to pipeline_data. Added color crop --- src/openalpr/pipeline_data.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/openalpr/pipeline_data.h b/src/openalpr/pipeline_data.h index 9a42947..4fca140 100644 --- a/src/openalpr/pipeline_data.h +++ b/src/openalpr/pipeline_data.h @@ -7,6 +7,7 @@ #include "config.h" #include "textdetection/textline.h" #include "edges/scorekeeper.h" +#include "prewarp.h" namespace alpr { @@ -25,6 +26,8 @@ namespace alpr // Inputs Config* config; + PreWarp* prewarp; + cv::Mat colorImg; cv::Mat grayImg; cv::Rect regionOfInterest; @@ -33,6 +36,8 @@ namespace alpr cv::Mat crop_gray; + cv::Mat color_deskewed; + bool hasPlateBorder; cv::Mat plateBorderMask; std::vector textLines; From 125cea00de4695602aeefb75d15b20cbcb9d6dcd Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:23:29 -0400 Subject: [PATCH 36/50] Made runtime_dir variable public --- src/openalpr/config.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/openalpr/config.h b/src/openalpr/config.h index c4524e9..1880a4e 100644 --- a/src/openalpr/config.h +++ b/src/openalpr/config.h @@ -122,12 +122,13 @@ namespace alpr std::string getPostProcessRuntimeDir(); std::string getTessdataPrefix(); + std::string runtimeBaseDir; + private: float ocrImagePercent; float stateIdImagePercent; - - std::string runtimeBaseDir; + void loadCommonValues(std::string configFile); void loadCountryValues(std::string configFile, std::string country); From ce5e2780533204ffceeb0ab43f625382598c43a5 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:23:48 -0400 Subject: [PATCH 37/50] Produce a color crop in addition to a grayscale crop of the license plate area --- src/openalpr/licenseplatecandidate.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/openalpr/licenseplatecandidate.cpp b/src/openalpr/licenseplatecandidate.cpp index a3e45b7..b8a107d 100644 --- a/src/openalpr/licenseplatecandidate.cpp +++ b/src/openalpr/licenseplatecandidate.cpp @@ -71,18 +71,30 @@ namespace alpr getTimeMonotonic(&startTime); - Mat originalCrop = pipeline_data->crop_gray; - + // Compute the transformation matrix to go from the current image to the new plate corners Transformation imgTransform(this->pipeline_data->grayImg, pipeline_data->crop_gray, expandedRegion); - - Size cropSize = imgTransform.getCropSize(pipeline_data->plate_corners, + Size cropSize = imgTransform.getCropSize(pipeline_data->plate_corners, Size(pipeline_data->config->ocrImageWidthPx, pipeline_data->config->ocrImageHeightPx)); Mat transmtx = imgTransform.getTransformationMatrix(pipeline_data->plate_corners, cropSize); - pipeline_data->crop_gray = imgTransform.crop(cropSize, transmtx); + + + // Crop the plate corners from the original color image (after un-applying prewarp) + vector projectedPoints = pipeline_data->prewarp->projectPoints(pipeline_data->plate_corners, true); + pipeline_data->color_deskewed = Mat::zeros(cropSize, pipeline_data->colorImg.type()); + std::vector deskewed_points; + deskewed_points.push_back(cv::Point2f(0,0)); + deskewed_points.push_back(cv::Point2f(pipeline_data->color_deskewed.cols,0)); + deskewed_points.push_back(cv::Point2f(pipeline_data->color_deskewed.cols,pipeline_data->color_deskewed.rows)); + deskewed_points.push_back(cv::Point2f(0,pipeline_data->color_deskewed.rows)); + cv::Mat color_transmtx = cv::getPerspectiveTransform(projectedPoints, deskewed_points); + cv::warpPerspective(pipeline_data->colorImg, pipeline_data->color_deskewed, color_transmtx, pipeline_data->color_deskewed.size()); + + // Make a grayscale copy as well for faster processing downstream + cv::cvtColor(pipeline_data->color_deskewed, pipeline_data->crop_gray, CV_BGR2GRAY); if (this->config->debugGeneral) - displayImage(config, "quadrilateral", pipeline_data->crop_gray); + displayImage(config, "quadrilateral", pipeline_data->color_deskewed); From 83e8acd8d329add292896680391515622632269b Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sun, 9 Aug 2015 19:24:45 -0400 Subject: [PATCH 38/50] Updated code to use state ID library --- src/openalpr/alpr_impl.cpp | 23 ++++++++++++++--------- src/openalpr/alpr_impl.h | 6 +++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/openalpr/alpr_impl.cpp b/src/openalpr/alpr_impl.cpp index 02975c2..042de45 100644 --- a/src/openalpr/alpr_impl.cpp +++ b/src/openalpr/alpr_impl.cpp @@ -36,7 +36,7 @@ namespace alpr config = new Config(country, configFile, runtimeDir); plateDetector = ALPR_NULL_PTR; - stateIdentifier = ALPR_NULL_PTR; + stateDetector = ALPR_NULL_PTR; ocr = ALPR_NULL_PTR; prewarp = ALPR_NULL_PTR; @@ -69,8 +69,8 @@ namespace alpr if (plateDetector != ALPR_NULL_PTR) delete plateDetector; - if (stateIdentifier != ALPR_NULL_PTR) - delete stateIdentifier; + if (stateDetector != ALPR_NULL_PTR) + delete stateDetector; if (ocr != ALPR_NULL_PTR) delete ocr; @@ -152,6 +152,7 @@ namespace alpr plateQueue.pop(); PipelineData pipeline_data(img, grayImg, plateRegion.rect, config); + pipeline_data.prewarp = prewarp; timespec platestarttime; getTimeMonotonic(&platestarttime); @@ -180,11 +181,15 @@ namespace alpr if (detectRegion) { - stateIdentifier->recognize(&pipeline_data); - if (pipeline_data.region_confidence > 0) + std::vector state_candidates = stateDetector->detect(pipeline_data.color_deskewed.data, + pipeline_data.color_deskewed.elemSize(), + pipeline_data.color_deskewed.cols, + pipeline_data.color_deskewed.rows); + + if (state_candidates.size() > 0) { - plateResult.region = pipeline_data.region_code; - plateResult.regionConfidence = (int) pipeline_data.region_confidence; + plateResult.region = state_candidates[0].state_code; + plateResult.regionConfidence = (int) state_candidates[0].confidence; } } @@ -580,12 +585,12 @@ namespace alpr { this->detectRegion = detectRegion; - if (detectRegion && this->stateIdentifier == NULL) + if (detectRegion && this->stateDetector == NULL) { timespec startTime; getTimeMonotonic(&startTime); - this->stateIdentifier = new StateIdentifier(this->config); + this->stateDetector = new StateDetector(this->config->country, this->config->runtimeBaseDir); timespec endTime; getTimeMonotonic(&endTime); diff --git a/src/openalpr/alpr_impl.h b/src/openalpr/alpr_impl.h index 776807b..6941fd1 100644 --- a/src/openalpr/alpr_impl.h +++ b/src/openalpr/alpr_impl.h @@ -35,7 +35,7 @@ #include "prewarp.h" #include "licenseplatecandidate.h" -#include "stateidentifier.h" +#include "../statedetection/state_detector.h" #include "segmentation/charactersegmenter.h" #include "ocr.h" @@ -76,7 +76,7 @@ namespace alpr AlprFullDetails recognizeFullDetails(cv::Mat img, std::vector regionsOfInterest); AlprResults recognize( std::vector imageBytes ); - AlprResults recognize( std::vector imageBytes, std::vector regionsOfInterest ); + AlprResults recognize( std::vector imageBytes, std::vector regionsOfInterest ); AlprResults recognize( unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector regionsOfInterest ); AlprResults recognize( cv::Mat img ); AlprResults recognize( cv::Mat img, std::vector regionsOfInterest ); @@ -100,7 +100,7 @@ namespace alpr private: Detector* plateDetector; - StateIdentifier* stateIdentifier; + StateDetector* stateDetector; OCR* ocr; PreWarp* prewarp; From ea255b1be35f88d9de83cf825e16eda0ac4977bf Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 10 Aug 2015 23:00:59 -0400 Subject: [PATCH 39/50] Deconstructor using correct tesseract function to close it out --- src/openalpr/ocr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openalpr/ocr.cpp b/src/openalpr/ocr.cpp index 0fda772..e05fcec 100644 --- a/src/openalpr/ocr.cpp +++ b/src/openalpr/ocr.cpp @@ -48,7 +48,7 @@ namespace alpr OCR::~OCR() { - tesseract.Clear(); + tesseract.End(); } void OCR::performOCR(PipelineData* pipeline_data) From 28aed1b7d978d4143c0e942fe1b829f846d98f28 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 10 Aug 2015 23:02:33 -0400 Subject: [PATCH 40/50] Added country config arguments for postprocess_regex_letters and postprocess_regex_numbers --- runtime_data/config/au.conf | 4 ++++ runtime_data/config/auwide.conf | 4 ++++ runtime_data/config/eu.conf | 4 ++++ runtime_data/config/kr.conf | 4 ++++ runtime_data/config/us.conf | 4 ++++ src/openalpr/config.cpp | 5 ++++- src/openalpr/config.h | 3 +++ 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/runtime_data/config/au.conf b/runtime_data/config/au.conf index 19d2bd4..d3fd4a9 100644 --- a/runtime_data/config/au.conf +++ b/runtime_data/config/au.conf @@ -30,3 +30,7 @@ min_plate_size_width_px = 85 min_plate_size_height_px = 28 ocr_language = lau + +; Override for postprocess letters/numbers regex. +postprocess_regex_letters = [A-Z] +postprocess_regex_numbers = [0-9] \ No newline at end of file diff --git a/runtime_data/config/auwide.conf b/runtime_data/config/auwide.conf index 9fdbe79..490e7b3 100644 --- a/runtime_data/config/auwide.conf +++ b/runtime_data/config/auwide.conf @@ -31,3 +31,7 @@ min_plate_size_width_px = 100 min_plate_size_height_px = 20 ocr_language = lau + +; Override for postprocess letters/numbers regex. +postprocess_regex_letters = [A-Z] +postprocess_regex_numbers = [0-9] \ No newline at end of file diff --git a/runtime_data/config/eu.conf b/runtime_data/config/eu.conf index 8d00aa5..b3d3f69 100644 --- a/runtime_data/config/eu.conf +++ b/runtime_data/config/eu.conf @@ -32,3 +32,7 @@ min_plate_size_width_px = 65 min_plate_size_height_px = 18 ocr_language = leu + +; Override for postprocess letters/numbers regex. +postprocess_regex_letters = [A-Z] +postprocess_regex_numbers = [0-9] \ No newline at end of file diff --git a/runtime_data/config/kr.conf b/runtime_data/config/kr.conf index 84b2b4d..e0ca45f 100644 --- a/runtime_data/config/kr.conf +++ b/runtime_data/config/kr.conf @@ -31,3 +31,7 @@ min_plate_size_width_px = 100 min_plate_size_height_px = 20 ocr_language = lkr + +; Override for postprocess letters/numbers regex. +postprocess_regex_letters = \pL +postprocess_regex_numbers = \pN diff --git a/runtime_data/config/us.conf b/runtime_data/config/us.conf index d311841..c9f8124 100644 --- a/runtime_data/config/us.conf +++ b/runtime_data/config/us.conf @@ -30,3 +30,7 @@ min_plate_size_width_px = 70 min_plate_size_height_px = 35 ocr_language = lus + +; Override for postprocess letters/numbers regex. +postprocess_regex_letters = [A-Z] +postprocess_regex_numbers = [0-9] \ No newline at end of file diff --git a/src/openalpr/config.cpp b/src/openalpr/config.cpp index 35c24fa..1e8c99d 100644 --- a/src/openalpr/config.cpp +++ b/src/openalpr/config.cpp @@ -243,7 +243,10 @@ namespace alpr plateLinesSensitivityHorizontal = getFloat(ini, "", "plateline_sensitivity_horizontal", 0); ocrLanguage = getString(ini, "", "ocr_language", "none"); - + + postProcessRegexLetters = getString(ini, "", "postprocess_regex_letters", "\\pL"); + postProcessRegexNumbers = getString(ini, "", "postprocess_regex_numbers", "\\pN"); + ocrImageWidthPx = round(((float) templateWidthPx) * ocrImagePercent); ocrImageHeightPx = round(((float)templateHeightPx) * ocrImagePercent); stateIdImageWidthPx = round(((float)templateWidthPx) * stateIdImagePercent); diff --git a/src/openalpr/config.h b/src/openalpr/config.h index 1880a4e..3767329 100644 --- a/src/openalpr/config.h +++ b/src/openalpr/config.h @@ -100,6 +100,9 @@ namespace alpr unsigned int postProcessMinCharacters; unsigned int postProcessMaxCharacters; + std::string postProcessRegexLetters; + std::string postProcessRegexNumbers; + bool debugGeneral; bool debugTiming; bool debugPrewarp; From 6e94703dea53a0b48312a22c57bbcc602ba72a1c Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 10 Aug 2015 23:03:22 -0400 Subject: [PATCH 41/50] Using configured regex letter/number values to build pre-compiled postprocess regexes --- src/openalpr/postprocess/postprocess.cpp | 2 +- src/openalpr/postprocess/regexrule.cpp | 6 +++--- src/openalpr/postprocess/regexrule.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openalpr/postprocess/postprocess.cpp b/src/openalpr/postprocess/postprocess.cpp index dcdf043..3d7bc5b 100644 --- a/src/openalpr/postprocess/postprocess.cpp +++ b/src/openalpr/postprocess/postprocess.cpp @@ -36,7 +36,7 @@ namespace alpr string region, pattern; while (infile >> region >> pattern) { - RegexRule* rule = new RegexRule(region, pattern); + RegexRule* rule = new RegexRule(region, pattern, config->postProcessRegexLetters, config->postProcessRegexNumbers); //cout << "REGION: " << region << " PATTERN: " << pattern << endl; if (rules.find(region) == rules.end()) diff --git a/src/openalpr/postprocess/regexrule.cpp b/src/openalpr/postprocess/regexrule.cpp index 57bd619..aa8226e 100644 --- a/src/openalpr/postprocess/regexrule.cpp +++ b/src/openalpr/postprocess/regexrule.cpp @@ -28,7 +28,7 @@ tthread::mutex regexrule_mutex_m; namespace alpr { - RegexRule::RegexRule(string region, string pattern) + RegexRule::RegexRule(string region, string pattern, std::string letters_regex, std::string numbers_regex) //: re2_regex("") { this->original = pattern; @@ -80,11 +80,11 @@ namespace alpr } else if (utf_character == "@") { - regexval << "\\pL"; + regexval << letters_regex; } else if (utf_character == "#") { - regexval << "\\pN"; + regexval << numbers_regex; } else if ((utf_character == "*") || (utf_character == "+")) { diff --git a/src/openalpr/postprocess/regexrule.h b/src/openalpr/postprocess/regexrule.h index d071f61..d369a92 100644 --- a/src/openalpr/postprocess/regexrule.h +++ b/src/openalpr/postprocess/regexrule.h @@ -33,7 +33,7 @@ namespace alpr class RegexRule { public: - RegexRule(std::string region, std::string pattern); + RegexRule(std::string region, std::string pattern, std::string letters_regex, std::string numbers_regex); virtual ~RegexRule(); bool match(std::string text); From 228af9b29065e7117955faf10c65d82556aa290d Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 10 Aug 2015 23:08:40 -0400 Subject: [PATCH 42/50] Fixed compile error in classifychars --- src/misc_utilities/classifychars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc_utilities/classifychars.cpp b/src/misc_utilities/classifychars.cpp index 3d7e61c..f9a3cbd 100644 --- a/src/misc_utilities/classifychars.cpp +++ b/src/misc_utilities/classifychars.cpp @@ -323,7 +323,7 @@ vector showCharSelection(Mat image, vector charRegions, string sta for (int i = 0; i < charRegions.size(); i++) humanInputs[i] = SPACE; - RegexRule regex_rule("", "[\\pL\\pN]"); + RegexRule regex_rule("", "[\\pL\\pN]", "", ""); int16_t waitkey = waitKey(50); while (waitkey != ENTER_KEY && waitkey != ESCAPE_KEY) From 39525717d815f9618893671e45af45c4889f97b9 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 10 Aug 2015 23:08:48 -0400 Subject: [PATCH 43/50] updated regex unit tests --- src/tests/test_regex.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tests/test_regex.cpp b/src/tests/test_regex.cpp index 1c516dc..fe76582 100644 --- a/src/tests/test_regex.cpp +++ b/src/tests/test_regex.cpp @@ -11,7 +11,7 @@ using namespace alpr; TEST_CASE( "ASCII tests", "[Regex]" ) { - RegexRule rule1("us", "@@@####"); + RegexRule rule1("us", "@@@####", "[A-Za-z]", "[0-9]"); REQUIRE( rule1.match("123ABCD") == false); REQUIRE( rule1.match("123ABC") == false); @@ -28,7 +28,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) { REQUIRE( rule1.match("AAA1111") == true); REQUIRE( rule1.match("zzz1111") == true); - RegexRule rule2("us", "[ABC]@@####"); + RegexRule rule2("us", "[ABC]@@####", "[A-Z]", "[0-9]"); REQUIRE( rule2.match("ZBC1234") == false); REQUIRE( rule2.match("DBC1234") == false); @@ -38,7 +38,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) { REQUIRE( rule2.match("BAA1111") == true); REQUIRE( rule2.match("CAA1111") == true); - RegexRule rule3("us", "[A]@@###[12]"); + RegexRule rule3("us", "[A]@@###[12]", "[A-Z]", "[0-9]"); REQUIRE( rule3.match("ZBC1234") == false); REQUIRE( rule3.match("ZBC1231") == false); @@ -48,7 +48,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) { REQUIRE( rule3.match("ABC1232") == true); - RegexRule rule4("us", "[A-C][E-G]1111"); + RegexRule rule4("us", "[A-C][E-G]1111", "[A-Z]", "[0-9]"); REQUIRE( rule4.match("DG1111") == false); REQUIRE( rule4.match("AD1111") == false); @@ -61,7 +61,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) { REQUIRE( rule4.match("BF1111") == true); REQUIRE( rule4.match("BG1111") == true); - RegexRule rule5("us", "\\d\\d\\D\\D"); + RegexRule rule5("us", "\\d\\d\\D\\D", "[A-Z]", "[0-9]"); REQUIRE( rule5.match("AA11") == false); REQUIRE( rule5.match("11AA") == true); @@ -69,7 +69,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) { TEST_CASE( "Unicode tests", "[Regex]" ) { - RegexRule rule1("us", "@@@####"); + RegexRule rule1("us", "@@@####", "\\pL", "\\pN"); REQUIRE( rule1.match("123与与与下") == false); REQUIRE( rule1.match("与万12345") == false); @@ -78,7 +78,7 @@ TEST_CASE( "Unicode tests", "[Regex]" ) { REQUIRE( rule1.match("与万口1234") == true); - RegexRule rule2("us", "[십팔]@@####"); + RegexRule rule2("us", "[십팔]@@####", "\\pL", "\\pN"); REQUIRE( rule2.match("123与与与下") == false); REQUIRE( rule2.match("与万12345") == false); @@ -93,7 +93,7 @@ TEST_CASE( "Unicode tests", "[Regex]" ) { TEST_CASE( "Invalid tests", "[Regex]" ) { - RegexRule rule1("us", "[A@@####"); + RegexRule rule1("us", "[A@@####", "\\pL", "\\pN"); REQUIRE( rule1.match("123ABCD") == false); REQUIRE( rule1.match("123ABC") == false); @@ -103,6 +103,6 @@ TEST_CASE( "Invalid tests", "[Regex]" ) { REQUIRE( rule1.match("AAA1111") == false); REQUIRE( rule1.match("zzz1111") == false); - RegexRule rule2("us", "A####]"); + RegexRule rule2("us", "A####]", "\\pL", "\\pN"); REQUIRE( rule2.match("A1234") == false); } \ No newline at end of file From b145da1e85196737001b5f366d3063b2e3c968ad Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Mon, 10 Aug 2015 23:20:37 -0400 Subject: [PATCH 44/50] Fixes issue #174 --- src/openalpr/alpr_impl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/openalpr/alpr_impl.cpp b/src/openalpr/alpr_impl.cpp index 042de45..85bf805 100644 --- a/src/openalpr/alpr_impl.cpp +++ b/src/openalpr/alpr_impl.cpp @@ -97,6 +97,10 @@ namespace alpr response.results.img_width = img.cols; response.results.img_height = img.rows; + // Fix regions of interest in case they extend beyond the bounds of the image + for (unsigned int i = 0; i < regionsOfInterest.size(); i++) + regionsOfInterest[i] = expandRect(regionsOfInterest[i], 0, 0, img.cols, img.rows); + for (unsigned int i = 0; i < regionsOfInterest.size(); i++) { response.results.regionsOfInterest.push_back(AlprRegionOfInterest(regionsOfInterest[i].x, regionsOfInterest[i].y, From 8af1b19a1a100e39e733885714bc29d721fcd3f4 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Tue, 11 Aug 2015 09:54:01 +0200 Subject: [PATCH 45/50] Link statedetection statically on Windows. --- src/statedetection/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/statedetection/CMakeLists.txt b/src/statedetection/CMakeLists.txt index 3c15c6d..f65e7a9 100644 --- a/src/statedetection/CMakeLists.txt +++ b/src/statedetection/CMakeLists.txt @@ -7,8 +7,11 @@ set(statedetector_source_files state_detector_impl.cpp ) - -add_library(statedetection SHARED ${statedetector_source_files} ) +if (WIN32) + add_library(statedetection STATIC ${statedetector_source_files} ) +ELSE() + add_library(statedetection SHARED ${statedetector_source_files} ) +ENDIF() set_target_properties(statedetection PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSION}) From 063d0bda6a071fce81785498b68481585a7603de Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Tue, 11 Aug 2015 09:54:19 +0200 Subject: [PATCH 46/50] Link with support. --- src/statedetection/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/statedetection/CMakeLists.txt b/src/statedetection/CMakeLists.txt index f65e7a9..405f8af 100644 --- a/src/statedetection/CMakeLists.txt +++ b/src/statedetection/CMakeLists.txt @@ -17,6 +17,7 @@ set_target_properties(statedetection PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSI TARGET_LINK_LIBRARIES(statedetection ${OpenCV_LIBS} + support ) From 0cf100b6224c0647aedebb63b3b772af8520a4b5 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Tue, 11 Aug 2015 09:54:39 +0200 Subject: [PATCH 47/50] Link with statedetection. --- src/CMakeLists.txt | 1 + src/misc_utilities/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a777aa..2a89c54 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,6 +101,7 @@ ENDIF() TARGET_LINK_LIBRARIES(alpr ${OPENALPR_LIB} + statedetection support video ${OpenCV_LIBS} diff --git a/src/misc_utilities/CMakeLists.txt b/src/misc_utilities/CMakeLists.txt index 8c904cd..7232c4d 100644 --- a/src/misc_utilities/CMakeLists.txt +++ b/src/misc_utilities/CMakeLists.txt @@ -2,6 +2,7 @@ ADD_EXECUTABLE( openalpr-utils-sortstate sortstate.cpp ) TARGET_LINK_LIBRARIES(openalpr-utils-sortstate ${OPENALPR_LIB} + statedetection support ${OpenCV_LIBS} ${Tesseract_LIBRARIES} From df2c1a34887bd1e26ef284eef0d3722b88c5ab72 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Tue, 11 Aug 2015 09:55:06 +0200 Subject: [PATCH 48/50] Link .NET binding with statedetection. --- src/bindings/csharp/openalpr-net/openalpr-net.vcxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj index 3e733e9..419977b 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj +++ b/src/bindings/csharp/openalpr-net/openalpr-net.vcxproj @@ -106,7 +106,7 @@ true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib;$(OpenALPRDistDir)\statedetection.lib @@ -119,7 +119,7 @@ true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib;$(OpenALPRDistDir)\statedetection.lib @@ -131,7 +131,7 @@ true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib;$(OpenALPRDistDir)\statedetection.lib @@ -143,7 +143,7 @@ true - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;$(OpenALPRDistDir)\opencv_videostab$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ts$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_stitching$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_contrib$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\libtesseract$(TesseractVersion)-static$(TesseractDebugPrefix).lib;$(OpenALPRDistDir)\liblept$(LeptonicaVersion)$(DebugPrefix).lib;ws2_32.lib;$(OpenALPRDistDir)\opencv_nonfree$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_gpu$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_photo$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_objdetect$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_legacy$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_video$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_ml$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_calib3d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_features2d$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_highgui$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_imgproc$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_flann$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\opencv_core$(OpenCVVersion)$(DebugPrefix).lib;$(OpenALPRDistDir)\support.lib;$(OpenALPRDistDir)\openalpr-static.lib;$(OpenALPRDistDir)\statedetection.lib From 68bc2e4dbbfc8c0b68ccf09d30dddd28ab1810db Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Tue, 11 Aug 2015 12:05:33 +0200 Subject: [PATCH 49/50] Add method for prewarping an image from raw pixel data. --- .../csharp/openalpr-net/openalpr-net.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.cpp b/src/bindings/csharp/openalpr-net/openalpr-net.cpp index a691f20..d1519c9 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.cpp +++ b/src/bindings/csharp/openalpr-net/openalpr-net.cpp @@ -452,6 +452,32 @@ namespace openalprnet { return gcnew AlprResultsNet(results); } + /// + /// Pre-warp from raw pixel data. + /// + array^ PreWarp(array^ imageBuffer) + { + std::vector buffer = AlprHelper::ToVector(imageBuffer); + cv::Mat src = cv::imdecode(buffer, 1); + + alpr::PreWarp *preWarp = new alpr::PreWarp(m_Impl->getConfig()); + cv::Mat warpedImage = preWarp->warpImage(src); + + std::vector warpedImageVector; + cv::imencode(".jpg", warpedImage, warpedImageVector); + + const size_t warpedImageSize = warpedImageVector.size(); + + array^ warpedImageByteArray = gcnew array(warpedImageSize); + pin_ptr pin(&warpedImageByteArray[0]); + + std::memcpy(pin, &warpedImageVector[0], warpedImageSize); + + delete preWarp; + + return warpedImageByteArray; + } + bool IsLoaded() { return m_Impl->isLoaded(); } From 59577d059fcb6d98321fcb641e6aee9cf4be54d0 Mon Sep 17 00:00:00 2001 From: Peter Rekdal Sunde Date: Tue, 11 Aug 2015 12:18:29 +0200 Subject: [PATCH 50/50] Add missing include. --- src/bindings/csharp/openalpr-net/openalpr-net.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bindings/csharp/openalpr-net/openalpr-net.h b/src/bindings/csharp/openalpr-net/openalpr-net.h index 52ec33e..ca26c5e 100644 --- a/src/bindings/csharp/openalpr-net/openalpr-net.h +++ b/src/bindings/csharp/openalpr-net/openalpr-net.h @@ -1,6 +1,7 @@ #pragma once #include "alpr.h" +#include "prewarp.h" #include #include