mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 06:16:56 +08:00
Merge branch 'master' of https://github.com/openalpr/openalpr
Conflicts: src/openalpr/support/re2/util/strutil.cc
This commit is contained in:
@@ -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.
|
||||
|
||||
|
1
distros/debian/python-openalpr.install
Normal file
1
distros/debian/python-openalpr.install
Normal file
@@ -0,0 +1 @@
|
||||
usr/lib/python2.7/dist-packages/openalpr
|
@@ -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]
|
@@ -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]
|
@@ -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]
|
@@ -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
|
||||
|
@@ -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]
|
@@ -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 @@####
|
||||
|
@@ -203,6 +203,8 @@ va ####@@
|
||||
va #####[JY]
|
||||
wa ###@@@
|
||||
wa @@@####
|
||||
wi ###@@@
|
||||
wi @@@###
|
||||
wv [1-9DON]@@###
|
||||
wv [1-9DON]@####
|
||||
wy ######
|
||||
|
@@ -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)
|
||||
|
@@ -38,5 +38,3 @@ using namespace System::Security::Permissions;
|
||||
[assembly:ComVisible(false)];
|
||||
|
||||
[assembly:CLSCompliantAttribute(true)];
|
||||
|
||||
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
|
||||
|
@@ -65,7 +65,7 @@ namespace openalprnet {
|
||||
channels = 4;
|
||||
break;
|
||||
default:
|
||||
throw gcnew NotImplementedException();
|
||||
throw gcnew NotSupportedException(bitmap->PixelFormat.ToString());
|
||||
}
|
||||
|
||||
BitmapData^ bitmapData = bitmap->LockBits(
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "alpr.h"
|
||||
#include "prewarp.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@@ -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>
|
||||
|
@@ -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
|
||||
)
|
||||
|
1
src/bindings/python/openalpr/__init__.py
Normal file
1
src/bindings/python/openalpr/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from openalpr import Alpr
|
@@ -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)
|
||||
|
||||
|
@@ -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();
|
||||
|
||||
|
12
src/bindings/python/setup.py
Normal file
12
src/bindings/python/setup.py
Normal 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']
|
||||
)
|
@@ -54,4 +54,4 @@ try:
|
||||
|
||||
finally:
|
||||
if alpr:
|
||||
alpr.unload()
|
||||
alpr.unload()
|
||||
|
@@ -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()))
|
||||
{
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
@@ -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}
|
||||
)
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
|
||||
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 == "+"))
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#ifndef OPENALPR_PLATFORM_H
|
||||
#define OPENALPR_PLATFORM_H
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
27
src/statedetection/CMakeLists.txt
Normal file
27
src/statedetection/CMakeLists.txt
Normal 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)
|
||||
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
};
|
||||
|
||||
}
|
52
src/statedetection/state_detector.cpp
Normal file
52
src/statedetection/state_detector.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
55
src/statedetection/state_detector.h
Normal file
55
src/statedetection/state_detector.h
Normal 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
|
83
src/statedetection/state_detector_impl.cpp
Normal file
83
src/statedetection/state_detector_impl.cpp
Normal 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;
|
||||
}
|
||||
}
|
@@ -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
|
@@ -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);
|
||||
}
|
Reference in New Issue
Block a user