Compare commits

..

4 Commits
master ... 1.3

Author SHA1 Message Date
liuruoze 4c49f89ed1 a little change
10 years ago
liuruoze 200607bae6 readme change
10 years ago
liuruoze eb83fa2ede chang readme
10 years ago
liuruoze 61b0710882 v1.3 change, fix svm train, add ann train
10 years ago

@ -1,39 +0,0 @@
**I'm submitting a ...** (check one with "x")
```
[ ] bug report
[ ] help wanted
[ ] feature request
```
**Current behavior**
**Expected/desired behavior**
**Reproduction of the problem**
If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce.
**What is the expected behavior?**
**What is the motivation / use case for changing the behavior?**
**Please tell us about your environment:**
* **System:** CentOS
* **Compiler version/IDE:** gcc4.8
* **CMake version:** 3.5.1
* **OpenCV version:** [2.4.9 | 2.4.10 | 2.4.11 | 2.4.12 | 2.4.13 | 3.0 ALPHA | 3.0 BETA | 3.0 RC1 | 3.0 | 3.1 ]

217
.gitignore vendored

@ -1,26 +1,10 @@
.idea/
_build/
resources/image/tmp/
*.lib
*.suo
*.sdf
*.opensdf
*.exe
*.dll
*.ilk
*.pdb
experi
/tmp
resources/image/native_test/*.jpg
resources/image/native_test/cars
resources/image/native_test/*.py
resources/image/phone_test
*.vsp
*.psess
*.DS_Store
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
@ -28,17 +12,206 @@ Thumbs.db
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
# Build results
experiment/
experi/
bak/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
*.orig
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.cache
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# If using the old MSBuild-Integrated Package Restore, uncomment this:
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# idea IDE
.idea/
# XCode IDE
EasyPR.xcodeproj/
# Debug tmp files
tmp/
# native_test files
native_test/

@ -1,64 +1,46 @@
cmake_minimum_required(VERSION 3.0.0)
project(easypr)
cmake_minimum_required(VERSION 2.8)
project (easypr)
# c++11 required
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/opencv-3.2.0")
endif ()
# OpenVC3 required
find_package(OpenCV 3.2.0 REQUIRED)
# where to find header files
include_directories(.)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} doesnt support C++11. Please upgrade or use a different C++ compiler.")
endif()
# opencv package required
find_package(OpenCV REQUIRED)
# easypr library
include_directories(include)
include_directories(${OpenCV_INCLUDE_DIRS})
# sub directories
add_subdirectory(thirdparty)
# sources to be compiled
set(SOURCE_FILES
src/core/core_func.cpp
src/core/chars_identify.cpp
src/core/chars_recognise.cpp
src/core/chars_segment.cpp
src/core/feature.cpp
src/core/plate_detect.cpp
src/core/plate_judge.cpp
src/core/plate_locate.cpp
src/core/plate_recognize.cpp
src/core/params.cpp
src/train/ann_train.cpp
src/train/annCh_train.cpp
src/train/svm_train.cpp
src/train/train.cpp
src/train/create_data.cpp
src/util/util.cpp
src/util/program_options.cpp
src/util/kv.cpp
)
# pack objects to static library
src/core/core_func.cpp
src/core/chars_identify.cpp
src/core/chars_recognise.cpp
src/core/chars_segment.cpp
src/core/feature.cpp
src/core/plate.cpp
src/core/plate_detect.cpp
src/core/plate_judge.cpp
src/core/plate_locate.cpp
src/core/plate_recognize.cpp
src/train/ann_train.cpp
src/train/svm_train.cpp
src/preprocess/deface.cpp
src/preprocess/gdts.cpp
src/preprocess/mc_data.cpp
src/util/util.cpp
src/util/program_options.cpp
)
add_library(easypr STATIC ${SOURCE_FILES})
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(EXECUTABLE_NAME "demo")
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(EXECUTABLE_NAME "demo")
endif ()
# set to be releas mode
# set(CMAKE_BUILD_TYPE Release)
# test cases
add_executable(${EXECUTABLE_NAME} test/main.cpp)
# link opencv libs
target_link_libraries(${EXECUTABLE_NAME} easypr thirdparty ${OpenCV_LIBS})
# MESSAGE(${CMAKE_BINARY_DIR}/../)
SET_TARGET_PROPERTIES(${EXECUTABLE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/../")
add_executable(easypr_test test/main.cpp)
target_link_libraries(easypr_test ${OpenCV_LIBS} easypr)

@ -1,113 +1,9 @@
EasyPR版本更新
======
本次更新版本是1.6alpha版本,主要改进如下:
1. 采用灰度字符训练以及新的特征使中文字符正确率上升到了86%比上个版本提升了近14个百分点。
2. 借助于字符分割与识别算法的优化在general_test上的完整识别率(0-error)从原先的59%首次上升到现在的70%1-error则提升到了82%,提升巨大。
3. 在车牌判断模块中使用了新的SVM特征颜色+投影从而在保持鲁棒性的同时提升了正确率。定位指标中FScore从76%提升到82%.
4. 新增一种新的字符分割方法groundMSER字符分割方法。
5. 提供了近万张中文字符灰度图数据供训练并且在主界面中提供了一个方法从free大神的车牌集里提取中文与英文字符。
6. 提供了两万两千张的字符灰度图数据,供训练灰度字符模型使用。
7. 代码优化与升级许多bug修复。
8. Opencv3.2版本的支持编译前仅需要将config.h中将#define CV_VERSION_THREE_ZERO改为#define CV_VERSION_THREE_TWO即可。
9. 更加友好的linux与mac版本支持使用CMake即可顺利编译单独的utf-8与gbk的文件供分别的系统使用。
======
本次更新是EasyPR 1.5正式版本相比beta版本有以下几点更新
1.修正了SVM训练异常的问题现在1.5版本也可以自由的使用SVM训练了。这个问题确实是opencv的bug详见[讨论](https://github.com/opencv/opencv/issues/5054),在此感谢 @tka 同学的告知。
注意3.2的opencv也修正了这个问题如果你用3.2版本的话也可以。但是不清楚3.2版本是否会引入其他的问题在目前的EasyPR版本里即便用3.0或者3.1版本也可以规避训练异常的问题。
2.支持linux和mac编译如果碰到问题请在issue里提问。
3.增加一个无需配置opencv的[懒人版](http://git.oschina.net/easypr/EasyPR/attach_files)。仅仅支持vs2013也只能在debug和x86下运行其他情况的话还是得配置opencv。感谢范文捷同学的帮助。页面里的两个文件都要下载下载后用[7zip](http://www.7-zip.org/)解压。
其他的主要改进如下:
1.增加了一种新的基于文字定位的定位方法 (MSER), 在面对低对比度,低光照以及大图像上有较强的鲁棒性。
* 夜间的车牌图像
![夜间的车牌图像](resources/doc/res/night_1.jpg)
* 对比度非常低的图像
![对比度非常低的图像](resources/doc/res/contrast_1.jpg)
* 近距离的图像
![近距离的图像](resources/doc/res/near_1.jpg)
* 高分辨率的图像
![高分辨率的图像](resources/doc/res/big_1.jpg)
2.更加合理的评价协议。结合新增的GroundTruth文件与ICDAR2003的协议使得整体评价指标更为合理。通用数据集里同时增加了近50张新图片。文字定位方法在面对这些复杂图片时比先前的SOBEL+COLOR的方法定位率提升了27个百分点。
实际运行时使用了文字定位与颜色定位的结合最终对256张的测试图片的测试结果如下
![v1.5版运行结果](resources/doc/res/v1.5_result.jpg)
3.使用了非极大值抑制算法去除相邻的车牌,使得最终输出变的合理。即便使用多个定位方法,最终也只会输出一个车牌,而且是可能性最大的车牌。
4.基于局部空间的大津阈值算法与自适应阈值算法,提升了文字分割与分子识别的准确率。
* 车牌图像
![车牌图像](resources/doc/res/not_avg_contrast.jpg)
* 普通大津阈值结果
![普通大津阈值结果](resources/doc/res/normal_ostu.jpg)
* 空间大津阈值结果
![空间大津阈值结果](resources/doc/res/spatial_ostu.jpg)
5.新的SVM模型与特征LBP提升了车牌判断的鲁棒性新的中文ANN识别模型提升了中文识别的整体准确率近15个百分点。
6.增加了Grid Search方法可以进行自动调参。
7.首次增加了多线程支持基于OpenMP的文字定位方法在最终的识别速度上比原先的单线程方法提高了接近2倍。
8.替换了一部分中文注释使得windows下的visual studio在面对全部以LF结尾的文件时也能成功通过编译。目前的程序只要opencv配置正确gitosc上通过zip下载下来的程序可以直接通过编译并运行。
关于本次改动的具体内容可以看博客中的[介绍](http://www.cnblogs.com/subconscious/p/5637735.html)。
======
本次更新是1.4 正式版,主要改进在于几个方面:
1.代码统一为UTF-8格式多平台的Shell不再出现乱码。
2.支持opencv3.0与3.1注意这与opencv2.x不兼容要想支持的话请下载1.3版本。
3.ANN训练开放。
4.修正了SVM训练异常的问题。
5.代码优化。
不知道怎么下载以前的版本的小伙伴可以在github或gitosc的"branch"里选择"tags",然后点击"v1.3",再然后点击"download zip"。当然如果直接git clone的话可以随时方便切换。
在后面的版本中计划做以下几点改善:
1.新的评价框架,更加合理的评估数据。
2.新的车牌定位算法。
======
本次更新是1.3beta版,主要改进在于提升了字符识别模块的准确性:
@ -123,8 +19,10 @@ EasyPR版本更新
目前版本的问题是处理时间还是偏高1.3正式版本中会对这个问题进行fix。
======
本次更新是1.3alpha版,主要改进在于提升了字符识别模块的准确性:
平均字符差距从2.0降低到0.7完整匹配度从25%左右上升到目前的68%。
@ -141,8 +39,10 @@ EasyPR版本更新
目前版本的问题是处理时间大幅度上升1.3正式版本中会对这个问题进行fix。
======
本次更新是1.2版主要改进在于提升了车牌定位模块的准确性从70%左右到目前的94%,见下图:
![1.2版综合效果](resources/doc/res/testresult.png)
@ -165,8 +65,10 @@ EasyPR版本更新
* 与Linux版本做了整合可以实现跨平台编译。
======
目前EasyPR的版本是1.1相比上一个版本1.0,有以下更新(这次的更新内容较多,为了跟你现有的项目和代码不冲突,请
谨慎选择全部更新,最好新起一个目录试试新增的功能和内容):

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9955D685-A3FF-42E4-AF4B-4F6CE7A4B7F2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Demo</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>easypr_test</TargetName>
<OutDir>$(SolutionDir)\bin\debug\</OutDir>
<IntDir>$(Configuration)\Demo\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\bin\release\</OutDir>
<IntDir>$(Configuration)\Demo\</IntDir>
<TargetName>easypr_test</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\EasyPR\test\main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\EasyPR\test\accuracy.hpp" />
<ClInclude Include="..\EasyPR\test\chars.hpp" />
<ClInclude Include="..\EasyPR\test\plate.hpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="EasyPR.vcxproj">
<Project>{62add040-59c5-4d8e-a065-8c5d0cd777be}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -15,39 +15,19 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test\main.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="..\thirdparty\xmlParser\xmlParser.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\test\accuracy.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="..\test\chars.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="..\test\plate.hpp">
<ClInclude Include="..\EasyPR\test\accuracy.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="..\test\config.hpp">
<ClInclude Include="..\EasyPR\test\chars.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="..\test\result.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="..\thirdparty\xmlParser\xmlParser.h">
<ClInclude Include="..\EasyPR\test\plate.hpp">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\resources\result\accuracy.txt">
<Filter>资源文件</Filter>
</Text>
<Text Include="..\CMakeLists.txt">
<Filter>资源文件</Filter>
</Text>
<ClCompile Include="..\EasyPR\test\main.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
</Project>

@ -1,41 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "vcprojs\demo.vcxproj", "{FADCD7E1-8071-4F1C-8071-C469569C3B56}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EasyPR", "EasyPR.vcxproj", "{62ADD040-59C5-4D8E-A065-8C5D0CD777BE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeasypr", "vcprojs\libeasypr.vcxproj", "{2791E339-04FB-44EF-9F92-C90131FE7772}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FA4945DA-3C0F-44C5-90DF-A492614B8B4D}"
ProjectSection(SolutionItems) = preProject
Usage.md = Usage.md
EndProjectSection
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo", "Demo.vcxproj", "{9955D685-A3FF-42E4-AF4B-4F6CE7A4B7F2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Debug|Win32.ActiveCfg = Debug|Win32
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Debug|Win32.Build.0 = Debug|Win32
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Debug|x64.ActiveCfg = Debug|x64
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Debug|x64.Build.0 = Debug|x64
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Release|Win32.ActiveCfg = Release|Win32
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Release|Win32.Build.0 = Release|Win32
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Release|x64.ActiveCfg = Release|x64
{FADCD7E1-8071-4F1C-8071-C469569C3B56}.Release|x64.Build.0 = Release|x64
{2791E339-04FB-44EF-9F92-C90131FE7772}.Debug|Win32.ActiveCfg = Debug|Win32
{2791E339-04FB-44EF-9F92-C90131FE7772}.Debug|Win32.Build.0 = Debug|Win32
{2791E339-04FB-44EF-9F92-C90131FE7772}.Debug|x64.ActiveCfg = Debug|x64
{2791E339-04FB-44EF-9F92-C90131FE7772}.Debug|x64.Build.0 = Debug|x64
{2791E339-04FB-44EF-9F92-C90131FE7772}.Release|Win32.ActiveCfg = Release|Win32
{2791E339-04FB-44EF-9F92-C90131FE7772}.Release|Win32.Build.0 = Release|Win32
{2791E339-04FB-44EF-9F92-C90131FE7772}.Release|x64.ActiveCfg = Release|x64
{2791E339-04FB-44EF-9F92-C90131FE7772}.Release|x64.Build.0 = Release|x64
{62ADD040-59C5-4D8E-A065-8C5D0CD777BE}.Debug|Win32.ActiveCfg = Debug|Win32
{62ADD040-59C5-4D8E-A065-8C5D0CD777BE}.Debug|Win32.Build.0 = Debug|Win32
{62ADD040-59C5-4D8E-A065-8C5D0CD777BE}.Release|Win32.ActiveCfg = Release|Win32
{62ADD040-59C5-4D8E-A065-8C5D0CD777BE}.Release|Win32.Build.0 = Release|Win32
{9955D685-A3FF-42E4-AF4B-4F6CE7A4B7F2}.Debug|Win32.ActiveCfg = Debug|Win32
{9955D685-A3FF-42E4-AF4B-4F6CE7A4B7F2}.Debug|Win32.Build.0 = Debug|Win32
{9955D685-A3FF-42E4-AF4B-4F6CE7A4B7F2}.Release|Win32.ActiveCfg = Release|Win32
{9955D685-A3FF-42E4-AF4B-4F6CE7A4B7F2}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{62ADD040-59C5-4D8E-A065-8C5D0CD777BE}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>EasyPR</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="opencv.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<SourcePath>$(SourcePath)</SourcePath>
<TargetName>libeasypr</TargetName>
<OutDir>$(SolutionDir)\bin\debug\</OutDir>
<IntDir>$(Configuration)\EasyPR\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>libeasypr</TargetName>
<OutDir>$(SolutionDir)\bin\release\</OutDir>
<IntDir>$(Configuration)\EasyPR\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>opencv_calib3d2411d.lib;opencv_contrib2411d.lib;opencv_core2411d.lib;opencv_features2d2411d.lib;opencv_flann2411d.lib;opencv_gpu2411d.lib;opencv_highgui2411d.lib;opencv_imgproc2411d.lib;opencv_legacy2411d.lib;opencv_ml2411d.lib;opencv_nonfree2411d.lib;opencv_objdetect2411d.lib;opencv_ocl2411d.lib;opencv_photo2411d.lib;opencv_stitching2411d.lib;opencv_superres2411d.lib;opencv_ts2411d.lib;opencv_video2411d.lib;opencv_videostab2411d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Users\Micooz\Documents\opencv\build\x86\vc12\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>opencv_calib3d248d.lib;opencv_contrib248d.lib;opencv_core248d.lib;opencv_features2d248d.lib;opencv_calib3d2411.lib;opencv_contrib2411.lib;opencv_core2411.lib;opencv_features2d2411.lib;opencv_flann2411.lib;opencv_gpu2411.lib;opencv_highgui2411.lib;opencv_imgproc2411.lib;opencv_legacy2411.lib;opencv_ml2411.lib;opencv_nonfree2411.lib;opencv_objdetect2411.lib;opencv_ocl2411.lib;opencv_photo2411.lib;opencv_stitching2411.lib;opencv_superres2411.lib;opencv_ts2411.lib;opencv_video2411.lib;opencv_videostab2411.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Users\Micooz\Documents\opencv\build\x86\vc12\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="include\easypr.h" />
<ClInclude Include="include\easypr\api.hpp" />
<ClInclude Include="include\easypr\chars_identify.h" />
<ClInclude Include="include\easypr\chars_recognise.h" />
<ClInclude Include="include\easypr\chars_segment.h" />
<ClInclude Include="include\easypr\core_func.h" />
<ClInclude Include="include\easypr\feature.h" />
<ClInclude Include="include\easypr\plate.h" />
<ClInclude Include="include\easypr\plate_detect.h" />
<ClInclude Include="include\easypr\plate_judge.h" />
<ClInclude Include="include\easypr\plate_locate.h" />
<ClInclude Include="include\easypr\plate_recognize.h" />
<ClInclude Include="include\easypr\preprocess\deface.h" />
<ClInclude Include="include\easypr\preprocess\gdts.h" />
<ClInclude Include="include\easypr\preprocess\mc_data.h" />
<ClInclude Include="include\easypr\program_options.h" />
<ClInclude Include="include\easypr\svm_train.h" />
<ClInclude Include="include\easypr\util.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\core\chars_identify.cpp" />
<ClCompile Include="src\core\chars_recognise.cpp" />
<ClCompile Include="src\core\chars_segment.cpp" />
<ClCompile Include="src\core\core_func.cpp" />
<ClCompile Include="src\core\feature.cpp" />
<ClCompile Include="src\core\plate.cpp" />
<ClCompile Include="src\core\plate_detect.cpp" />
<ClCompile Include="src\core\plate_judge.cpp" />
<ClCompile Include="src\core\plate_locate.cpp" />
<ClCompile Include="src\core\plate_recognize.cpp" />
<ClCompile Include="src\preprocess\deface.cpp" />
<ClCompile Include="src\preprocess\gdts.cpp" />
<ClCompile Include="src\preprocess\mc_data.cpp" />
<ClCompile Include="src\train\ann_train.cpp" />
<ClCompile Include="src\train\svm_train.cpp" />
<ClCompile Include="src\util\program_options.cpp" />
<ClCompile Include="src\util\util.cpp" />
</ItemGroup>
<ItemGroup>
<Xml Include="resources\model\ann.xml" />
<Xml Include="resources\model\svm.xml" />
</ItemGroup>
<ItemGroup>
<Text Include="resources\image\GDSL.txt" />
<Text Include="resources\image\使用说明.txt" />
<Text Include="关于版权.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="头文件\easypr">
<UniqueIdentifier>{9bb276ae-c7dc-4518-9674-bad84e57b9ac}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\easypr\preprocess">
<UniqueIdentifier>{6d263c48-a60a-4d68-8c2d-be376356168a}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\core">
<UniqueIdentifier>{bab97015-644d-43a0-a50a-a10567a88dbe}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\preprocess">
<UniqueIdentifier>{9a417cf1-7356-4acc-8b03-2b23009aa1ff}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\train">
<UniqueIdentifier>{46477ca6-b57a-48af-b8a7-49b05c42319f}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\util">
<UniqueIdentifier>{53a5d227-5ea7-45e4-9533-ed69bff250fb}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\easypr.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\easypr\api.hpp">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\chars_identify.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\chars_recognise.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\chars_segment.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\core_func.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\feature.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\plate.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\plate_detect.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\plate_judge.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\plate_locate.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\plate_recognize.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\program_options.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\svm_train.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\util.h">
<Filter>头文件\easypr</Filter>
</ClInclude>
<ClInclude Include="include\easypr\preprocess\deface.h">
<Filter>头文件\easypr\preprocess</Filter>
</ClInclude>
<ClInclude Include="include\easypr\preprocess\gdts.h">
<Filter>头文件\easypr\preprocess</Filter>
</ClInclude>
<ClInclude Include="include\easypr\preprocess\mc_data.h">
<Filter>头文件\easypr\preprocess</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\core\chars_identify.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\chars_recognise.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\chars_segment.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\core_func.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\train\ann_train.cpp">
<Filter>源文件\train</Filter>
</ClCompile>
<ClCompile Include="src\train\svm_train.cpp">
<Filter>源文件\train</Filter>
</ClCompile>
<ClCompile Include="src\util\util.cpp">
<Filter>源文件\util</Filter>
</ClCompile>
<ClCompile Include="src\util\program_options.cpp">
<Filter>源文件\util</Filter>
</ClCompile>
<ClCompile Include="src\core\feature.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\plate.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_detect.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_judge.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_locate.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_recognize.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="src\preprocess\deface.cpp">
<Filter>源文件\preprocess</Filter>
</ClCompile>
<ClCompile Include="src\preprocess\gdts.cpp">
<Filter>源文件\preprocess</Filter>
</ClCompile>
<ClCompile Include="src\preprocess\mc_data.cpp">
<Filter>源文件\preprocess</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Xml Include="resources\model\ann.xml">
<Filter>资源文件</Filter>
</Xml>
<Xml Include="resources\model\svm.xml">
<Filter>资源文件</Filter>
</Xml>
</ItemGroup>
<ItemGroup>
<Text Include="关于版权.txt" />
<Text Include="resources\image\使用说明.txt" />
<Text Include="resources\image\GDSL.txt" />
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

@ -1,200 +0,0 @@
# 使用
### 获取源代码
可以访问我们的项目主页获取代码:
* [github](https://github.com/liuruoze/EasyPR)
* [oschina](https://git.oschina.net/easypr/EasyPR)
如果你熟悉git版本控制工具可以使用下面的命令从 Github 克隆代码:
$ git clone https://github.com/liuruoze/EasyPR
### 准备工作
1. 安装OpenCV
从 [OpenCV官方网站](http://opencv.org/) 获取对应平台的 `OpenCV3.1.0`
EasyPR支持当前主流的操作系统通常不需要对源代码进行更改就可以编译运行尽管如此不同平台上IDE的配置也是有很大差异的下面主要说明WindowsLinux以及Mac OS下的编译方法。
#### Windows
对于使用 Windows 的同学建议的IDE是Visual Studio如果使用的不是VS请自行配置也欢迎分享你的配置方案。
|环境 | 需求
|------|----------
| 操作系统 | 64位Windows7 sp1 / Windows 8 及以上
| Visual Studio | vs2013 / vs2015
| Python可选 | Python3.*
**Note**: 预编译的 **OpenCV3.1** 已经不支持较低版本的Visual Studio请选择vs2013及以上的版本。
**方法一**
**注意**: python方法仅针对v1.5以下的版本。在1.6及以上版本中,由于架构变化,不推荐使用。可以加群看群里的配置方法。
1. 确保将Python的安装目录添加到系统环境变量PATH中。
2. 执行 `python configure.py` ,根据提示填写相关信息。
3. 打开解决方案文件 `EasyPR.sln`,直接编译运行即可。
**方法二**
打开解决方案文件 `EasyPR.sln`,该解决方案会加载两个项目:
* `EasyPR`用于编译src/下的源文件生成静态库`libeasypr.lib`
* `Demo`用来编译test/下的main.cpp并链接libeasypr.lib生成可执行程序。
**配置OpenCV**
OpenCV for Windows 通常会将使用VS编译好二进制文件放到 `opencv\build\` 目录下。
解决方案自动加载的两个项目配置不符合你的环境,请依次手动配置:
**demo**
| 配置项 | 值
|-------------|-----------
| `C/C++`-`附加包含目录` | **[opencv的include目录]**;$(SolutionDir)include
| `链接器`-`附加库目录` | **[opencv的lib目录]**
| `链接器`-`输入`-`附加依赖项` | **opencv_world310d.lib**;%(AdditionalDependencies)
*Note*Debug版本为**opencv_world310d.lib**Release版本为**opencv_world310.lib**
**libeasypr**
| 配置项 | 值
|-------------|-----------
| `C/C++`-`附加包含目录` | **[opencv的include目录]**;$(SolutionDir)include
**编译**
默认情况下,生成的 `demo.exe` 会放在项目根目录下。
**Note**: 直接双击运行程序会出现找不到opencv动态库的情况这个时候有两个办法
* 在`opencv\build\x64\vc(..)\bin`下找到缺失的dll放到执行目录下。
* 将上述bin目录添加到系统环境变量**PATH**中,然后重新运行程序。
**参考**windows平台下的opencv的手动配置可以参考这份[博客](http://my.phirobot.com/blog/2014-02-opencv_configuration_in_vs.html)。
#### Linux & Mac OS
EasyPR使用CMake在Linux及Mac OS下进行构建确保系统安装了最新版本的[CMake](http://cmake.org)。
为了避免系统中安装的老版本opencv对编译的影响需要在 `CMakeLists.txt` 中修改:
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/opencv3")
路径指向opencv3的安装目录该目录下应该有OpenCV的CMake配置文件。
项目提供了一键编译shell在项目根目录下执行
```
$ ./build.sh
```
即可。
----
**Note**: *你可以直接利用 EasyPR/include 和编译生成的静态库来调用EasyPR提供的函数接口编写自己的程序。*
运行Demo
```
$ ./demo // 进入菜单交互界面
$ ./demo ? // 查看CLI帮助
```
### 如何开始
当进入交互界面以后,首先是主目录,下面是主目录各个功能的解释:
| 名称 | 说明
|-------------|-----------
| 测试 | 分别测试车牌识别中每个环节。要想更改测试的图片可以替换resources/image下的图片
| 批量测试 | 跑完整个general_test下所有图片输出准确率等指标用于评估EasyPR的效果
| SVM训练 | 用SVM训练车牌判断模型
| ANN训练 | 用ANN训练字符识别和中文识别模型对应ann.xml和ann_chinese.xml
| 中文训练 | 1.6版新增用ANN模型训练灰度中文字符生成annCh.xml
| 生成字符 | 需要配合plates_200k这个数据集才能作用
当成功运行EasyPR后首先运行批量测试功能。如果最后的指标跟readme一致说明EasyPR安装成功。
可以在accuracy.hpp中修改 `pr.setResultShow(false)``pr.setResultShow(true)` 让批量测试显示出车牌定位的效果。
**Note**:
在批量测试下有一个选项native_test。可以把自己的图片放到resources/image/native_test下测试用的。如果你自己的图片没有ground_truth无法计算准确率指标。但是可以打开车牌定位的效果。
如果想评估车牌定位的指标。需要生成GroundTruth_windows.xml和GroundTruth_others.xml。可以参考general_test下的同名文件来了解下这个文件的格式该如何定义。例如下面的一个xml节点
```xml
<taggedRectangle x="170" y="184" width="96" height="27" rotation="-1" locateType="1">蓝牌:京A88731</taggedRectangle>
```
taggedRectangle对应一个车牌属性x和y表示的是车牌外接矩形的中心点的坐标。width和height是宽度和高度。另外两个属性目前没用到。
GroundTruth_windows.xml的编码需要设置为ANSI而GroundTruth_others.xml的编码要设置为UTF-8否则会出现乱码。
### 命令行示例
可以向 `demo[.exe]` 传递命令行参数来完成你想要的工作目前Demo支持5个子命令。对于每个子命令的帮助信息可以传入 `-h` 参数来获取。
**车牌识别**
# 利用提供的SVM和ANN模型来识别一张图片里面的所有车牌
$ ./demo recognize -p resources/image/plate_recognize.jpg --svm model/svm.xml --ann model/ann.xml
# 或者更简单一些(注意模型路径)
$ ./demo recognize -p resources/image/plate_recognize.jpg
**SVM训练**
新版本的EasyPR大大简化了SVM训练
# 首先准备好车牌图片集合plates/
# 是车牌的放在plates/has/
# 不是车牌的放在plates/no/
# 车牌可从项目resources/train/svm.7z中解压得到。
$ ./demo svm --plates=path/to/your/plates --svm=save/to/svm.xml
# 该命令将70%的车牌作为训练数据另外30%的车牌作为测试数据,
# 这个只可在 include/easypr/config.h 修改。
# 将训练好的模型存放在 save/to/svm.xml。
首先在easypr的主目录下面新建了一个tmp文件夹并且把svm.7z解压得到的svm文件夹移动到tmp文件夹下面
执行 $ demo svm --plates=tmp/svm --svm=tmp/svm.xml生成得到的tmp文件夹下面的svm.xml就是训练好的模型
替换model/svm.xml就可以达到替换新模型的目的替换前请先备份原始模型。
**ANN训练**
先准备好字符图片集合可从项目resources/train/ann.7z中解压得到。
每类字符都存放在以其名称命名的子文件夹中,命名规则请参考 `resources/text/province_mapping`
一切准备就绪后,运行下面这条命令即可:
$ ./demo ann --chars=path/to/chars --ann=save/to/ann.xml
首先在easypr的主目录下面新建了一个tmp文件夹并且把ann.7z解压得到的ann文件夹移动到tmp文件夹下面
执行 $ demo ann --chars=tmp/ann --ann=tmp/ann.xml生成得到的tmp文件夹下面的svm.xml就是训练好的模型
替换model/ann.xml就可以达到替换新模型的目的替换前请先备份原始模型。
**注意**
train文件夹下有3个ann压缩包解释一下
| 文件 | 用途
|-------------|-----------
| ann.7z | 包括黑白的字符和中文数据ann以及ann_chinese.xml由这个训练得到
| annCh.7z | 仅仅包括中文的灰度数据annCh.xml由这个训练得到
| annGray.7z | 包括了灰度的字符数据目前没有任何模型由这个训练得到主要是为未来的CNN做准备

File diff suppressed because it is too large Load Diff

@ -1,7 +0,0 @@
#!/usr/bin/env bash
rm -rf build
mkdir build
cd build
cmake ..
make -j8

@ -1,158 +0,0 @@
# -*- coding: utf-8 -*-
# --------------------------------------------------------------------
# EasyPR auto configure script
# --------------------------------------------------------------------
#
# This script configures OpenCV3.1 for Visual Studio
# on Windows.
#
# You are required to have Python3.* installed, and python.exe must
# be added to your PATH (C:\Python34 for example).
#
# You can use it by executing:
#
# C:\> cd path\to\EasyPR
# C:\> python configure.py
#
# Note: compatible with python3, haven't been tested on python2.
#
# --------------------------------------------------------------------
import os
import re
kProjectDir = "vcprojs"
kProjects = ["libeasypr.vcxproj", "demo.vcxproj"]
kProjectTemplates = ["libeasypr.vcxproj.template", "demo.vcxproj.template"]
kOpenCVConfig = "OpenCVConfig-version.cmake"
kConfig = {
"build": "",
"include": "",
"library": "",
"link": ["opencv_world310"],
"bit": "",
"vs": ""
}
kPatterns = {
"include": "(<AdditionalIncludeDirectories>)(.*?)(</AdditionalIncludeDirectories>)",
"library": "(<AdditionalLibraryDirectories>)(.*?)(</AdditionalLibraryDirectories>)",
"link": "(<AdditionalDependencies>)(.*?)(</AdditionalDependencies>)"
}
kReplacements = {
"include": r"\1%s;\2\3",
"library": r'\1%s\3',
"link": r'\1%s;\2\3'
}
def configure():
for i in range(2):
print(">> creating %s" % kProjects[i])
tpath = os.path.join(kProjectDir, kProjectTemplates[i])
fp = open(tpath, encoding="utf-8")
try:
# read from disk
original = fp.read()
nstring = ""
if 0 == i:
nstring = configure_libeasypr(original)
elif 1 == i:
nstring = configure_demo(original)
# write to disk
wpath = os.path.join(kProjectDir, kProjects[i])
writer = open(wpath, mode="wb")
try:
writer.write(nstring.encode())
finally:
writer.close()
finally:
fp.close()
print(">> all done! Open EasyPR.sln and have fun!")
def configure_libeasypr(buffer):
# additional include dir
pattern = re.compile(kPatterns["include"])
return pattern.sub(kReplacements["include"] %
(kConfig["include"][:2] + re.escape(kConfig["include"][2:])),
buffer)
def configure_demo(buffer):
# additional include dir
pattern = re.compile(kPatterns["include"])
nstring = pattern.sub(kReplacements["include"] %
(kConfig["include"][:2] + re.escape(kConfig["include"][2:])),
buffer)
# additional library dir
pattern = re.compile(kPatterns["library"])
nstring = pattern.sub(kReplacements["library"] %
(kConfig["library"][:2] + re.escape(kConfig["library"][2:])),
nstring)
# additional dependencies
#lib_string = ""
#for lib in kConfig["link"]:
# lib_string += (lib + "d.lib")
#pattern = re.compile(kPatterns["link"])
#return pattern.sub(kReplacements["link"] % lib_string, nstring)
return nstring
def check_opencv_version():
file = os.path.join(kConfig["build"], kOpenCVConfig)
print(">> Checking ", file)
fp = open(file)
opencv_version = 0
try:
fline = fp.readline()
match = re.search(r"OpenCV_VERSION (\d)\.(\d)\.(\d{,2})", fline)
if match is not None:
opencv_version = match.group(1) + "." + match.group(2)
finally:
fp.close()
return opencv_version
def cli():
while True:
root_ = input(r"Where is your opencv root path? (e.g, C:\path\to\opencv3): ")
if os.path.exists(root_):
kConfig["build"] = os.path.join(root_, "build")
kConfig["include"] = os.path.join(kConfig["build"], "include")
break
else:
print("Invalid path")
if check_opencv_version() != "3.1":
print("requires opencv 3.1")
exit()
kConfig["bit"] = "x64"
while True:
vc = input("Which Visual Studio you are using? (vs2013 or vs2015): ")
if vc == "vs2013":
kConfig["vs"] = "vc12"
break
elif vc == "vs2015":
kConfig["vs"] = "vc14"
break
else:
print("Please type vs2013 or vs2015")
kConfig["library"] = os.path.normpath("%s/%s/%s/lib/" % (kConfig["build"], kConfig["bit"], kConfig["vs"]))
if __name__ == "__main__":
cli()
configure()

@ -1,13 +1,12 @@
#ifndef EASYPR_EASYPR_H
#define EASYPR_EASYPR_H
#include "easypr/core/plate_recognize.h"
#include "easypr/train/svm_train.h"
#include "easypr/train/ann_train.h"
#include "easypr/train/annCh_train.h"
#include "easypr/util/util.h"
#include "easypr/util/program_options.h"
#include "easypr/plate_recognize.h"
#include "easypr/svm_train.h"
#include "easypr/preprocess/mc_data.h"
#include "easypr/preprocess/gdts.h"
#include "easypr/preprocess/deface.h"
#include "easypr/util.h"
#include "easypr/api.hpp"
#include "easypr/config.h"
#endif //EASYPR_EASYPR_H

@ -6,21 +6,24 @@
#include <string>
#include <vector>
#include "opencv2/opencv.hpp"
#include "easypr/config.h"
#include <opencv2/opencv.hpp>
namespace easypr {
namespace api {
static bool plate_judge(const char* image, const char* model) {
static bool plate_judge(const char* image,const char *model) {
cv::Mat src = cv::imread(image);
assert(!src.empty());
CPlateJudge judger;
judger.LoadModel(model);
int result;
result = PlateJudge::instance()->plateJudge(src);
judger.plateJudge(src, result);
return result == 0;
return result == 1;
}
static void plate_locate(const char* image, const bool life_mode = true) {
@ -33,6 +36,7 @@ static void plate_locate(const char* image, const bool life_mode = true) {
plate.setLifemode(life_mode);
std::vector<cv::Mat> results;
plate.plateLocate(src, results);
}
@ -41,30 +45,17 @@ static std::vector<std::string> plate_recognize(const char* image,
const char* model_ann,
const bool life_mode = true) {
cv::Mat img = cv::imread(image);
assert(!img.empty());
CPlateRecognize pr;
pr.setResultShow(false);
pr.setLifemode(true);
pr.setMaxPlates(1);
pr.setDetectType(PR_DETECT_CMSER | PR_DETECT_COLOR);
pr.LoadSVM(model_svm);
pr.LoadANN(model_ann);
pr.setLifemode(life_mode);
pr.setDebug(false);
std::vector<std::string> results;
std::vector<CPlate> plates;
pr.plateRecognize(img, plates, 0);
for (auto plate : plates) {
results.push_back(plate.getPlateStr());
}
if (plates.size() == 1) {
if (1) {
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "result.jpg";
imwrite(ss.str(), plates.at(0).getPlateMat());
}
}
pr.plateRecognize(img, results);
return std::move(results);
}
@ -76,7 +67,10 @@ static Color get_plate_color(const char* image) {
return getPlateType(img, true);
}
}
}
#endif // EASYPR_API_HPP
#endif //EASYPR_API_HPP

@ -0,0 +1,63 @@
//////////////////////////////////////////////////////////////////////////
// Name: chars_identify Header
// Version: 1.0
// Date: 2014-09-25
// Author: liuruoze
// Copyright: liuruoze
// Reference: Mastering OpenCV with Practical Computer Vision Projects
// Reference: CSDN Bloger taotao1233
// Desciption:
// Defines CCharsIdentify
//////////////////////////////////////////////////////////////////////////
#ifndef __CHARS_IDENTIFY_H__
#define __CHARS_IDENTIFY_H__
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsIdentify {
public:
CCharsIdentify();
//! 字符分割
string charsIdentify(Mat, bool, bool);
string charsIdentify(Mat input);
//! 字符分类
int classify(Mat, bool, bool);
int classify(Mat f);
//! 装载ANN模型
void LoadModel();
//! 装载ANN模型
void LoadModel(string s);
//! 设置与读取模型路径
inline void setModelPath(string path) { m_path = path; }
inline string getModelPath() const { return m_path; }
private:
//使用的ANN模型
CvANN_MLP ann;
//! 模型存储路径
string m_path;
//! 特征尺寸
int m_predictSize;
//! 省份对应map
std::map<string, string> m_map;
};
} /* \namespace easypr */
#endif /* endif __CHARS_IDENTIFY_H__ */

