Conflicts:
	src/openalpr/support/re2/util/strutil.cc
This commit is contained in:
Matt Hill
2015-08-12 09:09:51 -04:00
55 changed files with 525 additions and 282 deletions

View File

@@ -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: python
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.

View File

@@ -0,0 +1 @@
usr/lib/python2.7/dist-packages/openalpr

View File

@@ -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]

View File

@@ -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]

View File

@@ -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]

View File

@@ -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
@@ -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

View File

@@ -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]

View File

@@ -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 @@####

View File

@@ -203,6 +203,8 @@ va ####@@
va #####[JY]
wa ###@@@
wa @@@####
wi ###@@@
wi @@@###
wv [1-9DON]@@###
wv [1-9DON]@####
wy ######

View File

@@ -101,6 +101,7 @@ ENDIF()
TARGET_LINK_LIBRARIES(alpr
${OPENALPR_LIB}
statedetection
support
video
${OpenCV_LIBS}
@@ -134,6 +135,7 @@ add_subdirectory(tests)
ENDIF()
add_subdirectory(openalpr)
add_subdirectory(statedetection)
add_subdirectory(video)
if (WITH_BINDING_JAVA)

View File

@@ -38,5 +38,3 @@ using namespace System::Security::Permissions;
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];

View File

@@ -65,7 +65,7 @@ namespace openalprnet {
channels = 4;
break;
default:
throw gcnew NotImplementedException();
throw gcnew NotSupportedException(bitmap->PixelFormat.ToString());
}
BitmapData^ bitmapData = bitmap->LockBits(

View File

@@ -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();

View File

@@ -326,7 +326,7 @@ namespace openalprnet {
event EventHandler<AlprFrameEventArgs^>^ 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();
@@ -409,8 +409,9 @@ namespace openalprnet {
/// </summary>
AlprResultsNet^ Recognize(MemoryStream^ memoryStream, List<System::Drawing::Rectangle>^ regionsOfInterest)
{
std::vector<char> p = AlprHelper::MemoryStreamToVector(memoryStream);
AlprResults results = m_Impl->recognize(p);
std::vector<char> buffer = AlprHelper::MemoryStreamToVector(memoryStream);
std::vector<AlprRegionOfInterest> rois = AlprHelper::ToVector(regionsOfInterest);
AlprResults results = m_Impl->recognize(buffer, rois);
return gcnew AlprResultsNet(results);
}
@@ -427,8 +428,9 @@ namespace openalprnet {
/// </summary>
/// <param name="imageBuffer">Bytes representing image data</param>
AlprResultsNet^ Recognize(cli::array<Byte>^ imageBuffer, List<System::Drawing::Rectangle>^ regionsOfInterest) {
std::vector<char> p = AlprHelper::ToVector(imageBuffer);
AlprResults results = m_Impl->recognize(p);
std::vector<char> buffer = AlprHelper::ToVector(imageBuffer);
std::vector<AlprRegionOfInterest> rois = AlprHelper::ToVector(regionsOfInterest);
AlprResults results = m_Impl->recognize(buffer, rois);
return gcnew AlprResultsNet(results);
}
@@ -450,6 +452,32 @@ namespace openalprnet {
return gcnew AlprResultsNet(results);
}
/// <summary>
/// Pre-warp from raw pixel data.
/// </summary>
array<Byte>^ PreWarp(array<Byte>^ imageBuffer)
{
std::vector<char> 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<uchar> warpedImageVector;
cv::imencode(".jpg", warpedImage, warpedImageVector);
const size_t warpedImageSize = warpedImageVector.size();
array<Byte>^ warpedImageByteArray = gcnew array<Byte>(warpedImageSize);
pin_ptr<Byte> pin(&warpedImageByteArray[0]);
std::memcpy(pin, &warpedImageVector[0], warpedImageSize);
delete preWarp;
return warpedImageByteArray;
}
bool IsLoaded() {
return m_Impl->isLoaded();
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "alpr.h"
#include "prewarp.h"
#include <stdlib.h>
#include <string.h>

View File

@@ -25,6 +25,7 @@
<RootNamespace>openalprnet</RootNamespace>
<OpenALPRVersion>2.1.0</OpenALPRVersion>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset Condition="$(VisualStudioVersion)=='14.0'">v140</PlatformToolset>
<OpenALPRWindowsDir>..\..\..\..\windows</OpenALPRWindowsDir>
<CudaGeneration Condition="$(CudaGeneration)=='' OR $(CudaGeneration)=='None'">None</CudaGeneration>
<OpenALPRDistDir Condition="$(CudaGeneration)=='None'">$(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)</OpenALPRDistDir>
@@ -105,7 +106,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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</AdditionalDependencies>
<AdditionalDependencies>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</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -118,7 +119,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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</AdditionalDependencies>
<AdditionalDependencies>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</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -130,7 +131,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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</AdditionalDependencies>
<AdditionalDependencies>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</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -142,7 +143,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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</AdditionalDependencies>
<AdditionalDependencies>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</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -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)
install (TARGETS openalprpy DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install (DIRECTORY openalpr DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python2.7/dist-packages
USE_SOURCE_PERMISSIONS
)

View File

@@ -0,0 +1 @@
from openalpr import Alpr

View File

@@ -13,48 +13,52 @@ class Alpr():
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)

View File

@@ -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<char> 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();

View File

@@ -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']
)

View File

@@ -54,4 +54,4 @@ try:
finally:
if alpr:
alpr.unload()
alpr.unload()

View File

@@ -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()))
{

View File

@@ -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}
@@ -23,6 +24,7 @@ ADD_EXECUTABLE(openalpr-utils-benchmark
)
TARGET_LINK_LIBRARIES(openalpr-utils-benchmark
${OPENALPR_LIB}
statedetection
support
pthread
${OpenCV_LIBS}
@@ -72,4 +74,3 @@ ENDIF()
install (TARGETS openalpr-utils-prepcharsfortraining DESTINATION bin)
install (TARGETS openalpr-utils-tagplates DESTINATION bin)
install (TARGETS openalpr-utils-calibrate DESTINATION bin)

View File

@@ -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<double> 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;

View File

@@ -26,7 +26,6 @@
#include "postprocess/regexrule.h"
#include "licenseplatecandidate.h"
#include "stateidentifier.h"
#include "utility.h"
#include "support/filesystem.h"
#include "ocr.h"
@@ -324,7 +323,7 @@ vector<string> showCharSelection(Mat image, vector<Rect> 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)

View File

@@ -25,7 +25,7 @@
#include <sys/stat.h>
#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<StateCandidate> 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);

View File

@@ -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}
)

