mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 13:46:52 +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
|
OpenALPR is an open source Automatic License Plate Recognition library written
|
||||||
in C++. The library analyzes images and identifies license plates. The output
|
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.
|
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
|
min_plate_size_height_px = 28
|
||||||
|
|
||||||
ocr_language = lau
|
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
|
min_plate_size_height_px = 20
|
||||||
|
|
||||||
ocr_language = lau
|
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
|
min_plate_size_height_px = 18
|
||||||
|
|
||||||
ocr_language = leu
|
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_step_size = 0.10
|
||||||
char_analysis_height_num_steps = 5
|
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_min_charheight_percent = 0.4;
|
||||||
segmentation_max_segment_width_percent_vs_average = 2.0;
|
segmentation_max_segment_width_percent_vs_average = 2.0;
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ plate_height_mm = 110
|
|||||||
multiline = 0
|
multiline = 0
|
||||||
|
|
||||||
char_height_mm = 80
|
char_height_mm = 80
|
||||||
char_width_mm = 53
|
char_width_mm = 43
|
||||||
char_whitespace_top_mm = 10
|
char_whitespace_top_mm = 10
|
||||||
char_whitespace_bot_mm = 10
|
char_whitespace_bot_mm = 10
|
||||||
|
|
||||||
@@ -31,3 +31,7 @@ min_plate_size_width_px = 100
|
|||||||
min_plate_size_height_px = 20
|
min_plate_size_height_px = 20
|
||||||
|
|
||||||
ocr_language = lkr
|
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
|
min_plate_size_height_px = 35
|
||||||
|
|
||||||
ocr_language = lus
|
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 @@@####
|
gr @@@####
|
||||||
hu @@@###
|
hu @@@###
|
||||||
is @@@##
|
is @@@##
|
||||||
ie [12]##@######
|
ie ##[12][CDGLTW]######
|
||||||
ie [12]##@@######
|
ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]######
|
||||||
ie [12]##@#####
|
ie ##[12][CDGLTW]#####
|
||||||
ie [12]##@@#####
|
ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]#####
|
||||||
ie [12]##@####
|
ie ##[12][CDGLTW]####
|
||||||
ie [12]##@@####
|
ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]####
|
||||||
ie [12]##@###
|
ie ##[12][CDGLTW]###
|
||||||
ie [12]##@@###
|
ie ##[12][CDGKLMORSTW][DEHKLMNOSWXY]###
|
||||||
ie ##@######
|
ie ##[CDGLTW]######
|
||||||
ie ##@@######
|
ie ##[CDGKLMORSTW][DEHKLMNOSWXY]######
|
||||||
ie ##@#####
|
ie ##[CDGLTW]#####
|
||||||
ie ##@@#####
|
ie ##[CDGKLMORSTW][DEHKLMNOSWXY]#####
|
||||||
ie ##@####
|
ie ##[CDGLTW]####
|
||||||
ie ##@@####
|
ie ##[CDGKLMORSTW][DEHKLMNOSWXY]####
|
||||||
ie ##@###
|
ie ##[CDGLTW]###
|
||||||
ie ##@@###
|
ie ##[CDGKLMORSTW][DEHKLMNOSWXY]###
|
||||||
it @@###@@
|
it @@###@@
|
||||||
kz ###@@@
|
kz ###@@@
|
||||||
lv @@####
|
lv @@####
|
||||||
|
@@ -203,6 +203,8 @@ va ####@@
|
|||||||
va #####[JY]
|
va #####[JY]
|
||||||
wa ###@@@
|
wa ###@@@
|
||||||
wa @@@####
|
wa @@@####
|
||||||
|
wi ###@@@
|
||||||
|
wi @@@###
|
||||||
wv [1-9DON]@@###
|
wv [1-9DON]@@###
|
||||||
wv [1-9DON]@####
|
wv [1-9DON]@####
|
||||||
wy ######
|
wy ######
|
||||||
|
@@ -101,6 +101,7 @@ ENDIF()
|
|||||||
|
|
||||||
TARGET_LINK_LIBRARIES(alpr
|
TARGET_LINK_LIBRARIES(alpr
|
||||||
${OPENALPR_LIB}
|
${OPENALPR_LIB}
|
||||||
|
statedetection
|
||||||
support
|
support
|
||||||
video
|
video
|
||||||
${OpenCV_LIBS}
|
${OpenCV_LIBS}
|
||||||
@@ -134,6 +135,7 @@ add_subdirectory(tests)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
add_subdirectory(openalpr)
|
add_subdirectory(openalpr)
|
||||||
|
add_subdirectory(statedetection)
|
||||||
add_subdirectory(video)
|
add_subdirectory(video)
|
||||||
|
|
||||||
if (WITH_BINDING_JAVA)
|
if (WITH_BINDING_JAVA)
|
||||||
|
@@ -38,5 +38,3 @@ using namespace System::Security::Permissions;
|
|||||||
[assembly:ComVisible(false)];
|
[assembly:ComVisible(false)];
|
||||||
|
|
||||||
[assembly:CLSCompliantAttribute(true)];
|
[assembly:CLSCompliantAttribute(true)];
|
||||||
|
|
||||||
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
|
|
||||||
|
@@ -65,7 +65,7 @@ namespace openalprnet {
|
|||||||
channels = 4;
|
channels = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw gcnew NotImplementedException();
|
throw gcnew NotSupportedException(bitmap->PixelFormat.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapData^ bitmapData = bitmap->LockBits(
|
BitmapData^ bitmapData = bitmap->LockBits(
|
||||||
|
@@ -50,6 +50,11 @@ namespace openalprnet
|
|||||||
|
|
||||||
static Bitmap^ MatToBitmap(cv::Mat mat)
|
static Bitmap^ MatToBitmap(cv::Mat mat)
|
||||||
{
|
{
|
||||||
|
if (mat.empty())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const int width = mat.size().width;
|
const int width = mat.size().width;
|
||||||
const int height = mat.size().height;
|
const int height = mat.size().height;
|
||||||
const int channels = mat.channels();
|
const int channels = mat.channels();
|
||||||
|
@@ -326,7 +326,7 @@ namespace openalprnet {
|
|||||||
|
|
||||||
event EventHandler<AlprFrameEventArgs^>^ FrameProcessed;
|
event EventHandler<AlprFrameEventArgs^>^ FrameProcessed;
|
||||||
|
|
||||||
void recognizeFromVideo(System::String^ videoPath) {
|
void RecognizeFromVideo(System::String^ videoPath) {
|
||||||
if (System::IO::File::Exists(videoPath)) {
|
if (System::IO::File::Exists(videoPath)) {
|
||||||
int framenum = 0;
|
int framenum = 0;
|
||||||
cv::VideoCapture cap = cv::VideoCapture();
|
cv::VideoCapture cap = cv::VideoCapture();
|
||||||
@@ -409,8 +409,9 @@ namespace openalprnet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
AlprResultsNet^ Recognize(MemoryStream^ memoryStream, List<System::Drawing::Rectangle>^ regionsOfInterest)
|
AlprResultsNet^ Recognize(MemoryStream^ memoryStream, List<System::Drawing::Rectangle>^ regionsOfInterest)
|
||||||
{
|
{
|
||||||
std::vector<char> p = AlprHelper::MemoryStreamToVector(memoryStream);
|
std::vector<char> buffer = AlprHelper::MemoryStreamToVector(memoryStream);
|
||||||
AlprResults results = m_Impl->recognize(p);
|
std::vector<AlprRegionOfInterest> rois = AlprHelper::ToVector(regionsOfInterest);
|
||||||
|
AlprResults results = m_Impl->recognize(buffer, rois);
|
||||||
return gcnew AlprResultsNet(results);
|
return gcnew AlprResultsNet(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,8 +428,9 @@ namespace openalprnet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageBuffer">Bytes representing image data</param>
|
/// <param name="imageBuffer">Bytes representing image data</param>
|
||||||
AlprResultsNet^ Recognize(cli::array<Byte>^ imageBuffer, List<System::Drawing::Rectangle>^ regionsOfInterest) {
|
AlprResultsNet^ Recognize(cli::array<Byte>^ imageBuffer, List<System::Drawing::Rectangle>^ regionsOfInterest) {
|
||||||
std::vector<char> p = AlprHelper::ToVector(imageBuffer);
|
std::vector<char> buffer = AlprHelper::ToVector(imageBuffer);
|
||||||
AlprResults results = m_Impl->recognize(p);
|
std::vector<AlprRegionOfInterest> rois = AlprHelper::ToVector(regionsOfInterest);
|
||||||
|
AlprResults results = m_Impl->recognize(buffer, rois);
|
||||||
return gcnew AlprResultsNet(results);
|
return gcnew AlprResultsNet(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,6 +452,32 @@ namespace openalprnet {
|
|||||||
return gcnew AlprResultsNet(results);
|
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() {
|
bool IsLoaded() {
|
||||||
return m_Impl->isLoaded();
|
return m_Impl->isLoaded();
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "alpr.h"
|
#include "alpr.h"
|
||||||
|
#include "prewarp.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
<RootNamespace>openalprnet</RootNamespace>
|
<RootNamespace>openalprnet</RootNamespace>
|
||||||
<OpenALPRVersion>2.1.0</OpenALPRVersion>
|
<OpenALPRVersion>2.1.0</OpenALPRVersion>
|
||||||
<PlatformToolset>v120</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<PlatformToolset Condition="$(VisualStudioVersion)=='14.0'">v140</PlatformToolset>
|
||||||
<OpenALPRWindowsDir>..\..\..\..\windows</OpenALPRWindowsDir>
|
<OpenALPRWindowsDir>..\..\..\..\windows</OpenALPRWindowsDir>
|
||||||
<CudaGeneration Condition="$(CudaGeneration)=='' OR $(CudaGeneration)=='None'">None</CudaGeneration>
|
<CudaGeneration Condition="$(CudaGeneration)=='' OR $(CudaGeneration)=='None'">None</CudaGeneration>
|
||||||
<OpenALPRDistDir Condition="$(CudaGeneration)=='None'">$(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)</OpenALPRDistDir>
|
<OpenALPRDistDir Condition="$(CudaGeneration)=='None'">$(OpenALPRWindowsDir)\build\dist\$(OpenALPRVersion)\$(PlatformToolset)\$(Configuration)\$(Platform)</OpenALPRDistDir>
|
||||||
@@ -105,7 +106,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -118,7 +119,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -130,7 +131,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -142,7 +143,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -18,3 +18,6 @@ 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 = 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._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 = self._openalprpy_lib.dispose
|
||||||
|
self._dispose_func.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
self._is_loaded_func = self._openalprpy_lib.isLoaded
|
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._is_loaded_func.restype = ctypes.c_bool
|
||||||
|
|
||||||
self._recognize_file_func = self._openalprpy_lib.recognizeFile
|
self._recognize_file_func = self._openalprpy_lib.recognizeFile
|
||||||
self._recognize_file_func.restype = ctypes.c_void_p
|
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 = self._openalprpy_lib.recognizeArray
|
||||||
self._recognize_array_func.restype = ctypes.c_void_p
|
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._free_json_mem_func = self._openalprpy_lib.freeJsonMem
|
||||||
|
|
||||||
|
|
||||||
self._set_default_region_func = self._openalprpy_lib.setDefaultRegion
|
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 = 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 = 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 = self._openalprpy_lib.getVersion
|
||||||
|
self._get_version_func.argtypes = [ctypes.c_void_p]
|
||||||
self._get_version_func.restype = 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):
|
def unload(self):
|
||||||
self._openalprpy_lib.dispose()
|
self._openalprpy_lib.dispose(self.alpr_pointer)
|
||||||
|
|
||||||
def is_loaded(self):
|
def is_loaded(self):
|
||||||
return self._is_loaded_func()
|
return self._is_loaded_func(self.alpr_pointer)
|
||||||
|
|
||||||
def recognize_file(self, file_path):
|
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
|
json_data = ctypes.cast(ptr, ctypes.c_char_p).value
|
||||||
response_obj = json.loads(json_data)
|
response_obj = json.loads(json_data)
|
||||||
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
||||||
@@ -64,7 +68,7 @@ class Alpr():
|
|||||||
def recognize_array(self, byte_array):
|
def recognize_array(self, byte_array):
|
||||||
|
|
||||||
pb = ctypes.cast(byte_array, ctypes.POINTER(ctypes.c_ubyte))
|
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
|
json_data = ctypes.cast(ptr, ctypes.c_char_p).value
|
||||||
response_obj = json.loads(json_data)
|
response_obj = json.loads(json_data)
|
||||||
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
||||||
@@ -73,19 +77,19 @@ class Alpr():
|
|||||||
|
|
||||||
def get_version(self):
|
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
|
version_number = ctypes.cast(ptr, ctypes.c_char_p).value
|
||||||
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
self._free_json_mem_func(ctypes.c_void_p(ptr))
|
||||||
|
|
||||||
return version_number
|
return version_number
|
||||||
|
|
||||||
def set_top_n(self, topn):
|
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):
|
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):
|
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;
|
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");
|
//printf("Initialize");
|
||||||
|
|
||||||
@@ -29,35 +27,29 @@ extern "C" {
|
|||||||
std::string runtimeDir(cruntimeDir);
|
std::string runtimeDir(cruntimeDir);
|
||||||
|
|
||||||
//std::cout << country << std::endl << configFile << std::endl << runtimeDir << std::endl;
|
//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 nativeAlpr;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OPENALPR_EXPORT void dispose()
|
OPENALPR_EXPORT void dispose(Alpr* nativeAlpr)
|
||||||
{
|
{
|
||||||
//printf("Dispose");
|
|
||||||
initialized = false;
|
|
||||||
delete nativeAlpr;
|
delete nativeAlpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OPENALPR_EXPORT bool isLoaded()
|
OPENALPR_EXPORT bool isLoaded(Alpr* nativeAlpr)
|
||||||
{
|
{
|
||||||
//printf("IS LOADED");
|
//printf("IS LOADED");
|
||||||
|
|
||||||
if (!initialized)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return nativeAlpr->isLoaded();
|
return nativeAlpr->isLoaded();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OPENALPR_EXPORT char* recognizeFile(char* cimageFile)
|
OPENALPR_EXPORT char* recognizeFile(Alpr* nativeAlpr, char* cimageFile)
|
||||||
{
|
{
|
||||||
//printf("Recognize file");
|
//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("Recognize byte array");
|
||||||
//printf("buffer pointer: %p\n", buf);
|
//printf("buffer pointer: %p\n", buf);
|
||||||
//printf("buffer length: %d\n", len);
|
//printf("buffer length: %d\n", len);
|
||||||
|
|
||||||
|
//std::cout << "Using instance: " << nativeAlpr << std::endl;
|
||||||
|
|
||||||
std::vector<char> cvec(buf, buf+len);
|
std::vector<char> cvec(buf, buf+len);
|
||||||
|
|
||||||
@@ -103,7 +96,7 @@ extern "C" {
|
|||||||
return membuffer;
|
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
|
// Convert strings from java to C++ and release resources
|
||||||
std::string default_region(cdefault_region);
|
std::string default_region(cdefault_region);
|
||||||
@@ -111,17 +104,17 @@ extern "C" {
|
|||||||
nativeAlpr->setDefaultRegion(default_region);
|
nativeAlpr->setDefaultRegion(default_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
OPENALPR_EXPORT void setDetectRegion(bool detect_region)
|
OPENALPR_EXPORT void setDetectRegion(Alpr* nativeAlpr, bool detect_region)
|
||||||
{
|
{
|
||||||
nativeAlpr->setDetectRegion(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);
|
nativeAlpr->setTopN(top_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
OPENALPR_EXPORT char* getVersion()
|
OPENALPR_EXPORT char* getVersion(Alpr* nativeAlpr)
|
||||||
{
|
{
|
||||||
std::string version = nativeAlpr->getVersion();
|
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']
|
||||||
|
)
|
@@ -198,7 +198,9 @@ int main( int argc, const char** argv )
|
|||||||
std::cout << "Video processing ended" << std::endl;
|
std::cout << "Video processing ended" << std::endl;
|
||||||
}
|
}
|
||||||
else if (hasEndingInsensitive(filename, ".avi") || hasEndingInsensitive(filename, ".mp4") || hasEndingInsensitive(filename, ".webm") ||
|
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()))
|
if (fileExists(filename.c_str()))
|
||||||
{
|
{
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
ADD_EXECUTABLE( openalpr-utils-sortstate sortstate.cpp )
|
ADD_EXECUTABLE( openalpr-utils-sortstate sortstate.cpp )
|
||||||
TARGET_LINK_LIBRARIES(openalpr-utils-sortstate
|
TARGET_LINK_LIBRARIES(openalpr-utils-sortstate
|
||||||
${OPENALPR_LIB}
|
${OPENALPR_LIB}
|
||||||
|
statedetection
|
||||||
support
|
support
|
||||||
${OpenCV_LIBS}
|
${OpenCV_LIBS}
|
||||||
${Tesseract_LIBRARIES}
|
${Tesseract_LIBRARIES}
|
||||||
@@ -23,6 +24,7 @@ ADD_EXECUTABLE(openalpr-utils-benchmark
|
|||||||
)
|
)
|
||||||
TARGET_LINK_LIBRARIES(openalpr-utils-benchmark
|
TARGET_LINK_LIBRARIES(openalpr-utils-benchmark
|
||||||
${OPENALPR_LIB}
|
${OPENALPR_LIB}
|
||||||
|
statedetection
|
||||||
support
|
support
|
||||||
pthread
|
pthread
|
||||||
${OpenCV_LIBS}
|
${OpenCV_LIBS}
|
||||||
@@ -72,4 +74,3 @@ ENDIF()
|
|||||||
install (TARGETS openalpr-utils-prepcharsfortraining DESTINATION bin)
|
install (TARGETS openalpr-utils-prepcharsfortraining DESTINATION bin)
|
||||||
install (TARGETS openalpr-utils-tagplates DESTINATION bin)
|
install (TARGETS openalpr-utils-tagplates DESTINATION bin)
|
||||||
install (TARGETS openalpr-utils-calibrate DESTINATION bin)
|
install (TARGETS openalpr-utils-calibrate DESTINATION bin)
|
||||||
|
|
||||||
|
@@ -167,7 +167,7 @@ int main( int argc, const char** argv )
|
|||||||
alpr.setDetectRegion(true);
|
alpr.setDetectRegion(true);
|
||||||
|
|
||||||
Detector* plateDetector = createDetector(&config);
|
Detector* plateDetector = createDetector(&config);
|
||||||
StateIdentifier stateIdentifier(&config);
|
StateDetector stateDetector(country, config.runtimeBaseDir);
|
||||||
OCR ocr(&config);
|
OCR ocr(&config);
|
||||||
|
|
||||||
vector<double> endToEndTimes;
|
vector<double> endToEndTimes;
|
||||||
@@ -211,7 +211,7 @@ int main( int argc, const char** argv )
|
|||||||
|
|
||||||
getTimeMonotonic(&startTime);
|
getTimeMonotonic(&startTime);
|
||||||
|
|
||||||
stateIdentifier.recognize(&pipeline_data);
|
//stateDetector.detect(&pipeline_data);
|
||||||
getTimeMonotonic(&endTime);
|
getTimeMonotonic(&endTime);
|
||||||
double stateidTime = diffclock(startTime, endTime);
|
double stateidTime = diffclock(startTime, endTime);
|
||||||
cout << "\tRegion " << z << ": State ID time: " << stateidTime << "ms." << endl;
|
cout << "\tRegion " << z << ": State ID time: " << stateidTime << "ms." << endl;
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "postprocess/regexrule.h"
|
#include "postprocess/regexrule.h"
|
||||||
#include "licenseplatecandidate.h"
|
#include "licenseplatecandidate.h"
|
||||||
#include "stateidentifier.h"
|
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "support/filesystem.h"
|
#include "support/filesystem.h"
|
||||||
#include "ocr.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++)
|
for (int i = 0; i < charRegions.size(); i++)
|
||||||
humanInputs[i] = SPACE;
|
humanInputs[i] = SPACE;
|
||||||
|
|
||||||
RegexRule regex_rule("", "[\\p{Digit}\\p{Alpha}]");
|
RegexRule regex_rule("", "[\\pL\\pN]", "", "");
|
||||||
|
|
||||||
int16_t waitkey = waitKey(50);
|
int16_t waitkey = waitKey(50);
|
||||||
while (waitkey != ENTER_KEY && waitkey != ESCAPE_KEY)
|
while (waitkey != ENTER_KEY && waitkey != ESCAPE_KEY)
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "licenseplatecandidate.h"
|
#include "licenseplatecandidate.h"
|
||||||
#include "stateidentifier.h"
|
#include "../statedetection/state_detector.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "support/filesystem.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.
|
// 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.
|
// 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 )
|
int main( int argc, const char** argv )
|
||||||
{
|
{
|
||||||
@@ -59,7 +59,7 @@ int main( int argc, const char** argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
Config config("us");
|
Config config("us");
|
||||||
StateIdentifier identifier(&config);
|
StateDetector identifier(config.country, config.runtimeBaseDir);
|
||||||
|
|
||||||
if (DirectoryExists(outDir.c_str()) == false)
|
if (DirectoryExists(outDir.c_str()) == false)
|
||||||
{
|
{
|
||||||
@@ -79,22 +79,17 @@ int main( int argc, const char** argv )
|
|||||||
cout << fullpath << endl;
|
cout << fullpath << endl;
|
||||||
frame = imread( fullpath.c_str() );
|
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";
|
cout << candidates[0].confidence << " : " << candidates[0].state_code;
|
||||||
pipeline_data.region_confidence = 100;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << pipeline_data.region_confidence << " : " << pipeline_data.region_code;
|
|
||||||
|
|
||||||
ostringstream convert; // stream used for the conversion
|
ostringstream convert; // stream used for the conversion
|
||||||
convert << i; // insert the textual representation of 'Number' in the characters in the stream
|
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() );
|
system( copyCommand.c_str() );
|
||||||
waitKey(50);
|
waitKey(50);
|
||||||
//while ((char) waitKey(50) != 'c') { }
|
//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
|
detection/detectormorph.cpp
|
||||||
licenseplatecandidate.cpp
|
licenseplatecandidate.cpp
|
||||||
utility.cpp
|
utility.cpp
|
||||||
stateidentifier.cpp
|
|
||||||
featurematcher.cpp
|
|
||||||
ocr.cpp
|
ocr.cpp
|
||||||
postprocess/postprocess.cpp
|
postprocess/postprocess.cpp
|
||||||
postprocess/regexrule.cpp
|
postprocess/regexrule.cpp
|
||||||
@@ -51,6 +49,7 @@ set_target_properties(openalpr PROPERTIES SOVERSION ${OPENALPR_MAJOR_VERSION})
|
|||||||
|
|
||||||
TARGET_LINK_LIBRARIES(openalpr
|
TARGET_LINK_LIBRARIES(openalpr
|
||||||
support
|
support
|
||||||
|
statedetection
|
||||||
${OpenCV_LIBS}
|
${OpenCV_LIBS}
|
||||||
${Tesseract_LIBRARIES}
|
${Tesseract_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@@ -68,6 +68,11 @@ namespace alpr
|
|||||||
return impl->recognize(imageBytes);
|
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)
|
AlprResults Alpr::recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest)
|
||||||
{
|
{
|
||||||
return impl->recognize(pixelData, bytesPerPixel, imgWidth, imgHeight, regionsOfInterest);
|
return impl->recognize(pixelData, bytesPerPixel, imgWidth, imgHeight, regionsOfInterest);
|
||||||
|
@@ -135,6 +135,9 @@ namespace alpr
|
|||||||
// Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).
|
// Recognize from byte data representing an encoded image (e.g., BMP, PNG, JPG, GIF etc).
|
||||||
AlprResults recognize(std::vector<char> imageBytes);
|
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.
|
// Recognize from raw pixel data.
|
||||||
AlprResults recognize(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest);
|
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);
|
config = new Config(country, configFile, runtimeDir);
|
||||||
|
|
||||||
plateDetector = ALPR_NULL_PTR;
|
plateDetector = ALPR_NULL_PTR;
|
||||||
stateIdentifier = ALPR_NULL_PTR;
|
stateDetector = ALPR_NULL_PTR;
|
||||||
ocr = ALPR_NULL_PTR;
|
ocr = ALPR_NULL_PTR;
|
||||||
prewarp = ALPR_NULL_PTR;
|
prewarp = ALPR_NULL_PTR;
|
||||||
|
|
||||||
@@ -69,8 +69,8 @@ namespace alpr
|
|||||||
if (plateDetector != ALPR_NULL_PTR)
|
if (plateDetector != ALPR_NULL_PTR)
|
||||||
delete plateDetector;
|
delete plateDetector;
|
||||||
|
|
||||||
if (stateIdentifier != ALPR_NULL_PTR)
|
if (stateDetector != ALPR_NULL_PTR)
|
||||||
delete stateIdentifier;
|
delete stateDetector;
|
||||||
|
|
||||||
if (ocr != ALPR_NULL_PTR)
|
if (ocr != ALPR_NULL_PTR)
|
||||||
delete ocr;
|
delete ocr;
|
||||||
@@ -97,6 +97,10 @@ namespace alpr
|
|||||||
response.results.img_width = img.cols;
|
response.results.img_width = img.cols;
|
||||||
response.results.img_height = img.rows;
|
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++)
|
for (unsigned int i = 0; i < regionsOfInterest.size(); i++)
|
||||||
{
|
{
|
||||||
response.results.regionsOfInterest.push_back(AlprRegionOfInterest(regionsOfInterest[i].x, regionsOfInterest[i].y,
|
response.results.regionsOfInterest.push_back(AlprRegionOfInterest(regionsOfInterest[i].x, regionsOfInterest[i].y,
|
||||||
@@ -152,6 +156,7 @@ namespace alpr
|
|||||||
plateQueue.pop();
|
plateQueue.pop();
|
||||||
|
|
||||||
PipelineData pipeline_data(img, grayImg, plateRegion.rect, config);
|
PipelineData pipeline_data(img, grayImg, plateRegion.rect, config);
|
||||||
|
pipeline_data.prewarp = prewarp;
|
||||||
|
|
||||||
timespec platestarttime;
|
timespec platestarttime;
|
||||||
getTimeMonotonic(&platestarttime);
|
getTimeMonotonic(&platestarttime);
|
||||||
@@ -180,11 +185,15 @@ namespace alpr
|
|||||||
|
|
||||||
if (detectRegion)
|
if (detectRegion)
|
||||||
{
|
{
|
||||||
stateIdentifier->recognize(&pipeline_data);
|
std::vector<StateCandidate> state_candidates = stateDetector->detect(pipeline_data.color_deskewed.data,
|
||||||
if (pipeline_data.region_confidence > 0)
|
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.region = state_candidates[0].state_code;
|
||||||
plateResult.regionConfidence = (int) pipeline_data.region_confidence;
|
plateResult.regionConfidence = (int) state_candidates[0].confidence;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +354,16 @@ namespace alpr
|
|||||||
return this->recognize(img);
|
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)
|
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;
|
this->detectRegion = detectRegion;
|
||||||
if (detectRegion && this->stateIdentifier == NULL)
|
if (detectRegion && this->stateDetector == NULL)
|
||||||
{
|
{
|
||||||
timespec startTime;
|
timespec startTime;
|
||||||
getTimeMonotonic(&startTime);
|
getTimeMonotonic(&startTime);
|
||||||
|
|
||||||
this->stateIdentifier = new StateIdentifier(this->config);
|
this->stateDetector = new StateDetector(this->config->country, this->config->runtimeBaseDir);
|
||||||
|
|
||||||
timespec endTime;
|
timespec endTime;
|
||||||
getTimeMonotonic(&endTime);
|
getTimeMonotonic(&endTime);
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
#include "prewarp.h"
|
#include "prewarp.h"
|
||||||
|
|
||||||
#include "licenseplatecandidate.h"
|
#include "licenseplatecandidate.h"
|
||||||
#include "stateidentifier.h"
|
#include "../statedetection/state_detector.h"
|
||||||
#include "segmentation/charactersegmenter.h"
|
#include "segmentation/charactersegmenter.h"
|
||||||
#include "ocr.h"
|
#include "ocr.h"
|
||||||
|
|
||||||
@@ -76,6 +76,7 @@ namespace alpr
|
|||||||
AlprFullDetails recognizeFullDetails(cv::Mat img, std::vector<cv::Rect> regionsOfInterest);
|
AlprFullDetails recognizeFullDetails(cv::Mat img, std::vector<cv::Rect> regionsOfInterest);
|
||||||
|
|
||||||
AlprResults recognize( std::vector<char> imageBytes );
|
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( unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight, std::vector<AlprRegionOfInterest> regionsOfInterest );
|
||||||
AlprResults recognize( cv::Mat img );
|
AlprResults recognize( cv::Mat img );
|
||||||
AlprResults recognize( cv::Mat img, std::vector<cv::Rect> regionsOfInterest );
|
AlprResults recognize( cv::Mat img, std::vector<cv::Rect> regionsOfInterest );
|
||||||
@@ -99,7 +100,7 @@ namespace alpr
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Detector* plateDetector;
|
Detector* plateDetector;
|
||||||
StateIdentifier* stateIdentifier;
|
StateDetector* stateDetector;
|
||||||
OCR* ocr;
|
OCR* ocr;
|
||||||
PreWarp* prewarp;
|
PreWarp* prewarp;
|
||||||
|
|
||||||
|
@@ -244,6 +244,9 @@ namespace alpr
|
|||||||
|
|
||||||
ocrLanguage = getString(ini, "", "ocr_language", "none");
|
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);
|
ocrImageWidthPx = round(((float) templateWidthPx) * ocrImagePercent);
|
||||||
ocrImageHeightPx = round(((float)templateHeightPx) * ocrImagePercent);
|
ocrImageHeightPx = round(((float)templateHeightPx) * ocrImagePercent);
|
||||||
stateIdImageWidthPx = round(((float)templateWidthPx) * stateIdImagePercent);
|
stateIdImageWidthPx = round(((float)templateWidthPx) * stateIdImagePercent);
|
||||||
|
@@ -100,6 +100,9 @@ namespace alpr
|
|||||||
unsigned int postProcessMinCharacters;
|
unsigned int postProcessMinCharacters;
|
||||||
unsigned int postProcessMaxCharacters;
|
unsigned int postProcessMaxCharacters;
|
||||||
|
|
||||||
|
std::string postProcessRegexLetters;
|
||||||
|
std::string postProcessRegexNumbers;
|
||||||
|
|
||||||
bool debugGeneral;
|
bool debugGeneral;
|
||||||
bool debugTiming;
|
bool debugTiming;
|
||||||
bool debugPrewarp;
|
bool debugPrewarp;
|
||||||
@@ -122,12 +125,13 @@ namespace alpr
|
|||||||
std::string getPostProcessRuntimeDir();
|
std::string getPostProcessRuntimeDir();
|
||||||
std::string getTessdataPrefix();
|
std::string getTessdataPrefix();
|
||||||
|
|
||||||
|
std::string runtimeBaseDir;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
float ocrImagePercent;
|
float ocrImagePercent;
|
||||||
float stateIdImagePercent;
|
float stateIdImagePercent;
|
||||||
|
|
||||||
std::string runtimeBaseDir;
|
|
||||||
|
|
||||||
void loadCommonValues(std::string configFile);
|
void loadCommonValues(std::string configFile);
|
||||||
void loadCountryValues(std::string configFile, std::string country);
|
void loadCountryValues(std::string configFile, std::string country);
|
||||||
|
@@ -69,6 +69,8 @@ namespace alpr
|
|||||||
|
|
||||||
float total = getTotal();
|
float total = getTotal();
|
||||||
|
|
||||||
|
std::cout << "--------------------" << std::endl;
|
||||||
|
std::cout << "Total: " << total << std::endl;
|
||||||
for (unsigned int i = 0; i < weight_ids.size(); i++)
|
for (unsigned int i = 0; i < weight_ids.size(); i++)
|
||||||
{
|
{
|
||||||
float percent_of_total = (scores[i] * weights[i]) / total * 100;
|
float percent_of_total = (scores[i] * weights[i]) / total * 100;
|
||||||
@@ -79,8 +81,7 @@ namespace alpr
|
|||||||
" (" << percent_of_total << "% of total)" << std::endl;
|
" (" << percent_of_total << "% of total)" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "--------------------" << std::endl;
|
||||||
std::cout << "Total: " << total << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -71,18 +71,30 @@ namespace alpr
|
|||||||
getTimeMonotonic(&startTime);
|
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);
|
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));
|
Size(pipeline_data->config->ocrImageWidthPx, pipeline_data->config->ocrImageHeightPx));
|
||||||
Mat transmtx = imgTransform.getTransformationMatrix(pipeline_data->plate_corners, cropSize);
|
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)
|
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 requires the prefix directory to be set as an env variable
|
||||||
tesseract.Init(config->getTessdataPrefix().c_str(), config->ocrLanguage.c_str() );
|
tesseract.Init(config->getTessdataPrefix().c_str(), config->ocrLanguage.c_str() );
|
||||||
tesseract.SetVariable("save_blob_choices", "T");
|
tesseract.SetVariable("save_blob_choices", "T");
|
||||||
|
tesseract.SetVariable("debug_file", "/dev/null");
|
||||||
tesseract.SetPageSegMode(PSM_SINGLE_CHAR);
|
tesseract.SetPageSegMode(PSM_SINGLE_CHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
OCR::~OCR()
|
OCR::~OCR()
|
||||||
{
|
{
|
||||||
tesseract.Clear();
|
tesseract.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OCR::performOCR(PipelineData* pipeline_data)
|
void OCR::performOCR(PipelineData* pipeline_data)
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "textdetection/textline.h"
|
#include "textdetection/textline.h"
|
||||||
#include "edges/scorekeeper.h"
|
#include "edges/scorekeeper.h"
|
||||||
|
#include "prewarp.h"
|
||||||
|
|
||||||
namespace alpr
|
namespace alpr
|
||||||
{
|
{
|
||||||
@@ -25,6 +26,8 @@ namespace alpr
|
|||||||
// Inputs
|
// Inputs
|
||||||
Config* config;
|
Config* config;
|
||||||
|
|
||||||
|
PreWarp* prewarp;
|
||||||
|
|
||||||
cv::Mat colorImg;
|
cv::Mat colorImg;
|
||||||
cv::Mat grayImg;
|
cv::Mat grayImg;
|
||||||
cv::Rect regionOfInterest;
|
cv::Rect regionOfInterest;
|
||||||
@@ -33,6 +36,8 @@ namespace alpr
|
|||||||
|
|
||||||
cv::Mat crop_gray;
|
cv::Mat crop_gray;
|
||||||
|
|
||||||
|
cv::Mat color_deskewed;
|
||||||
|
|
||||||
bool hasPlateBorder;
|
bool hasPlateBorder;
|
||||||
cv::Mat plateBorderMask;
|
cv::Mat plateBorderMask;
|
||||||
std::vector<TextLine> textLines;
|
std::vector<TextLine> textLines;
|
||||||
|
@@ -36,7 +36,7 @@ namespace alpr
|
|||||||
string region, pattern;
|
string region, pattern;
|
||||||
while (infile >> 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;
|
//cout << "REGION: " << region << " PATTERN: " << pattern << endl;
|
||||||
|
|
||||||
if (rules.find(region) == rules.end())
|
if (rules.find(region) == rules.end())
|
||||||
@@ -170,7 +170,7 @@ namespace alpr
|
|||||||
for (int i = 0; i < letters.size(); i++)
|
for (int i = 0; i < letters.size(); i++)
|
||||||
{
|
{
|
||||||
if (letters[i].size() > 0)
|
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)
|
if (this->config->debugPostProcess)
|
||||||
@@ -386,12 +386,6 @@ namespace alpr
|
|||||||
return true;
|
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 )
|
bool letterCompare( const Letter &left, const Letter &right )
|
||||||
{
|
{
|
||||||
|
@@ -53,7 +53,6 @@ namespace alpr
|
|||||||
std::vector<Letter> letter_details;
|
std::vector<Letter> letter_details;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool wordCompare( const PPResult &left, const PPResult &right );
|
|
||||||
bool letterCompare( const Letter &left, const Letter &right );
|
bool letterCompare( const Letter &left, const Letter &right );
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ namespace alpr
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Config* config;
|
Config* config;
|
||||||
//void getTopN();
|
|
||||||
void findAllPermutations(std::string templateregion, int topn);
|
void findAllPermutations(std::string templateregion, int topn);
|
||||||
bool analyzePermutation(std::vector<int> letterIndices, 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
|
namespace alpr
|
||||||
{
|
{
|
||||||
|
|
||||||
RegexRule::RegexRule(string region, string pattern)
|
RegexRule::RegexRule(string region, string pattern, std::string letters_regex, std::string numbers_regex)
|
||||||
//: re2_regex("")
|
//: re2_regex("")
|
||||||
{
|
{
|
||||||
this->original = pattern;
|
this->original = pattern;
|
||||||
@@ -80,11 +80,11 @@ namespace alpr
|
|||||||
}
|
}
|
||||||
else if (utf_character == "@")
|
else if (utf_character == "@")
|
||||||
{
|
{
|
||||||
regexval << "\\pL";
|
regexval << letters_regex;
|
||||||
}
|
}
|
||||||
else if (utf_character == "#")
|
else if (utf_character == "#")
|
||||||
{
|
{
|
||||||
regexval << "\\pN";
|
regexval << numbers_regex;
|
||||||
}
|
}
|
||||||
else if ((utf_character == "*") || (utf_character == "+"))
|
else if ((utf_character == "*") || (utf_character == "+"))
|
||||||
{
|
{
|
||||||
|
@@ -33,7 +33,7 @@ namespace alpr
|
|||||||
class RegexRule
|
class RegexRule
|
||||||
{
|
{
|
||||||
public:
|
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();
|
virtual ~RegexRule();
|
||||||
|
|
||||||
bool match(std::string text);
|
bool match(std::string text);
|
||||||
|
@@ -159,7 +159,6 @@ namespace alpr
|
|||||||
getTimeMonotonic(&startTime);
|
getTimeMonotonic(&startTime);
|
||||||
|
|
||||||
filterEdgeBoxes(pipeline_data->thresholds, candidateBoxes, medianCharWidth, avgCharHeight);
|
filterEdgeBoxes(pipeline_data->thresholds, candidateBoxes, medianCharWidth, avgCharHeight);
|
||||||
candidateBoxes = filterMostlyEmptyBoxes(pipeline_data->thresholds, candidateBoxes);
|
|
||||||
candidateBoxes = combineCloseBoxes(candidateBoxes, medianCharWidth);
|
candidateBoxes = combineCloseBoxes(candidateBoxes, medianCharWidth);
|
||||||
|
|
||||||
candidateBoxes = filterMostlyEmptyBoxes(pipeline_data->thresholds, candidateBoxes);
|
candidateBoxes = filterMostlyEmptyBoxes(pipeline_data->thresholds, candidateBoxes);
|
||||||
@@ -260,7 +259,7 @@ namespace alpr
|
|||||||
|
|
||||||
vector<Rect> CharacterSegmenter::getBestCharBoxes(Mat img, vector<Rect> charBoxes, float avgCharWidth)
|
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
|
// 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.
|
// 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 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 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);
|
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);
|
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;
|
return directory;
|
||||||
#else
|
#else
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
readlink("/proc/self/exe", buffer, 2048);
|
readlink("/proc/self/exe", buffer, sizeof(buffer));
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << buffer;
|
ss << buffer;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#ifndef OPENALPR_PLATFORM_H
|
#ifndef OPENALPR_PLATFORM_H
|
||||||
#define OPENALPR_PLATFORM_H
|
#define OPENALPR_PLATFORM_H
|
||||||
|
|
||||||
#include <string>
|
#include <string.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#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 int DEFAULT_TRAINING_FEATURES = 305;
|
||||||
const float MAX_DISTANCE_TO_MATCH = 100.0f;
|
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 = DescriptorMatcher::create( "BruteForce-HammingLUT" );
|
||||||
this->descriptorMatcher = new BFMatcher(NORM_HAMMING, false);
|
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
|
// 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)
|
void FeatureMatcher::crisscrossFiltering(const vector<KeyPoint> queryKeypoints, const vector<DMatch> inputMatches, vector<DMatch> &outputMatches)
|
||||||
{
|
{
|
||||||
Rect crissCrossAreaVertical(0, 0, config->stateIdImageWidthPx, config->stateIdimageHeightPx * 2);
|
Rect crissCrossAreaVertical(0, 0, w, h * 2);
|
||||||
Rect crissCrossAreaHorizontal(0, 0, config->stateIdImageWidthPx * 2, config->stateIdimageHeightPx);
|
Rect crissCrossAreaHorizontal(0, 0, w * 2, h);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < billMapping.size(); i++)
|
for (unsigned int i = 0; i < billMapping.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -175,8 +173,8 @@ namespace alpr
|
|||||||
KeyPoint tkp = trainingImgKeypoints[i][matchesForOnePlate[j].trainIdx];
|
KeyPoint tkp = trainingImgKeypoints[i][matchesForOnePlate[j].trainIdx];
|
||||||
KeyPoint qkp = queryKeypoints[matchesForOnePlate[j].queryIdx];
|
KeyPoint qkp = queryKeypoints[matchesForOnePlate[j].queryIdx];
|
||||||
|
|
||||||
vlines.push_back(LineSegment(tkp.pt.x, tkp.pt.y + config->stateIdimageHeightPx, qkp.pt.x, 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 + config->stateIdImageWidthPx, qkp.pt.y));
|
hlines.push_back(LineSegment(tkp.pt.x, tkp.pt.y, qkp.pt.x + w, qkp.pt.y));
|
||||||
matchIdx.push_back(j);
|
matchIdx.push_back(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,8 +213,8 @@ namespace alpr
|
|||||||
|
|
||||||
if (mostIntersectionsIndex >= 0)
|
if (mostIntersectionsIndex >= 0)
|
||||||
{
|
{
|
||||||
if (this->config->debugStateId)
|
// if (this->config->debugStateId)
|
||||||
cout << "Filtered intersection! " << billMapping[i] << endl;
|
// cout << "Filtered intersection! " << billMapping[i] << endl;
|
||||||
vlines.erase(vlines.begin() + mostIntersectionsIndex);
|
vlines.erase(vlines.begin() + mostIntersectionsIndex);
|
||||||
hlines.erase(hlines.begin() + mostIntersectionsIndex);
|
hlines.erase(hlines.begin() + mostIntersectionsIndex);
|
||||||
matchIdx.erase(matchIdx.begin() + mostIntersectionsIndex);
|
matchIdx.erase(matchIdx.begin() + mostIntersectionsIndex);
|
||||||
@@ -232,10 +230,10 @@ namespace alpr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if successful, false otherwise
|
// Returns true if successful, false otherwise
|
||||||
bool FeatureMatcher::loadRecognitionSet(string country)
|
bool FeatureMatcher::loadRecognitionSet(string directory, string country)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << config->getKeypointsRuntimeDir() << "/" << country << "/";
|
out << directory << "/keypoints/" << country << "/";
|
||||||
string country_dir = out.str();
|
string country_dir = out.str();
|
||||||
|
|
||||||
if (DirectoryExists(country_dir.c_str()))
|
if (DirectoryExists(country_dir.c_str()))
|
||||||
@@ -253,7 +251,6 @@ namespace alpr
|
|||||||
|
|
||||||
// convert to gray and resize to the size of the templates
|
// convert to gray and resize to the size of the templates
|
||||||
cvtColor(img, img, CV_BGR2GRAY);
|
cvtColor(img, img, CV_BGR2GRAY);
|
||||||
resize(img, img, getSizeMaintainingAspect(img, config->stateIdImageWidthPx, config->stateIdimageHeightPx));
|
|
||||||
|
|
||||||
if( img.empty() )
|
if( img.empty() )
|
||||||
{
|
{
|
||||||
@@ -290,6 +287,9 @@ namespace alpr
|
|||||||
{
|
{
|
||||||
RecognitionResult result;
|
RecognitionResult result;
|
||||||
|
|
||||||
|
this->w = queryImg.cols;
|
||||||
|
this->h = queryImg.rows;
|
||||||
|
|
||||||
result.haswinner = false;
|
result.haswinner = false;
|
||||||
result.confidence = 0;
|
result.confidence = 0;
|
||||||
|
|
||||||
@@ -381,13 +381,13 @@ namespace alpr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->config->debugStateId)
|
// if (this->config->debugStateId)
|
||||||
{
|
// {
|
||||||
for (unsigned int i = 0; i < billMapping.size(); i++)
|
// for (unsigned int i = 0; i < billMapping.size(); i++)
|
||||||
{
|
// {
|
||||||
cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
|
// cout << billMapping[i] << " : " << bill_match_counts[i] << endl;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
@@ -44,20 +44,19 @@ namespace alpr
|
|||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FeatureMatcher(Config* config);
|
FeatureMatcher();
|
||||||
virtual ~FeatureMatcher();
|
virtual ~FeatureMatcher();
|
||||||
|
|
||||||
RecognitionResult recognize( const cv::Mat& queryImg, bool drawOnImage, cv::Mat* outputImage,
|
RecognitionResult recognize( const cv::Mat& queryImg, bool drawOnImage, cv::Mat* outputImage,
|
||||||
bool debug_on, std::vector<int> debug_matches_array );
|
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();
|
bool isLoaded();
|
||||||
|
|
||||||
int numTrainingElements();
|
int numTrainingElements();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config* config;
|
|
||||||
|
|
||||||
cv::Ptr<cv::DescriptorMatcher> descriptorMatcher;
|
cv::Ptr<cv::DescriptorMatcher> descriptorMatcher;
|
||||||
cv::Ptr<cv::FastFeatureDetector> detector;
|
cv::Ptr<cv::FastFeatureDetector> detector;
|
||||||
@@ -74,6 +73,9 @@ namespace alpr
|
|||||||
void surfStyleMatching( const cv::Mat& queryDescriptors, std::vector<cv::KeyPoint> queryKeypoints,
|
void surfStyleMatching( const cv::Mat& queryDescriptors, std::vector<cv::KeyPoint> queryKeypoints,
|
||||||
std::vector<cv::DMatch>& matches12 );
|
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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef OPENALPR_STATEIDENTIFIER_H
|
#ifndef SRC_STATE_DETECTOR_IMPL_H
|
||||||
#define OPENALPR_STATEIDENTIFIER_H
|
#define SRC_STATE_DETECTOR_IMPL_H
|
||||||
|
|
||||||
#include "opencv2/imgproc/imgproc.hpp"
|
#include "state_detector.h"
|
||||||
#include "constants.h"
|
|
||||||
#include "featurematcher.h"
|
#include "featurematcher.h"
|
||||||
#include "utility.h"
|
#include <opencv2/core/core.hpp>
|
||||||
#include "config.h"
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
#include "pipeline_data.h"
|
|
||||||
|
|
||||||
namespace alpr
|
namespace alpr {
|
||||||
{
|
|
||||||
|
|
||||||
class StateIdentifier
|
|
||||||
{
|
|
||||||
|
|
||||||
|
class StateDetectorImpl {
|
||||||
public:
|
public:
|
||||||
StateIdentifier(Config* config);
|
StateDetectorImpl(const std::string country, const std::string runtimeDir);
|
||||||
virtual ~StateIdentifier();
|
virtual ~StateDetectorImpl();
|
||||||
|
|
||||||
bool recognize(PipelineData* pipeline_data);
|
bool isLoaded();
|
||||||
|
|
||||||
//int confidence;
|
// Maximum number of candidates to return
|
||||||
|
void setTopN(int topN);
|
||||||
|
|
||||||
protected:
|
std::vector<StateCandidate> detect(std::vector<char> imageBytes);
|
||||||
Config* config;
|
std::vector<StateCandidate> detect(unsigned char* pixelData, int bytesPerPixel, int imgWidth, int imgHeight);
|
||||||
|
std::vector<StateCandidate> detect(cv::Mat image);
|
||||||
private:
|
|
||||||
|
|
||||||
FeatureMatcher* featureMatcher;
|
|
||||||
|
|
||||||
|
FeatureMatcher featureMatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // OPENALPR_STATEIDENTIFIER_H
|
|
||||||
|
#endif //SRC_STATE_DETECTOR_IMPL_H
|
@@ -11,7 +11,7 @@ using namespace alpr;
|
|||||||
|
|
||||||
TEST_CASE( "ASCII tests", "[Regex]" ) {
|
TEST_CASE( "ASCII tests", "[Regex]" ) {
|
||||||
|
|
||||||
RegexRule rule1("us", "@@@####");
|
RegexRule rule1("us", "@@@####", "[A-Za-z]", "[0-9]");
|
||||||
|
|
||||||
REQUIRE( rule1.match("123ABCD") == false);
|
REQUIRE( rule1.match("123ABCD") == false);
|
||||||
REQUIRE( rule1.match("123ABC") == false);
|
REQUIRE( rule1.match("123ABC") == false);
|
||||||
@@ -28,7 +28,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) {
|
|||||||
REQUIRE( rule1.match("AAA1111") == true);
|
REQUIRE( rule1.match("AAA1111") == true);
|
||||||
REQUIRE( rule1.match("zzz1111") == 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("ZBC1234") == false);
|
||||||
REQUIRE( rule2.match("DBC1234") == false);
|
REQUIRE( rule2.match("DBC1234") == false);
|
||||||
@@ -38,7 +38,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) {
|
|||||||
REQUIRE( rule2.match("BAA1111") == true);
|
REQUIRE( rule2.match("BAA1111") == true);
|
||||||
REQUIRE( rule2.match("CAA1111") == 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("ZBC1234") == false);
|
||||||
REQUIRE( rule3.match("ZBC1231") == false);
|
REQUIRE( rule3.match("ZBC1231") == false);
|
||||||
@@ -48,7 +48,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) {
|
|||||||
REQUIRE( rule3.match("ABC1232") == true);
|
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("DG1111") == false);
|
||||||
REQUIRE( rule4.match("AD1111") == false);
|
REQUIRE( rule4.match("AD1111") == false);
|
||||||
@@ -61,7 +61,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) {
|
|||||||
REQUIRE( rule4.match("BF1111") == true);
|
REQUIRE( rule4.match("BF1111") == true);
|
||||||
REQUIRE( rule4.match("BG1111") == 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("AA11") == false);
|
||||||
REQUIRE( rule5.match("11AA") == true);
|
REQUIRE( rule5.match("11AA") == true);
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ TEST_CASE( "ASCII tests", "[Regex]" ) {
|
|||||||
|
|
||||||
TEST_CASE( "Unicode tests", "[Regex]" ) {
|
TEST_CASE( "Unicode tests", "[Regex]" ) {
|
||||||
|
|
||||||
RegexRule rule1("us", "@@@####");
|
RegexRule rule1("us", "@@@####", "\\pL", "\\pN");
|
||||||
|
|
||||||
REQUIRE( rule1.match("123与与与下") == false);
|
REQUIRE( rule1.match("123与与与下") == false);
|
||||||
REQUIRE( rule1.match("与万12345") == false);
|
REQUIRE( rule1.match("与万12345") == false);
|
||||||
@@ -78,7 +78,7 @@ TEST_CASE( "Unicode tests", "[Regex]" ) {
|
|||||||
|
|
||||||
REQUIRE( rule1.match("与万口1234") == true);
|
REQUIRE( rule1.match("与万口1234") == true);
|
||||||
|
|
||||||
RegexRule rule2("us", "[십팔]@@####");
|
RegexRule rule2("us", "[십팔]@@####", "\\pL", "\\pN");
|
||||||
|
|
||||||
REQUIRE( rule2.match("123与与与下") == false);
|
REQUIRE( rule2.match("123与与与下") == false);
|
||||||
REQUIRE( rule2.match("与万12345") == false);
|
REQUIRE( rule2.match("与万12345") == false);
|
||||||
@@ -93,7 +93,7 @@ TEST_CASE( "Unicode tests", "[Regex]" ) {
|
|||||||
|
|
||||||
|
|
||||||
TEST_CASE( "Invalid 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("123ABCD") == false);
|
||||||
REQUIRE( rule1.match("123ABC") == false);
|
REQUIRE( rule1.match("123ABC") == false);
|
||||||
@@ -103,6 +103,6 @@ TEST_CASE( "Invalid tests", "[Regex]" ) {
|
|||||||
REQUIRE( rule1.match("AAA1111") == false);
|
REQUIRE( rule1.match("AAA1111") == false);
|
||||||
REQUIRE( rule1.match("zzz1111") == false);
|
REQUIRE( rule1.match("zzz1111") == false);
|
||||||
|
|
||||||
RegexRule rule2("us", "A####]");
|
RegexRule rule2("us", "A####]", "\\pL", "\\pN");
|
||||||
REQUIRE( rule2.match("A1234") == false);
|
REQUIRE( rule2.match("A1234") == false);
|
||||||
}
|
}
|
Reference in New Issue
Block a user