@ -9,16 +9,15 @@
// Desciption:
// Defines CCharsRecognise
//////////////////////////////////////////////////////////////////////////
#ifndef EASYPR_CORE_CHARSRECOGNISE_H_
#define EASYPR_CORE_CHARSRECOGNISE_H_
#ifndef __CHARS_RECOGNISE_H__
#define __CHARS_RECOGNISE_H__
#include "easypr/core/chars_segment.h"
#include "easypr/core/chars_identify.h"
#include "easypr/core/core_func.h"
#include "easypr/util/util.h"
#include "easypr/core/plate.hpp"
#include "easypr/config.h"
#include "easypr/chars_segment.h"
#include "easypr/chars_identify.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsRecognise {
@ -27,32 +26,30 @@ class CCharsRecognise {
~CCharsRecognise();
int charsRecognise(cv::Mat plate, std::string& plateLicense);
int charsRecognise(CPlate& plate, std::string& plateLicense);
//! 字符分割与识别
int charsRecognise(Mat, String&);
inline std::string getPlateColor(cv::Mat input) const {
std::string color = "未知";
Color result = getPlateType(input, true);
if (BLUE == result) color = "蓝牌";
if (YELLOW == result) color = "黄牌";
if (WHITE == result) color = "白牌";
#ifdef OS_WINDOWS
color = utils::utf8_to_gbk(color.c_str());
#endif
return color;
}
string charsRecognise(Mat plate);
//! 装载ANN模型
void LoadANN(string s);
//! 是否开启调试模式
inline void setCRDebug(int param) { m_charsSegment->setDebug(param); }
inline std::string getPlateColor(Color in) const {
std::string color = "未知";
if (BLUE == in) color = "蓝牌";
if (YELLOW == in) color = "黄牌";
if (WHITE == in) color = "白牌";
#ifdef OS_WINDOWS
color = utils::utf8_to_gbk(color.c_str());
#endif
//! 获取调试模式状态
inline int getCRDebug() { return m_charsSegment->getDebug(); }
//! 获得车牌颜色
inline string getPlateColor(Mat input) const {
string color = "未知";
Color result = getPlateType(input, true);
if (BLUE == result) color = "蓝牌";
if (YELLOW == result) color = "黄牌";
return color;
}
//! 设置变量
inline void setLiuDingSize(int param) {
m_charsSegment->setLiuDingSize(param);
}
@ -73,11 +70,13 @@ class CCharsRecognise {
}
private:
//!字符分割
//!字符分割
CCharsSegment* m_charsSegment;
//! 字符识别
CCharsIdentify* m_charsIdentify;
};
} /* \namespace easypr */
#endif // EASYPR_CORE_CHARSRECOGNISE_H_
#endif /* endif __CHARS_RECOGNISE_H__ */