View File

@@ -68,6 +68,11 @@ namespace alpr
return impl->recognize(imageBytes);
}
AlprResults Alpr::recognize(std::vector<char> imageBytes, std::vector<AlprRegionOfInterest> regionsOfInterest)
{
return impl->recognize(imageBytes, regionsOfInterest);
}
AlprResults Alpr::recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest)
{
return impl->recognize(pixelData, bytesPerPixel, imgWidth, imgHeight, regionsOfInterest);

View File

@@ -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<char> imageBytes);
// Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).
AlprResults recognize(std::vector<char> imageBytes);
// Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).
AlprResults recognize(std::vector<char> imageBytes, std::vector<AlprRegionOfInterest> regionsOfInterest);
// Recognize from raw pixel data.
AlprResults recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest);

View File

@@ -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;
@@ -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,
@@ -152,6 +156,7 @@ namespace alpr
plateQueue.pop();
PipelineData pipeline_data(img, grayImg, plateRegion.rect, config);
pipeline_data.prewarp = prewarp;
timespec platestarttime;
getTimeMonotonic(&platestarttime);
@@ -180,11 +185,15 @@ namespace alpr
if (detectRegion)
{
stateIdentifier->recognize(&pipeline_data);
if (pipeline_data.region_confidence > 0)
std::vector<StateCandidate> 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;
}
}
@@ -345,6 +354,16 @@ namespace alpr
return this->recognize(img);
}
AlprResults AlprImpl::recognize(std::vector<char> imageBytes, std::vector<AlprRegionOfInterest> regionsOfInterest)
{
cv::Mat img = cv::imdecode(cv::Mat(imageBytes), 1);
std::vector<cv::Rect> 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<AlprRegionOfInterest> regionsOfInterest)
{
@@ -570,12 +589,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);

View File

@@ -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,6 +76,7 @@ namespace alpr
AlprFullDetails recognizeFullDetails(cv::Mat img, std::vector<cv::Rect> regionsOfInterest);
AlprResults recognize( std::vector<char> imageBytes );
AlprResults recognize( std::vector<char> imageBytes, std::vector<AlprRegionOfInterest> regionsOfInterest );
AlprResults recognize( unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest );
AlprResults recognize( cv::Mat img );
AlprResults recognize( cv::Mat img, std::vector<cv::Rect> regionsOfInterest );
@@ -99,7 +100,7 @@ namespace alpr
private:
Detector* plateDetector;
StateIdentifier* stateIdentifier;
StateDetector* stateDetector;
OCR* ocr;
PreWarp* prewarp;

View File

@@ -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);

View File

@@ -100,6 +100,9 @@ namespace alpr
unsigned int postProcessMinCharacters;
unsigned int postProcessMaxCharacters;
std::string postProcessRegexLetters;
std::string postProcessRegexNumbers;
bool debugGeneral;
bool debugTiming;
bool debugPrewarp;
@@ -122,12 +125,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);

View File

@@ -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;
}
}

View File