@ -0,0 +1,96 @@
//////////////////////////////////////////////////////////////////////////
// Name: chars_segment Header
// Version: 1.0
// Date: 2014-09-19
// Author: liuruoze
// Copyright: liuruoze
// Reference: Mastering OpenCV with Practical Computer Vision Projects
// Reference: CSDN Bloger taotao1233
// Desciption:
// Defines CCharsSegment
//////////////////////////////////////////////////////////////////////////
#ifndef __CHARS_SEGMENT_H__
#define __CHARS_SEGMENT_H__
#include "core_func.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharsSegment {
public:
CCharsSegment();
//! 字符分割
int charsSegment(Mat, vector<Mat>&);
//! 字符尺寸验证
bool verifyCharSizes(Mat r);
//! 字符预处理
Mat preprocessChar(Mat in);
//! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect GetChineseRect(const Rect rectSpe);
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
int GetSpecificRect(const vector<Rect>& vecRect);
//! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect,
int specIndex);
//! 将Rect按位置从左到右进行排序
int SortRect(const vector<Rect>& vecRect, vector<Rect>& out);
//! 设置变量
inline void setLiuDingSize(int param) { m_LiuDingSize = param; }
inline void setColorThreshold(int param) { m_ColorThreshold = param; }
inline void setBluePercent(float param) { m_BluePercent = param; }
inline float getBluePercent() const { return m_BluePercent; }
inline void setWhitePercent(float param) { m_WhitePercent = param; }
inline float getWhitePercent() const { return m_WhitePercent; }
//! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 1;
//! preprocessChar所用常量
static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1;
static const int VERTICAL = 0;
//! preprocessChar所用常量
static const int DEFAULT_LIUDING_SIZE = 7;
static const int DEFAULT_MAT_WIDTH = 136;
static const int DEFAULT_COLORTHRESHOLD = 150;
//! 是否开启调试模式
inline void setDebug(int param) { m_debug = param; }
//! 获取调试模式状态
inline int getDebug() { return m_debug; }
private:
//!柳钉判断参数
int m_LiuDingSize;
//!车牌大小参数
int m_theMatWidth;
//!车牌颜色判断参数
int m_ColorThreshold;
float m_BluePercent;
float m_WhitePercent;
//! 是否开启调试模式0关闭非0开启
int m_debug;
};
} /* \namespace easypr */
#endif /* endif __CHARS_SEGMENT_H__ */

@ -1,148 +0,0 @@
#ifndef EASYPR_CONFIG_H_
#define EASYPR_CONFIG_H_
#define CV_VERSION_THREE_ZERO
namespace easypr {
enum Color { BLUE, YELLOW, WHITE, UNKNOWN };
enum LocateType { SOBEL, COLOR, CMSER, OTHER };
enum CharSearchDirection { LEFT, RIGHT };
enum
{
PR_MODE_UNCONSTRAINED,
PR_MODE_CAMERPOHNE,
PR_MODE_PARKING,
PR_MODE_HIGHWAY
};
enum
{
PR_DETECT_SOBEL = 0x01, /**Sobel detect type, using twice Sobel */
PR_DETECT_COLOR = 0x02, /**Color detect type */
PR_DETECT_CMSER = 0x04, /**Character detect type, using mser */
};
static const char* kDefaultSvmPath = "model/svm_hist.xml";
static const char* kLBPSvmPath = "model/svm_lbp.xml";
static const char* kHistSvmPath = "model/svm_hist.xml";
static const char* kDefaultAnnPath = "model/ann.xml";
static const char* kChineseAnnPath = "model/ann_chinese.xml";
static const char* kGrayAnnPath = "model/annCh.xml";
//This is important to for key transform to chinese
static const char* kChineseMappingPath = "model/province_mapping";
typedef enum {
kForward = 1, // correspond to "has plate"
kInverse = 0 // correspond to "no plate"
} SvmLabel;
static const int kPlateResizeWidth = 136;
static const int kPlateResizeHeight = 36;
static const int kShowWindowWidth = 1000;
static const int kShowWindowHeight = 800;
static const float kSvmPercentage = 0.7f;
static const int kCharacterInput = 120;
static const int kChineseInput = 440;
static const int kAnnInput = kCharacterInput;
static const int kCharacterSize = 10;
static const int kChineseSize = 20;
static const int kPredictSize = kCharacterSize;
static const int kNeurons = 40;
static const char *kChars[] = {
"0", "1", "2",
"3", "4", "5",
"6", "7", "8",
"9",
/* 10 */
"A", "B", "C",
"D", "E", "F",
"G", "H", /* {"I", "I"} */
"J", "K", "L",
"M", "N", /* {"O", "O"} */
"P", "Q", "R",
"S", "T", "U",
"V", "W", "X",
"Y", "Z",
/* 24 */
"zh_cuan" , "zh_e" , "zh_gan" ,
"zh_gan1" , "zh_gui" , "zh_gui1" ,
"zh_hei" , "zh_hu" , "zh_ji" ,
"zh_jin" , "zh_jing" , "zh_jl" ,
"zh_liao" , "zh_lu" , "zh_meng" ,
"zh_min" , "zh_ning" , "zh_qing" ,
"zh_qiong", "zh_shan" , "zh_su" ,
"zh_sx" , "zh_wan" , "zh_xiang",
"zh_xin" , "zh_yu" , "zh_yu1" ,
"zh_yue" , "zh_yun" , "zh_zang" ,
"zh_zhe"
/* 31 */
};
static const int kCharactersNumber = 34;
static const int kChineseNumber = 31;
static const int kCharsTotalNumber = 65;
static bool kDebug = false;
static const int kGrayCharWidth = 20;
static const int kGrayCharHeight = 32;
static const int kCharLBPGridX = 4;
static const int kCharLBPGridY = 4;
static const int kCharLBPPatterns = 16;
static const int kCharHiddenNeurans = 64;
static const int kCharsCountInOnePlate = 7;
static const int kSymbolsCountInChinesePlate = 6;
static const float kPlateMaxSymbolCount = 7.5f;
static const int kSymbolIndex = 2;
// Disable the copy and assignment operator for this class.
#define DISABLE_ASSIGN_AND_COPY(className) \
private:\
className& operator=(const className&); \
className(const className&)
// Display the image.
#define SET_DEBUG(param) \
kDebug = param
// Display the image.
#define SHOW_IMAGE(imgName, debug) \
if (debug) { \
namedWindow("imgName", WINDOW_AUTOSIZE); \
moveWindow("imgName", 500, 500); \
imshow("imgName", imgName); \
waitKey(0); \
destroyWindow("imgName"); \
}
// Load model. compatitable withe 3.0, 3.1 and 3.2
#ifdef CV_VERSION_THREE_TWO
#define LOAD_SVM_MODEL(model, path) \
model = ml::SVM::load(path);
#define LOAD_ANN_MODEL(model, path) \
model = ml::ANN_MLP::load(path);
#else
#define LOAD_SVM_MODEL(model, path) \
model = ml::SVM::load<ml::SVM>(path);
#define LOAD_ANN_MODEL(model, path) \
model = ml::ANN_MLP::load<ml::ANN_MLP>(path);
#endif
}
#endif // EASYPR_CONFIG_H_