@@ -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<Point2f> projectedPoints = pipeline_data->prewarp->projectPoints(pipeline_data->plate_corners, true);
pipeline_data->color_deskewed = Mat::zeros(cropSize, pipeline_data->colorImg.type());
std::vector<cv::Point2f> 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);

View File

@@ -42,12 +42,13 @@ 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);
}
OCR::~OCR()
{
tesseract.Clear();
tesseract.End();
}
void OCR::performOCR(PipelineData* pipeline_data)

View File

@@ -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<TextLine> textLines;

View File

@@ -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())
@@ -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)
@@ -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 )
{

View File

@@ -53,7 +53,6 @@ namespace alpr
std::vector<Letter> 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<int> letterIndices, std::string templateregion, int topn);

View File

@@ -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 == "+"))
{

View File

@@ -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);

View File

@@ -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);
@@ -260,7 +259,7 @@ namespace alpr
vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> 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.

View File

@@ -74,7 +74,6 @@ namespace alpr
void cleanCharRegions(std::vector<cv::Mat> thresholds, std::vector<cv::Rect> charRegions);
void cleanBasedOnColor(std::vector<cv::Mat> thresholds, cv::Mat colorMask, std::vector<cv::Rect> charRegions);
void cleanMostlyFullBoxes(std::vector<cv::Mat> thresholds, const std::vector<cv::Rect> charRegions);
std::vector<cv::Rect> filterMostlyEmptyBoxes(std::vector<cv::Mat> thresholds, const std::vector<cv::Rect> charRegions);
void filterEdgeBoxes(std::vector<cv::Mat> thresholds, const std::vector<cv::Rect> charRegions, float avgCharWidth, float avgCharHeight);

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<int> matchesArray(featureMatcher->numTrainingElements());
RecognitionResult result = featureMatcher->recognize(plateImg, true, &debugImg, true, matchesArray );
if (this->config->debugStateId)
{
displayImage(config, "State Identifier1", plateImg);
displayImage(config, "State Identifier", debugImg);
cout << result.haswinner << " : " << result.confidence << " : " << result.winner << endl;
}
if (config->debugTiming)
{
timespec endTime;
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;
}
}

View File

@@ -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;

View File

@@ -1,7 +1,7 @@
#ifndef OPENALPR_PLATFORM_H
#define OPENALPR_PLATFORM_H
#include <string>
#include <string.h>
#include <sstream>
#ifdef WINDOWS

View File

@@ -0,0 +1,27 @@
set(statedetector_source_files
state_detector.cpp
featurematcher.cpp
state_detector_impl.cpp
)
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})
TARGET_LINK_LIBRARIES(statedetection
${OpenCV_LIBS}
support
)
install (FILES state_detector.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install (TARGETS statedetection DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)

View File

@@ -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<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches)
{
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
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;
}

View File

@@ -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<int> 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<cv::DescriptorMatcher> descriptorMatcher;
cv::Ptr<cv::FastFeatureDetector> detector;
@@ -74,6 +73,9 @@ namespace alpr
void surfStyleMatching( const cv::Mat& queryDescriptors, std::vector<cv::KeyPoint> queryKeypoints,
std::vector<cv::DMatch>& matches12 );
int w;
int h;
};
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<StateCandidate> StateDetector::detect(vector<char> imageBytes) {
return impl->detect(imageBytes);
}
vector<StateCandidate> StateDetector::detect(unsigned char *pixelData, int bytesPerPixel, int imgWidth,
int imgHeight) {
return impl->detect(pixelData, bytesPerPixel, imgWidth, imgHeight);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef OPENALPR_STATE_DETECTOR_H
#define OPENALPR_STATE_DETECTOR_H
#include <string>
#include <vector>
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<StateCandidate> detect(std::vector<char> imageBytes);
std::vector<StateCandidate> detect(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight);
StateDetectorImpl* impl;
};
}
#endif //OPENALPR_STATE_DETECTOR_H

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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<StateCandidate> StateDetectorImpl::detect(std::vector<char> imageBytes) {
cv::Mat img = cv::imdecode(cv::Mat(imageBytes), 1);
return this->detect(img);
}
std::vector<StateCandidate> 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<StateCandidate> StateDetectorImpl::detect(cv::Mat image) {
std::vector<StateCandidate> results;
cv::Mat debugImg(image.size(), image.type());
image.copyTo(debugImg);
std::vector<int> 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;
}
}

View File

@@ -17,38 +17,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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 <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
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<StateCandidate> detect(std::vector<char> imageBytes);
std::vector<StateCandidate> detect(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight);
std::vector<StateCandidate> detect(cv::Mat image);
FeatureMatcher featureMatcher;
};
}
#endif // OPENALPR_STATEIDENTIFIER_H
#endif //SRC_STATE_DETECTOR_IMPL_H

View File

@@ -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);
}