@ -1,131 +0,0 @@
//////////////////////////////////////////////////////////////////////////
// Name: CHARACTER Header
// Version: 1.0
// Date: 2016-06-14
// Author: liuruoze
// Copyright: liuruoze
// Desciption:
// An abstract class for car character in plate.
//////////////////////////////////////////////////////////////////////////
#ifndef EASYPR_CORE_CHARACTER_H_
#define EASYPR_CORE_CHARACTER_H_
#include "opencv2/opencv.hpp"
using namespace cv;
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
class CCharacter {
public:
CCharacter()
{
m_characterMat = Mat();
m_characterGrayMat = Mat();
m_characterPos = Rect();
m_characterStr = "";
m_score = 0;
m_isChinese = false;
m_ostuLevel = 125;
m_center = Point(0, 0);
m_index = 0;
}
CCharacter(const CCharacter& other)
{
m_characterMat = other.m_characterMat;
m_characterGrayMat = other.m_characterGrayMat;
m_characterPos = other.m_characterPos;
m_characterStr = other.m_characterStr;
m_score = other.m_score;
m_isChinese = other.m_isChinese;
m_ostuLevel = other.m_ostuLevel;
m_center = other.m_center;
m_index = other.m_index;
}
inline void setCharacterMat(Mat param) { m_characterMat = param; }
inline Mat getCharacterMat() const { return m_characterMat; }
inline void setCharacterGrayMat(Mat param) { m_characterGrayMat = param; }
inline Mat getCharacterGrayMat() const { return m_characterGrayMat; }
inline void setCharacterPos(Rect param) { m_characterPos = param; }
inline Rect getCharacterPos() const { return m_characterPos; }
inline void setCharacterStr(String param) { m_characterStr = param; }
inline String getCharacterStr() const { return m_characterStr; }
inline void setCharacterScore(double param) { m_score = param; }
inline double getCharacterScore() const { return m_score; }
inline void setIsChinese(bool param) { m_isChinese = param; }
inline bool getIsChinese() const { return m_isChinese; }
inline void setOstuLevel(double param) { m_ostuLevel = param; }
inline double getOstuLevel() const { return m_ostuLevel; }
inline void setCenterPoint(Point param) { m_center = param; }
inline Point getCenterPoint() const { return m_center; }
inline void setIndex(int param) { m_index = param; }
inline int getIndex() const { return m_index; }
inline bool getIsStrong() const { return m_score >= 0.9; }
inline bool getIsWeak() const { return m_score < 0.9 && m_score >= 0.5; }
inline bool getIsLittle() const { return m_score < 0.5; }
bool operator < (const CCharacter& other) const
{
return (m_score > other.m_score);
}
bool operator < (const CCharacter& other)
{
return (m_score > other.m_score);
}
private:
//! character mat
Mat m_characterMat;
//! character gray mat
Mat m_characterGrayMat;
//! character rect
Rect m_characterPos;
//! character str
String m_characterStr;
//! character likely
double m_score;
//! weather is chinese
bool m_isChinese;
//! ostu level
double m_ostuLevel;
//! center point
Point m_center;
//! the postion in the plate, from 1 to 7 normal
int m_index;
////! m_score >= 0.9
//bool isStrong;
////! m_score < 0.9 && m_score >= 0.5
//bool isWeak;
////! m_score < 0.5
//bool isLittle;
};
} /*! \namespace easypr*/
#endif // EASYPR_CORE_PLATE_H_

@ -1,58 +0,0 @@
#ifndef EASYPR_CORE_CHARSIDENTIFY_H_
#define EASYPR_CORE_CHARSIDENTIFY_H_
#include <memory>
#include "opencv2/opencv.hpp"
#include "easypr/util/kv.h"
#include "easypr/core/character.hpp"
#include "easypr/core/feature.h"
namespace easypr {
class CharsIdentify {
public:
static CharsIdentify* instance();
int classify(cv::Mat f, float& maxVal, bool isChinses = false, bool isAlphabet = false);
void classify(cv::Mat featureRows, std::vector<int>& out_maxIndexs,
std::vector<float>& out_maxVals, std::vector<bool> isChineseVec);
void classify(std::vector<CCharacter>& charVec);
void classifyChinese(std::vector<CCharacter>& charVec);
void classifyChineseGray(std::vector<CCharacter>& charVec);
std::pair<std::string, std::string> identify(cv::Mat input, bool isChinese = false, bool isAlphabet = false);
int identify(std::vector<cv::Mat> inputs, std::vector<std::pair<std::string, std::string>>& outputs,
std::vector<bool> isChineseVec);
std::pair<std::string, std::string> identifyChinese(cv::Mat input, float& result, bool& isChinese);
std::pair<std::string, std::string> identifyChineseGray(cv::Mat input, float& result, bool& isChinese);
bool isCharacter(cv::Mat input, std::string& label, float& maxVal, bool isChinese = false);
void LoadModel(std::string path);
void LoadChineseModel(std::string path);
void LoadGrayChANN(std::string path);
void LoadChineseMapping(std::string path);
private:
CharsIdentify();
annCallback extractFeature;
static CharsIdentify* instance_;
// binary character classifer
cv::Ptr<cv::ml::ANN_MLP> ann_;
// binary character classifer, only for chinese
cv::Ptr<cv::ml::ANN_MLP> annChinese_;
// gray classifer, only for chinese
cv::Ptr<cv::ml::ANN_MLP> annGray_;
// used for chinese mapping
std::shared_ptr<Kv> kv_;
};
}
#endif // EASYPR_CORE_CHARSIDENTIFY_H_

@ -1,84 +0,0 @@
#ifndef EASYPR_CORE_CHARSSEGMENT_H_
#define EASYPR_CORE_CHARSSEGMENT_H_
#include "opencv2/opencv.hpp"
#include "easypr/config.h"
using namespace cv;
using namespace std;
namespace easypr {
class CCharsSegment {
public:
CCharsSegment();
//! using ostu algotithm the segment chars in plate
int charsSegment(Mat input, std::vector<Mat>& resultVec, Color color = BLUE);
//! using methods to segment chars in plate
int charsSegmentUsingOSTU(Mat input, std::vector<Mat>& resultVec, std::vector<Mat>& grayChars, Color color = BLUE);
int charsSegmentUsingMSER(Mat input, vector<Mat>& resultVec, vector<Mat>& grayChars, Color color = BLUE);
//! using project
int projectSegment(const Mat& input, Color color, vector<int>& out_indexs);
bool verifyCharSizes(Mat r);
// find the best chinese binaranzation method
void judgeChinese(Mat in, Mat& out, Color plateType);
void judgeChineseGray(Mat in, Mat& out, Color plateType);
Mat preprocessChar(Mat in);
//! to find the position of chinese
Rect GetChineseRect(const Rect rectSpe);
//! find the character refer to city, like "suA" A
int GetSpecificRect(const std::vector<Rect>& vecRect);
//! Do two things
// 1.remove rect in the left of city character
// 2.from the city rect, to the right, choose 6 rects
int RebuildRect(const std::vector<Rect>& vecRect, std::vector<Rect>& outRect,
int specIndex);
int SortRect(const std::vector<Rect>& vecRect, std::vector<Rect>& out);
inline void setLiuDingSize(int param) { m_LiuDingSize = param; }
inline void setColorThreshold(int param) { m_ColorThreshold = param; }
inline void setBluePercent(float param) { m_BluePercent = param; }
inline float getBluePercent() const { return m_BluePercent; }
inline void setWhitePercent(float param) { m_WhitePercent = param; }
inline float getWhitePercent() const { return m_WhitePercent; }
static const int DEFAULT_DEBUG = 1;
static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1;
static const int VERTICAL = 0;
static const int DEFAULT_LIUDING_SIZE = 7;
static const int DEFAULT_MAT_WIDTH = 136;
static const int DEFAULT_COLORTHRESHOLD = 150;
inline void setDebug(int param) { m_debug = param; }
inline int getDebug() { return m_debug; }
private:
int m_LiuDingSize;
int m_theMatWidth;
int m_ColorThreshold;
float m_BluePercent;
float m_WhitePercent;
int m_debug;
};
}
#endif // EASYPR_CORE_CHARSSEGMENT_H_

@ -1,159 +0,0 @@
#ifndef EASYPR_CORE_COREFUNC_H_
#define EASYPR_CORE_COREFUNC_H_
#include "opencv2/opencv.hpp"
#include "easypr/core/plate.hpp"
#include "easypr/core/character.hpp"
using namespace cv;
using namespace std;
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
//! find binary image match to color
//! input rgb, want match color ( blue or yellow)
//! out grey, 255 is match, 0 is not match
Mat colorMatch(const Mat& src, Mat& match, const Color r,
const bool adaptive_minsv);
//Mat mserMatch(const Mat& src, Mat& match, const Color r,
// std::vector<RotatedRect>& plateRect, std::vector<Rect>& out_charRect);
bool plateColorJudge(const Mat& src, const Color r, const bool adaptive_minsv,
float& percent);
bool bFindLeftRightBound(Mat& bound_threshold, int& posLeft, int& posRight);
bool bFindLeftRightBound1(Mat& bound_threshold, int& posLeft, int& posRight);
bool bFindLeftRightBound2(Mat& bound_threshold, int& posLeft, int& posRight);
bool clearLiuDing(Mat& img);
void clearLiuDingOnly(Mat& img);
void clearLiuDing(Mat mask, int& top, int& bottom);
Color getPlateType(const Mat& src, const bool adaptive_minsv);
Mat histeq(Mat in);
Rect GetCenterRect(Mat& in);
Mat CutTheRect(Mat& in, Rect& rect);
int ThresholdOtsu(Mat mat);
// project histogram
Mat ProjectedHistogram(Mat img, int t, int threshold = 20);
Mat showHistogram(const Mat& hist);
Mat preprocessChar(Mat in, int char_size);
Rect GetChineseRect(const Rect rectSpe);
bool verifyCharSizes(Rect r);
bool verifyPlateSize(Rect mr);
bool verifyRotatedPlateSizes(RotatedRect mr, bool showDebug = false);
// non-maximum suppression
void NMStoCharacter(std::vector<CCharacter> &inVec, double overlap);
// draw rotatedRectangle
void rotatedRectangle(InputOutputArray img, RotatedRect rect,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
// ostu region
void spatial_ostu(InputArray _src, int grid_x, int grid_y, Color type = BLUE);
// Scale to small image (for the purpose of comput mser in large image)
Mat scaleImage(const Mat& image, const Size& maxSize, double& scale_ratio);
// Scale back RotatedRect
RotatedRect scaleBackRRect(const RotatedRect& rr, const float scale_ratio);
//! use verify size to first generate char candidates
void mserCharMatch(const Mat &src, std::vector<Mat> &match, std::vector<CPlate>& out_plateVec_blue, std::vector<CPlate>& out_plateVec_yellow,
bool usePlateMser, std::vector<RotatedRect>& out_plateRRect_blue, std::vector<RotatedRect>& out_plateRRect_yellow, int index = 0, bool showDebug = false);
// computer the insert over union about two rrect
bool computeIOU(const RotatedRect& rrect1, const RotatedRect& rrect2, const int width, const int height, const float thresh, float& result);
float computeIOU(const RotatedRect& rrect1, const RotatedRect& rrect2, const int width, const int height);
bool computeIOU(const Rect& rect1, const Rect& rect2, const float thresh, float& result);
float computeIOU(const Rect& rect1, const Rect& rect2);
/** @brief convert form mser point to image.
The function created first by Hailiang Xu.
Modified by Ruoze Liu.
@param
*/
Mat adaptive_image_from_points(const std::vector<Point>& points,
const Rect& rect, const Size& size, const Scalar& backgroundColor = Scalar(0, 0, 0),
const Scalar& forgroundColor = Scalar(255, 255, 255), bool gray = true);
// Calculate a rect have same length and width and remains the center
Rect adaptive_charrect_from_rect(const Rect& rect, int maxwidth, int maxheight, bool useExtendHeight = false);
// calc safe rect
bool calcSafeRect(const RotatedRect& roi_rect, const Mat& src,
Rect_<float>& safeBoundRect);
bool calcSafeRect(const RotatedRect &roi_rect, const int width, const int height,
Rect_<float> &safeBoundRect);
// uniform resize all the image to same size for the next process
Mat uniformResize(const Mat &result, float& scale);
// uniform resize all the plates to same size for the next process
Mat uniformResizePlates(const Mat &result, float& scale);
// show detect results
void showDectectResults(const Mat& img, const std::vector<CPlate> &plateVec, size_t num);
// show the results
Mat showResult(const Mat &result, int img_index = 0);
// enlarge the char rect
Rect rectEnlarge(const Rect& src, const int mat_width, const int mat_height);
Rect rectFit(const Rect &src, const int mat_width, const int mat_height);
// write images to temp folder
void writeTempImage(const Mat& outImg, const string path, int index = 0);
// remove small hor lines in the plate
bool judegMDOratio2(const Mat &image, const Rect &rect, std::vector<Point> &contour, Mat &result, const float thresh = 1.f,
bool useExtendHeight = false);
// clear top and bottom borders
void clearBorder(const Mat &img, Rect& cropRect);
//! non-maximum surpresion for 1d array
template<typename T>
void NMSfor1D(const vector<T>& arr, vector<int>& index) {
// prepare
int size = (int)arr.size();
index.resize(size);
for (int j = 0; j < size; j++)
index.at(j) = 0;
// nms
int i = 1;
while (i < size - 1) {
if (arr.at(i) > arr.at(i + 1)) {
if (arr.at(i) >= arr.at(i - 1))
index.at(i) = 1;
}
else {
while (i < size - 1 && arr.at(i) <= arr.at(i + 1))
i = i + 1;
if (i < size - 1)
index.at(i) = 1;
}
i = i + 2;
}
}
} /*! \namespace easypr*/
#endif // EASYPR_CORE_COREFUNC_H_

@ -1,59 +0,0 @@
#ifndef EASYPR_CORE_FEATURE_H_
#define EASYPR_CORE_FEATURE_H_
#include "opencv2/opencv.hpp"
using namespace cv;
namespace easypr {
//! 获得车牌的特征数
cv::Mat getHistogram(cv::Mat in);
//! EasyPR的getFeatures回调函数
//! 用于从车牌的image生成svm的训练特征features
typedef void (*svmCallback)(const cv::Mat& image, cv::Mat& features);
//! EasyPR的getFeatures回调函数
//! convert from images to features used by gray char ann
typedef void (*annCallback)(const cv::Mat& image, cv::Mat& features);
//! gray and project feature
void getGrayPlusProject(const cv::Mat& grayChar, cv::Mat& features);
//! EasyPR的getFeatures回调函数
//! 本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const cv::Mat& image, cv::Mat& features);
//! 本函数是获取SIFT特征子
void getSIFTFeatures(const cv::Mat& image, cv::Mat& features);
//! 本函数是获取HOG特征子
void getHOGFeatures(const cv::Mat& image, cv::Mat& features);
//! 本函数是获取HSV空间量化的直方图特征子
void getHSVHistFeatures(const cv::Mat& image, cv::Mat& features);
//! LBP feature
void getLBPFeatures(const cv::Mat& image, cv::Mat& features);
//! color feature
void getColorFeatures(const cv::Mat& src, cv::Mat& features);
//! color feature and histom
void getHistomPlusColoFeatures(const cv::Mat& image, cv::Mat& features);
//! get character feature
cv::Mat charFeatures(cv::Mat in, int sizeData);
cv::Mat charFeatures2(cv::Mat in, int sizeData);
//! LBP feature + Histom feature
void getLBPplusHistFeatures(const cv::Mat& image, cv::Mat& features);
//! grayChar feauter
void getGrayCharFeatures(const cv::Mat& grayChar, cv::Mat& features);
void getGrayPlusLBP(const Mat& grayChar, Mat& features);
} /*! \namespace easypr*/
#endif // EASYPR_CORE_FEATURE_H_

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save