Convert src/* to utf-8.

Add v12 project files.
1.3
Micooz 10 years ago
parent bdaae0b59b
commit b947d37846

1
.gitignore vendored

@ -78,6 +78,7 @@ ipch/
*.psess *.psess
*.vsp *.vsp
*.vspx *.vspx
*.suo
# TFS 2012 Local Workspace # TFS 2012 Local Workspace
$tf/ $tf/

@ -0,0 +1,128 @@
<?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>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</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="opencv248.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="opencv248.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>D:\libs\opencv\build\x86\vc12\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_calib3d249d.lib;opencv_contrib249d.lib;opencv_core249d.lib;opencv_features2d249d.lib;opencv_flann249d.lib;opencv_gpu249d.lib;opencv_highgui249d.lib;opencv_imgproc249d.lib;opencv_legacy249d.lib;opencv_ml249d.lib;opencv_nonfree249d.lib;opencv_objdetect249d.lib;opencv_ocl249d.lib;opencv_photo249d.lib;opencv_stitching249d.lib;opencv_superres249d.lib;opencv_ts249d.lib;opencv_video249d.lib;opencv_videostab249d.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies>
</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;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="image\使用说明.txt" />
<None Include="image\免责声明.txt" />
<None Include="image\图片捐赠.txt" />
<None Include="image\版权声明.txt" />
<None Include="model\ann.xml" />
<None Include="model\svm.xml" />
<None Include="关于版权.txt" />
</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\features.cpp" />
<ClCompile Include="src\test\accuracy_test.cpp" />
<ClCompile Include="src\train\ann_train.cpp" />
<ClCompile Include="src\train\svm_train.cpp" />
<ClCompile Include="src\util\deface.cpp" />
<ClCompile Include="src\util\general_test_prepare.cpp" />
<ClCompile Include="src\util\generate_gdts.cpp" />
<ClCompile Include="src\util\mc_data_prepare.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\test\test.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\util\learn_prepare.cpp" />
<ClCompile Include="src\util\util.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\include\chars_identify.h" />
<ClInclude Include="src\include\chars_recognise.h" />
<ClInclude Include="src\include\chars_segment.h" />
<ClInclude Include="src\include\features.h" />
<ClInclude Include="src\include\plate_detect.h" />
<ClInclude Include="src\include\plate_judge.h" />
<ClInclude Include="src\include\plate_locate.h" />
<ClInclude Include="src\include\plate_recognize.h" />
<ClInclude Include="src\include\prep.h" />
<ClInclude Include="src\include\util.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,123 @@
<?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>
</ItemGroup>
<ItemGroup>
<None Include="model\ann.xml">
<Filter>资源文件</Filter>
</None>
<None Include="model\svm.xml">
<Filter>资源文件</Filter>
</None>
<None Include="关于版权.txt">
<Filter>资源文件</Filter>
</None>
<None Include="image\图片捐赠.txt" />
<None Include="image\免责声明.txt" />
<None Include="image\使用说明.txt" />
<None Include="image\版权声明.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\util\util.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\util\mc_data_prepare.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\util\learn_prepare.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\chars_identify.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\chars_recognise.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\chars_segment.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_detect.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_judge.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_locate.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\plate_recognize.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\core\features.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\test\test.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\test\accuracy_test.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\util\deface.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\main.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\train\ann_train.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\train\svm_train.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\util\generate_gdts.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\util\general_test_prepare.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\include\chars_identify.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\chars_recognise.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\chars_segment.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\plate_detect.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\plate_judge.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\plate_locate.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\plate_recognize.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\prep.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\util.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\include\features.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -9,20 +9,20 @@ namespace easypr{
#define VERTICAL 0 #define VERTICAL 0
#define NDEBUG #define NDEBUG
//中国车牌 //中国车牌
const char strCharacters[] = {'0','1','2','3','4','5',\ const char strCharacters[] = {'0','1','2','3','4','5',\
'6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\ '6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\
'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \ 'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \
'U','V', 'W', 'X', 'Y', 'Z'}; 'U','V', 'W', 'X', 'Y', 'Z'};
const int numCharacter = 34; /* 没有I和0,10个数字与24个英文字符之和 */ const int numCharacter = 34; /* 没有I和0,10个数字与24个英文字符之和 */
//以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符 //以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符
const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \ const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \ "zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \
"zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \ "zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \
"zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \ "zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \
"zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\ "zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\
"zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */}; "zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */};
const int numChinese = 20; const int numChinese = 20;
const int numAll = 54; /* 34+20=54 */ const int numAll = 54; /* 34+20=54 */
@ -36,26 +36,26 @@ CCharsIdentify::CCharsIdentify()
if (m_map.empty()) if (m_map.empty())
{ {
m_map.insert(pair<string, string>("zh_cuan","")); m_map.insert(pair<string, string>("zh_cuan",""));
m_map.insert(pair<string, string>("zh_e","")); m_map.insert(pair<string, string>("zh_e",""));
m_map.insert(pair<string, string>("zh_gan","")); m_map.insert(pair<string, string>("zh_gan",""));
m_map.insert(pair<string, string>("zh_hei","")); m_map.insert(pair<string, string>("zh_hei",""));
m_map.insert(pair<string, string>("zh_hu","")); m_map.insert(pair<string, string>("zh_hu",""));
m_map.insert(pair<string, string>("zh_ji","")); m_map.insert(pair<string, string>("zh_ji",""));
m_map.insert(pair<string, string>("zh_jl","")); m_map.insert(pair<string, string>("zh_jl",""));
m_map.insert(pair<string, string>("zh_jin","")); m_map.insert(pair<string, string>("zh_jin",""));
m_map.insert(pair<string, string>("zh_jing","")); m_map.insert(pair<string, string>("zh_jing",""));
m_map.insert(pair<string, string>("zh_shan","")); m_map.insert(pair<string, string>("zh_shan",""));
m_map.insert(pair<string, string>("zh_liao","")); m_map.insert(pair<string, string>("zh_liao",""));
m_map.insert(pair<string, string>("zh_lu","")); m_map.insert(pair<string, string>("zh_lu",""));
m_map.insert(pair<string, string>("zh_min","")); m_map.insert(pair<string, string>("zh_min",""));
m_map.insert(pair<string, string>("zh_ning","")); m_map.insert(pair<string, string>("zh_ning",""));
m_map.insert(pair<string, string>("zh_su","")); m_map.insert(pair<string, string>("zh_su",""));
m_map.insert(pair<string, string>("zh_sx","")); m_map.insert(pair<string, string>("zh_sx",""));
m_map.insert(pair<string, string>("zh_wan","")); m_map.insert(pair<string, string>("zh_wan",""));
m_map.insert(pair<string, string>("zh_yu","")); m_map.insert(pair<string, string>("zh_yu",""));
m_map.insert(pair<string, string>("zh_yue","")); m_map.insert(pair<string, string>("zh_yue",""));
m_map.insert(pair<string, string>("zh_zhe","")); m_map.insert(pair<string, string>("zh_zhe",""));
} }
} }
@ -72,7 +72,7 @@ void CCharsIdentify::LoadModel(string s)
ann.load(s.c_str(), "ann"); ann.load(s.c_str(), "ann");
} }
//create the accumulation histograms,img is a binary image, t is 水平或垂直 //create the accumulation histograms,img is a binary image, t is 水平或垂直
Mat CCharsIdentify::ProjectedHistogram(Mat img, int t) Mat CCharsIdentify::ProjectedHistogram(Mat img, int t)
{ {
int sz=(t)?img.rows:img.cols; int sz=(t)?img.rows:img.cols;
@ -80,7 +80,7 @@ Mat CCharsIdentify::ProjectedHistogram(Mat img, int t)
for(int j=0; j<sz; j++){ for(int j=0; j<sz; j++){
Mat data=(t)?img.row(j):img.col(j); Mat data=(t)?img.row(j):img.col(j);
mhist.at<float>(j)=countNonZero(data); //统计这一行或一列中非零元素的个数并保存到mhist中 mhist.at<float>(j)=countNonZero(data); //统计这一行或一列中非零元素的个数并保存到mhist中
} }
//Normalize histogram //Normalize histogram
@ -88,12 +88,12 @@ Mat CCharsIdentify::ProjectedHistogram(Mat img, int t)
minMaxLoc(mhist, &min, &max); minMaxLoc(mhist, &min, &max);
if(max>0) if(max>0)
mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图 mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图
return mhist; return mhist;
} }
//! 获得字符的特征图 //! 获得字符的特征图
Mat CCharsIdentify::features(Mat in, int sizeData) Mat CCharsIdentify::features(Mat in, int sizeData)
{ {
//Histogram features //Histogram features
@ -109,7 +109,7 @@ Mat CCharsIdentify::features(Mat in, int sizeData)
Mat out = Mat::zeros(1, numCols, CV_32F); Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量 //Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
int j=0; int j=0;
for(int i=0; i<vhist.cols; i++) for(int i=0; i<vhist.cols; i++)
{ {
@ -133,7 +133,7 @@ Mat CCharsIdentify::features(Mat in, int sizeData)
} }
//! 利用神经网络做识别 //! 利用神经网络做识别
int CCharsIdentify::classify(Mat f, bool isChinses){ int CCharsIdentify::classify(Mat f, bool isChinses){
int result = -1; int result = -1;
Mat output(1, numAll, CV_32FC1); Mat output(1, numAll, CV_32FC1);
@ -173,7 +173,7 @@ int CCharsIdentify::classify(Mat f, bool isChinses){
} }
//输入当个字符Mat,生成字符的string //输入当个字符Mat,生成字符的string
string CCharsIdentify::charsIdentify(Mat input, bool isChinese) string CCharsIdentify::charsIdentify(Mat input, bool isChinese)
{ {
Mat f = features(input, m_predictSize); Mat f = features(input, m_predictSize);

@ -19,7 +19,7 @@ void CCharsRecognise::LoadANN(string s)
int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense) int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense)
{ {
//车牌字符方块集合 //车牌字符方块集合
vector<Mat> matVec; vector<Mat> matVec;
string plateIdentify = ""; string plateIdentify = "";
@ -33,7 +33,7 @@ int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense)
Mat charMat = matVec[j]; Mat charMat = matVec[j];
bool isChinses = false; bool isChinses = false;
//默认首个字符块是中文字符 //默认首个字符块是中文字符
if (j == 0) if (j == 0)
isChinses = true; isChinses = true;

@ -14,7 +14,7 @@ CCharsSegment::CCharsSegment()
m_LiuDingSize = DEFAULT_LIUDING_SIZE; m_LiuDingSize = DEFAULT_LIUDING_SIZE;
m_theMatWidth = DEFAULT_MAT_WIDTH; m_theMatWidth = DEFAULT_MAT_WIDTH;
//!车牌颜色判断参数 //!车牌颜色判断参数
m_ColorThreshold = DEFAULT_COLORTHRESHOLD; m_ColorThreshold = DEFAULT_COLORTHRESHOLD;
m_BluePercent = DEFAULT_BLUEPERCEMT; m_BluePercent = DEFAULT_BLUEPERCEMT;
m_WhitePercent = DEFAULT_WHITEPERCEMT; m_WhitePercent = DEFAULT_WHITEPERCEMT;
@ -22,7 +22,7 @@ CCharsSegment::CCharsSegment()
m_debug = DEFAULT_DEBUG; m_debug = DEFAULT_DEBUG;
} }
//! 字符尺寸验证 //! 字符尺寸验证
bool CCharsSegment::verifySizes(Mat r){ bool CCharsSegment::verifySizes(Mat r){
//Char sizes 45x90 //Char sizes 45x90
float aspect=45.0f/90.0f; float aspect=45.0f/90.0f;
@ -46,12 +46,12 @@ bool CCharsSegment::verifySizes(Mat r){
return false; return false;
} }
//! 字符预处理 //! 字符预处理
Mat CCharsSegment::preprocessChar(Mat in){ Mat CCharsSegment::preprocessChar(Mat in){
//Remap image //Remap image
int h=in.rows; int h=in.rows;
int w=in.cols; int w=in.cols;
int charSize=CHAR_SIZE; //统一每个字符的大小 int charSize=CHAR_SIZE; //统一每个字符的大小
Mat transformMat=Mat::eye(2,3,CV_32F); Mat transformMat=Mat::eye(2,3,CV_32F);
int m=max(w,h); int m=max(w,h);
transformMat.at<float>(0,2)=m/2 - w/2; transformMat.at<float>(0,2)=m/2 - w/2;
@ -66,7 +66,7 @@ Mat CCharsSegment::preprocessChar(Mat in){
return out; return out;
} }
//! 直方图均衡,为判断车牌颜色做准备 //! 直方图均衡,为判断车牌颜色做准备
Mat CCharsSegment::histeq(Mat in) Mat CCharsSegment::histeq(Mat in)
{ {
Mat out(in.size(), in.type()); Mat out(in.size(), in.type());
@ -88,8 +88,8 @@ Mat CCharsSegment::histeq(Mat in)
} }
//getPlateType //getPlateType
//判断车牌的类型1为蓝牌2为黄牌0为未知默认蓝牌 //判断车牌的类型1为蓝牌2为黄牌0为未知默认蓝牌
//通过像素中蓝色所占比例的多少来判断大于0.3为蓝牌,否则为黄牌 //通过像素中蓝色所占比例的多少来判断大于0.3为蓝牌,否则为黄牌
int CCharsSegment::getPlateType(Mat input) int CCharsSegment::getPlateType(Mat input)
{ {
Mat img; Mat img;
@ -129,9 +129,9 @@ int CCharsSegment::getPlateType(Mat input)
} }
//clearLiuDing //clearLiuDing
//去除车牌上方的钮钉 //去除车牌上方的钮钉
//计算每行元素的阶跃数如果小于X认为是柳丁将此行全部填0涂黑 //计算每行元素的阶跃数如果小于X认为是柳丁将此行全部填0涂黑
//X的推荐值为可根据实际调整 //X的推荐值为可根据实际调整
Mat CCharsSegment::clearLiuDing(Mat img) Mat CCharsSegment::clearLiuDing(Mat img)
{ {
const int x = m_LiuDingSize; const int x = m_LiuDingSize;
@ -159,13 +159,13 @@ Mat CCharsSegment::clearLiuDing(Mat img)
return img; return img;
} }
//! 字符分割与排序 //! 字符分割与排序
int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec) int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
{ {
if( !input.data ) if( !input.data )
{ return -3; } { return -3; }
//判断车牌颜色以此确认threshold方法 //判断车牌颜色以此确认threshold方法
int plateType = getPlateType(input); int plateType = getPlateType(input);
cvtColor(input, input, CV_RGB2GRAY); cvtColor(input, input, CV_RGB2GRAY);
@ -183,7 +183,7 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
imwrite(ss.str(), img_threshold); imwrite(ss.str(), img_threshold);
} }
//去除车牌上方的柳钉以及下方的横线等干扰 //去除车牌上方的柳钉以及下方的横线等干扰
clearLiuDing(img_threshold); clearLiuDing(img_threshold);
@ -209,7 +209,7 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
vector<Rect> vecRect; vector<Rect> vecRect;
//Remove patch that are no inside limits of aspect ratio and area. //Remove patch that are no inside limits of aspect ratio and area.
//将不符合特定尺寸的图块排除出去 //将不符合特定尺寸的图块排除出去
while (itc != contours.end()) while (itc != contours.end())
{ {
Rect mr = boundingRect(Mat(*itc)); Rect mr = boundingRect(Mat(*itc));
@ -225,11 +225,11 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
return -3; return -3;
vector<Rect> sortedRect; vector<Rect> sortedRect;
//对符合尺寸的图块按照从左到右进行排序 //对符合尺寸的图块按照从左到右进行排序
SortRect(vecRect, sortedRect); SortRect(vecRect, sortedRect);
int specIndex = 0; int specIndex = 0;
//获得指示城市的特定Rect,如苏A的"A" //获得指示城市的特定Rect,如苏A的"A"
specIndex = GetSpecificRect(sortedRect); specIndex = GetSpecificRect(sortedRect);
if(m_debug) if(m_debug)
@ -243,9 +243,9 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
} }
} }
//根据特定Rect向左反推出中文字符 //根据特定Rect向左反推出中文字符
//这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect因此仅能 //这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect因此仅能
//退过特定算法来指定 //退过特定算法来指定
Rect chineseRect; Rect chineseRect;
if (specIndex < sortedRect.size()) if (specIndex < sortedRect.size())
chineseRect = GetChineseRect(sortedRect[specIndex]); chineseRect = GetChineseRect(sortedRect[specIndex]);
@ -261,9 +261,9 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
} }
//新建一个全新的排序Rect //新建一个全新的排序Rect
//将中文字符Rect第一个加进来因为它肯定是最左边的 //将中文字符Rect第一个加进来因为它肯定是最左边的
//其余的Rect只按照顺序去6个车牌只可能是7个字符这样可以避免阴影导致的“1”字符 //其余的Rect只按照顺序去6个车牌只可能是7个字符这样可以避免阴影导致的“1”字符
vector<Rect> newSortedRect; vector<Rect> newSortedRect;
newSortedRect.push_back(chineseRect); newSortedRect.push_back(chineseRect);
RebuildRect(sortedRect, newSortedRect, specIndex); RebuildRect(sortedRect, newSortedRect, specIndex);
@ -292,7 +292,7 @@ int CCharsSegment::charsSegment(Mat input, vector<Mat>& resultVec)
return 0; return 0;
} }
//! 将Rect按位置从左到右进行排序 //! 将Rect按位置从左到右进行排序
int CCharsSegment::SortRect(const vector<Rect>& vecRect, vector<Rect>& out) int CCharsSegment::SortRect(const vector<Rect>& vecRect, vector<Rect>& out)
{ {
vector<int> orderIndex; vector<int> orderIndex;
@ -336,7 +336,7 @@ int CCharsSegment::SortRect(const vector<Rect>& vecRect, vector<Rect>& out)
return 0; return 0;
} }
//! 根据特殊车牌来构造猜测中文字符的位置和大小 //! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect CCharsSegment::GetChineseRect(const Rect rectSpe) Rect CCharsSegment::GetChineseRect(const Rect rectSpe)
{ {
int height = rectSpe.height; int height = rectSpe.height;
@ -352,7 +352,7 @@ Rect CCharsSegment::GetChineseRect(const Rect rectSpe)
return a; return a;
} }
//! 找出指示城市的字符的Rect例如苏A7003X就是"A"的位置 //! 找出指示城市的字符的Rect例如苏A7003X就是"A"的位置
int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect) int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect)
{ {
vector<int> xpositions; vector<int> xpositions;
@ -379,7 +379,7 @@ int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect)
Rect mr = vecRect[i]; Rect mr = vecRect[i];
int midx = mr.x + mr.width/2; int midx = mr.x + mr.width/2;
//如果一个字符有一定的大小并且在整个车牌的1/7到2/7之间则是我们要找的特殊车牌 //如果一个字符有一定的大小并且在整个车牌的1/7到2/7之间则是我们要找的特殊车牌
if ((mr.width > maxWidth * 0.8 || mr.height > maxHeight * 0.8) && if ((mr.width > maxWidth * 0.8 || mr.height > maxHeight * 0.8) &&
(midx < int(m_theMatWidth / 7) * 2 && midx > int(m_theMatWidth / 7) * 1)) (midx < int(m_theMatWidth / 7) * 2 && midx > int(m_theMatWidth / 7) * 1))
{ {
@ -390,17 +390,17 @@ int CCharsSegment::GetSpecificRect(const vector<Rect>& vecRect)
return specIndex; return specIndex;
} }
//! 这个函数做两个事情 //! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。 // 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。 // 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int CCharsSegment::RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex) int CCharsSegment::RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex)
{ {
//最大只能有7个Rect,减去中文的就只有6个Rect //最大只能有7个Rect,减去中文的就只有6个Rect
int count = 6; int count = 6;
for (int i = 0; i < vecRect.size(); i++) for (int i = 0; i < vecRect.size(); i++)
{ {
//将特殊字符左边的Rect去掉这个可能会去掉中文Rect不过没关系我们后面会重建。 //将特殊字符左边的Rect去掉这个可能会去掉中文Rect不过没关系我们后面会重建。
if (i < specIndex) if (i < specIndex)
continue; continue;

@ -1,6 +1,6 @@
// 这个文件定义了EasyPR里所有特征生成的函数 // 这个文件定义了EasyPR里所有特征生成的函数
// 所属命名空间为easypr // 所属命名空间为easypr
// 这个部分中的特征由easypr的开发者修改 // 这个部分中的特征由easypr的开发者修改
#include "../include/prep.h" #include "../include/prep.h"
#include "../include/features.h" #include "../include/features.h"
@ -10,7 +10,7 @@
*/ */
namespace easypr { namespace easypr {
//! 直方图均衡 //! 直方图均衡
Mat histeq(Mat in) Mat histeq(Mat in)
{ {
Mat out(in.size(), in.type()); Mat out(in.size(), in.type());
@ -31,7 +31,7 @@ Mat histeq(Mat in)
return out; return out;
} }
// !获取垂直和水平方向直方图 // !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t) Mat ProjectedHistogram(Mat img, int t)
{ {
int sz=(t)?img.rows:img.cols; int sz=(t)?img.rows:img.cols;
@ -39,7 +39,7 @@ Mat ProjectedHistogram(Mat img, int t)
for(int j=0; j<sz; j++){ for(int j=0; j<sz; j++){
Mat data=(t)?img.row(j):img.col(j); Mat data=(t)?img.row(j):img.col(j);
mhist.at<float>(j)=countNonZero(data); //统计这一行或一列中非零元素的个数并保存到mhist中 mhist.at<float>(j)=countNonZero(data); //统计这一行或一列中非零元素的个数并保存到mhist中
} }
//Normalize histogram //Normalize histogram
@ -47,13 +47,13 @@ Mat ProjectedHistogram(Mat img, int t)
minMaxLoc(mhist, &min, &max); minMaxLoc(mhist, &min, &max);
if(max>0) if(max>0)
mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图 mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图
return mhist; return mhist;
} }
//! 获得车牌的特征数 //! 获得车牌的特征数
Mat getTheFeatures(Mat in) Mat getTheFeatures(Mat in)
{ {
const int VERTICAL = 0; const int VERTICAL = 0;
@ -68,7 +68,7 @@ Mat getTheFeatures(Mat in)
Mat out = Mat::zeros(1, numCols, CV_32F); Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,样本特征为水平、垂直直方图 //Asign values to feature,样本特征为水平、垂直直方图
int j=0; int j=0;
for(int i=0; i<vhist.cols; i++) for(int i=0; i<vhist.cols; i++)
{ {
@ -84,15 +84,15 @@ Mat getTheFeatures(Mat in)
return out; return out;
} }
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// !本函数是生成直方图均衡特征的回调函数 // !本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const Mat& image, Mat& features) void getHisteqFeatures(const Mat& image, Mat& features)
{ {
features = histeq(image); features = histeq(image);
} }
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// !本函数是获取垂直和水平的直方图图值 // !本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features) void getHistogramFeatures(const Mat& image, Mat& features)
{ {
Mat grayImage; Mat grayImage;
@ -104,20 +104,20 @@ void getHistogramFeatures(const Mat& image, Mat& features)
} }
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// 本函数是获取SITF特征子 // 本函数是获取SITF特征子
// ! // !
void getSIFTFeatures(const Mat& image, Mat& features) void getSIFTFeatures(const Mat& image, Mat& features)
{ {
//待完善 //待完善
} }
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// 本函数是获取HOG特征子 // 本函数是获取HOG特征子
void getHOGFeatures(const Mat& image, Mat& features) void getHOGFeatures(const Mat& image, Mat& features)
{ {
//待完善 //待完善
} }
} /* \namespace easypr */ } /* \namespace easypr */

@ -19,7 +19,7 @@ void CPlateDetect::LoadSVM(string s)
int CPlateDetect::plateDetect(Mat src, vector<Mat>& resultVec) int CPlateDetect::plateDetect(Mat src, vector<Mat>& resultVec)
{ {
//可能是车牌的图块集合 //可能是车牌的图块集合
vector<Mat> matVec; vector<Mat> matVec;
int resultLo = m_plateLocate->plateLocate(src, matVec); int resultLo = m_plateLocate->plateLocate(src, matVec);

@ -27,7 +27,7 @@ void CPlateJudge::LoadModel(string s)
svm.load(s.c_str(), "svm"); svm.load(s.c_str(), "svm");
} }
//! 直方图均衡 //! 直方图均衡
Mat CPlateJudge::histeq(Mat in) Mat CPlateJudge::histeq(Mat in)
{ {
Mat out(in.size(), in.type()); Mat out(in.size(), in.type());
@ -49,7 +49,7 @@ Mat CPlateJudge::histeq(Mat in)
} }
//! 对单幅图像进行SVM判断 //! 对单幅图像进行SVM判断
int CPlateJudge::plateJudge(const Mat& inMat,int& result) int CPlateJudge::plateJudge(const Mat& inMat,int& result)
{ {
if (m_getFeatures == NULL) if (m_getFeatures == NULL)
@ -58,7 +58,7 @@ int CPlateJudge::plateJudge(const Mat& inMat,int& result)
Mat features; Mat features;
m_getFeatures(inMat, features); m_getFeatures(inMat, features);
//通过直方图均衡化后的彩色图进行预测 //通过直方图均衡化后的彩色图进行预测
Mat p = features.reshape(1, 1); Mat p = features.reshape(1, 1);
p.convertTo(p, CV_32FC1); p.convertTo(p, CV_32FC1);
@ -69,7 +69,7 @@ int CPlateJudge::plateJudge(const Mat& inMat,int& result)
} }
//! 对多幅图像进行SVM判断 //! 对多幅图像进行SVM判断
int CPlateJudge::plateJudge(const vector<Mat>& inVec, int CPlateJudge::plateJudge(const vector<Mat>& inVec,
vector<Mat>& resultVec) vector<Mat>& resultVec)
{ {

@ -25,8 +25,8 @@ CPlateLocate::CPlateLocate()
m_debug = DEFAULT_DEBUG; m_debug = DEFAULT_DEBUG;
} }
//! 生活模式与工业模式切换 //! 生活模式与工业模式切换
//! 如果为真,则设置各项参数为定位生活场景照片(如百度图片)的参数,否则恢复默认值。 //! 如果为真,则设置各项参数为定位生活场景照片(如百度图片)的参数,否则恢复默认值。
void CPlateLocate::setLifemode(bool param) void CPlateLocate::setLifemode(bool param)
{ {
if(param == true) if(param == true)
@ -52,12 +52,12 @@ void CPlateLocate::setLifemode(bool param)
} }
//! 对minAreaRect获得的最小外接矩形用纵横比进行判断 //! 对minAreaRect获得的最小外接矩形用纵横比进行判断
bool CPlateLocate::verifySizes(RotatedRect mr) bool CPlateLocate::verifySizes(RotatedRect mr)
{ {
float error = m_error; float error = m_error;
//Spain car plate size: 52x11 aspect 4,7272 //Spain car plate size: 52x11 aspect 4,7272
//China car plate size: 440mm*140mmaspect 3.142857 //China car plate size: 440mm*140mmaspect 3.142857
float aspect = m_aspect; float aspect = m_aspect;
//Set a min and max area. All other patchs are discarded //Set a min and max area. All other patchs are discarded
//int min= 1*aspect*1; // minimum area //int min= 1*aspect*1; // minimum area
@ -85,7 +85,7 @@ bool CPlateLocate::verifySizes(RotatedRect mr)
} }
} }
//! 显示最终生成的车牌图像,便于判断是否成功进行了旋转。 //! 显示最终生成的车牌图像,便于判断是否成功进行了旋转。
Mat CPlateLocate::showResultMat(Mat src, Size rect_size, Point2f center, int index) Mat CPlateLocate::showResultMat(Mat src, Size rect_size, Point2f center, int index)
{ {
Mat img_crop; Mat img_crop;
@ -113,10 +113,10 @@ Mat CPlateLocate::showResultMat(Mat src, Size rect_size, Point2f center, int ind
return resultResized; return resultResized;
} }
//! 定位车牌图像 //! 定位车牌图像
//! src 原始图像 //! src 原始图像
//! resultVec 一个Mat的向量存储所有抓取到的图像 //! resultVec 一个Mat的向量存储所有抓取到的图像
//! 成功返回0否则返回-1 //! 成功返回0否则返回-1
int CPlateLocate::plateLocate(Mat src, vector<Mat>& resultVec) int CPlateLocate::plateLocate(Mat src, vector<Mat>& resultVec)
{ {
Mat src_blur, src_gray; Mat src_blur, src_gray;
@ -129,7 +129,7 @@ int CPlateLocate::plateLocate(Mat src, vector<Mat>& resultVec)
if( !src.data ) if( !src.data )
{ return -1; } { return -1; }
//高斯模糊。Size中的数字影响车牌定位的效果。 //高斯模糊。Size中的数字影响车牌定位的效果。
GaussianBlur( src, src_blur, Size(m_GaussianBlurSize, m_GaussianBlurSize), GaussianBlur( src, src_blur, Size(m_GaussianBlurSize, m_GaussianBlurSize),
0, 0, BORDER_DEFAULT ); 0, 0, BORDER_DEFAULT );
@ -199,11 +199,11 @@ int CPlateLocate::plateLocate(Mat src, vector<Mat>& resultVec)
imwrite(ss.str(), img_threshold); imwrite(ss.str(), img_threshold);
} }
//Find 轮廓 of possibles plates //Find 轮廓 of possibles plates
vector< vector< Point> > contours; vector< vector< Point> > contours;
findContours(img_threshold, findContours(img_threshold,
contours, // a vector of contours contours, // a vector of contours
CV_RETR_EXTERNAL, // 提取外部轮廓 CV_RETR_EXTERNAL, // 提取外部轮廓
CV_CHAIN_APPROX_NONE); // all pixels of each contours CV_CHAIN_APPROX_NONE); // all pixels of each contours
Mat result; Mat result;
@ -252,10 +252,10 @@ int CPlateLocate::plateLocate(Mat src, vector<Mat>& resultVec)
{ {
// rotated rectangle drawing // rotated rectangle drawing
// Get rotation matrix // Get rotation matrix
// 旋转这部分代码确实可以将某些倾斜的车牌调整正, // 旋转这部分代码确实可以将某些倾斜的车牌调整正,
// 但是它也会误将更多正的车牌搞成倾斜!所以综合考虑,还是不使用这段代码。 // 但是它也会误将更多正的车牌搞成倾斜!所以综合考虑,还是不使用这段代码。
// 2014-08-14,由于新到的一批图片中发现有很多车牌是倾斜的,因此决定再次尝试 // 2014-08-14,由于新到的一批图片中发现有很多车牌是倾斜的,因此决定再次尝试
// 这段代码。 // 这段代码。
if(m_debug) if(m_debug)
{ {
Point2f rect_points[4]; Point2f rect_points[4];
@ -272,7 +272,7 @@ int CPlateLocate::plateLocate(Mat src, vector<Mat>& resultVec)
angle = 90 + angle; angle = 90 + angle;
swap(rect_size.width, rect_size.height); swap(rect_size.width, rect_size.height);
} }
//如果抓取的方块旋转超过m_angle角度则不是车牌放弃处理 //如果抓取的方块旋转超过m_angle角度则不是车牌放弃处理
if (angle - m_angle < 0 && angle + m_angle > 0) if (angle - m_angle < 0 && angle + m_angle > 0)
{ {
//Create and rotate image //Create and rotate image

@ -12,13 +12,13 @@ CPlateRecognize::CPlateRecognize()
//m_charsRecognise = new CCharsRecognise(); //m_charsRecognise = new CCharsRecognise();
} }
////! 装载SVM模型 ////! 装载SVM模型
//void CPlateRecognize::LoadSVM(string strSVM) //void CPlateRecognize::LoadSVM(string strSVM)
//{ //{
// m_plateDetect->LoadModel(strSVM.c_str()); // m_plateDetect->LoadModel(strSVM.c_str());
//} //}
// //
////! 装载ANN模型 ////! 装载ANN模型
//void CPlateRecognize::LoadANN(string strANN) //void CPlateRecognize::LoadANN(string strANN)
//{ //{
// m_charsRecognise->LoadModel(strANN.c_str()); // m_charsRecognise->LoadModel(strANN.c_str());
@ -38,7 +38,7 @@ CPlateRecognize::CPlateRecognize()
int CPlateRecognize::plateRecognize(Mat src, vector<string>& licenseVec) int CPlateRecognize::plateRecognize(Mat src, vector<string>& licenseVec)
{ {
//车牌方块集合 //车牌方块集合
vector<Mat> plateVec; vector<Mat> plateVec;
int resultPD = plateDetect(src, plateVec); int resultPD = plateDetect(src, plateVec);
@ -51,10 +51,10 @@ int CPlateRecognize::plateRecognize(Mat src, vector<string>& licenseVec)
{ {
Mat plate = plateVec[j]; Mat plate = plateVec[j];
//获取车牌颜色 //获取车牌颜色
string plateType = getPlateType(plate); string plateType = getPlateType(plate);
//获取车牌号 //获取车牌号
string plateIdentify = ""; string plateIdentify = "";
int resultCR = charsRecognise(plate, plateIdentify); int resultCR = charsRecognise(plate, plateIdentify);
if (resultCR == 0) if (resultCR == 0)

@ -24,39 +24,39 @@ class CCharsIdentify
public: public:
CCharsIdentify(); CCharsIdentify();
//! 字符分割 //! 字符分割
string charsIdentify(Mat, bool); string charsIdentify(Mat, bool);
//! 字符分类 //! 字符分类
int classify(Mat, bool); int classify(Mat, bool);
//create the accumulation histograms,img is a binary image, t is 水平或垂直 //create the accumulation histograms,img is a binary image, t is 水平或垂直
Mat ProjectedHistogram(Mat img, int t); Mat ProjectedHistogram(Mat img, int t);
//! 获得字符的特征图 //! 获得字符的特征图
Mat features(Mat in, int sizeData); Mat features(Mat in, int sizeData);
//! 装载ANN模型 //! 装载ANN模型
void LoadModel(); void LoadModel();
//! 装载ANN模型 //! 装载ANN模型
void LoadModel(string s); void LoadModel(string s);
//! 设置与读取模型路径 //! 设置与读取模型路径
inline void setModelPath(string path){ m_path = path; } inline void setModelPath(string path){ m_path = path; }
inline string getModelPath() const{ return m_path; } inline string getModelPath() const{ return m_path; }
private: private:
//使用的ANN模型 //使用的ANN模型
CvANN_MLP ann; CvANN_MLP ann;
//! 模型存储路径 //! 模型存储路径
string m_path; string m_path;
//! 特征尺寸 //! 特征尺寸
int m_predictSize; int m_predictSize;
//! 省份对应map //! 省份对应map
map<string, string> m_map; map<string, string> m_map;
}; };

@ -27,32 +27,32 @@ class CCharsRecognise
public: public:
CCharsRecognise(); CCharsRecognise();
//! 字符分割与识别 //! 字符分割与识别
int charsRecognise(Mat, String&); int charsRecognise(Mat, String&);
//! 装载ANN模型 //! 装载ANN模型
void LoadANN(string s); void LoadANN(string s);
//! 是否开启调试模式 //! 是否开启调试模式
inline void setCRDebug(int param){ m_charsSegment->setDebug(param);} inline void setCRDebug(int param){ m_charsSegment->setDebug(param);}
//! 获取调试模式状态 //! 获取调试模式状态
inline int getCRDebug(){ return m_charsSegment->getDebug();} inline int getCRDebug(){ return m_charsSegment->getDebug();}
//! 获得车牌颜色 //! 获得车牌颜色
inline string getPlateType(Mat input) const inline string getPlateType(Mat input) const
{ {
string color = "未知"; string color = "未知";
int result = m_charsSegment->getPlateType(input); int result = m_charsSegment->getPlateType(input);
if (1 == result) if (1 == result)
color = "蓝牌"; color = "蓝牌";
if (2 == result) if (2 == result)
color = "黄牌"; color = "黄牌";
return color; return color;
} }
//! 设置变量 //! 设置变量
inline void setLiuDingSize(int param){ m_charsSegment->setLiuDingSize(param);} inline void setLiuDingSize(int param){ m_charsSegment->setLiuDingSize(param);}
inline void setColorThreshold(int param){ m_charsSegment->setColorThreshold(param);} inline void setColorThreshold(int param){ m_charsSegment->setColorThreshold(param);}
inline void setBluePercent(float param){ m_charsSegment->setBluePercent(param);} inline void setBluePercent(float param){ m_charsSegment->setBluePercent(param);}
@ -61,10 +61,10 @@ public:
inline float getWhitePercent() const { return m_charsSegment->getWhitePercent();} inline float getWhitePercent() const { return m_charsSegment->getWhitePercent();}
private: private:
//!字符分割 //!字符分割
CCharsSegment* m_charsSegment; CCharsSegment* m_charsSegment;
//! 字符识别 //! 字符识别
CCharsIdentify* m_charsIdentify; CCharsIdentify* m_charsIdentify;
}; };

@ -24,45 +24,45 @@ class CCharsSegment
public: public:
CCharsSegment(); CCharsSegment();
//! 字符分割 //! 字符分割
int charsSegment(Mat, vector<Mat>& ); int charsSegment(Mat, vector<Mat>& );
//! 字符尺寸验证 //! 字符尺寸验证
bool verifySizes(Mat r); bool verifySizes(Mat r);
//! 字符预处理 //! 字符预处理
Mat preprocessChar(Mat in); Mat preprocessChar(Mat in);
//! 生成直方图 //! 生成直方图
Mat ProjectedHistogram(Mat img, int t); Mat ProjectedHistogram(Mat img, int t);
//! 生成字符的特定特征 //! 生成字符的特定特征
Mat features(Mat in, int sizeData); Mat features(Mat in, int sizeData);
//! 直方图均衡,为判断车牌颜色做准备 //! 直方图均衡,为判断车牌颜色做准备
Mat histeq(Mat in); Mat histeq(Mat in);
//! 获得车牌颜色 //! 获得车牌颜色
int getPlateType(Mat input); int getPlateType(Mat input);
//! 去除影响字符识别的柳钉 //! 去除影响字符识别的柳钉
Mat clearLiuDing(Mat img); Mat clearLiuDing(Mat img);
//! 根据特殊车牌来构造猜测中文字符的位置和大小 //! 根据特殊车牌来构造猜测中文字符的位置和大小
Rect GetChineseRect(const Rect rectSpe); Rect GetChineseRect(const Rect rectSpe);
//! 找出指示城市的字符的Rect例如苏A7003X就是A的位置 //! 找出指示城市的字符的Rect例如苏A7003X就是A的位置
int GetSpecificRect(const vector<Rect>& vecRect); int GetSpecificRect(const vector<Rect>& vecRect);
//! 这个函数做两个事情 //! 这个函数做两个事情
// 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。 // 1.把特殊字符Rect左边的全部Rect去掉后面再重建中文字符的位置。
// 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。 // 2.从特殊字符Rect开始依次选择6个Rect多余的舍去。
int RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex); int RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex);
//! 将Rect按位置从左到右进行排序 //! 将Rect按位置从左到右进行排序
int SortRect(const vector<Rect>& vecRect, vector<Rect>& out); int SortRect(const vector<Rect>& vecRect, vector<Rect>& out);
//! 设置变量 //! 设置变量
inline void setLiuDingSize(int param){ m_LiuDingSize = param;} inline void setLiuDingSize(int param){ m_LiuDingSize = param;}
inline void setColorThreshold(int param){ m_ColorThreshold = param;} inline void setColorThreshold(int param){ m_ColorThreshold = param;}
@ -71,38 +71,38 @@ public:
inline void setWhitePercent(float param){ m_WhitePercent = param;} inline void setWhitePercent(float param){ m_WhitePercent = param;}
inline float getWhitePercent() const { return m_WhitePercent;} inline float getWhitePercent() const { return m_WhitePercent;}
//! 是否开启调试模式常量默认0代表关闭 //! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 0; static const int DEFAULT_DEBUG = 0;
//! preprocessChar所用常量 //! preprocessChar所用常量
static const int CHAR_SIZE = 20; static const int CHAR_SIZE = 20;
static const int HORIZONTAL = 1; static const int HORIZONTAL = 1;
static const int VERTICAL = 0; static const int VERTICAL = 0;
//! preprocessChar所用常量 //! preprocessChar所用常量
static const int DEFAULT_LIUDING_SIZE = 7; static const int DEFAULT_LIUDING_SIZE = 7;
static const int DEFAULT_MAT_WIDTH = 136; static const int DEFAULT_MAT_WIDTH = 136;
static const int DEFAULT_COLORTHRESHOLD = 150; static const int DEFAULT_COLORTHRESHOLD = 150;
//! 是否开启调试模式 //! 是否开启调试模式
inline void setDebug(int param){ m_debug = param;} inline void setDebug(int param){ m_debug = param;}
//! 获取调试模式状态 //! 获取调试模式状态
inline int getDebug(){ return m_debug;} inline int getDebug(){ return m_debug;}
private: private:
//!柳钉判断参数 //!柳钉判断参数
int m_LiuDingSize; int m_LiuDingSize;
//!车牌大小参数 //!车牌大小参数
int m_theMatWidth; int m_theMatWidth;
//!车牌颜色判断参数 //!车牌颜色判断参数
int m_ColorThreshold; int m_ColorThreshold;
float m_BluePercent; float m_BluePercent;
float m_WhitePercent; float m_WhitePercent;
//! 是否开启调试模式0关闭非0开启 //! 是否开启调试模式0关闭非0开启
int m_debug; int m_debug;
}; };

@ -6,31 +6,31 @@
*/ */
namespace easypr { namespace easypr {
//! 直方图均衡 //! 直方图均衡
Mat histeq(Mat in); Mat histeq(Mat in);
// !获取垂直和水平方向直方图 // !获取垂直和水平方向直方图
Mat ProjectedHistogram(Mat img, int t); Mat ProjectedHistogram(Mat img, int t);
//! 获得车牌的特征数 //! 获得车牌的特征数
Mat getTheFeatures(Mat in); Mat getTheFeatures(Mat in);
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// 用于从车牌的image生成svm的训练特征features // 用于从车牌的image生成svm的训练特征features
typedef void(*svmCallback)(const Mat& image, Mat& features); typedef void(*svmCallback)(const Mat& image, Mat& features);
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// !本函数是生成直方图均衡特征的回调函数 // !本函数是生成直方图均衡特征的回调函数
void getHisteqFeatures(const Mat& image, Mat& features); void getHisteqFeatures(const Mat& image, Mat& features);
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// !本函数是获取垂直和水平的直方图图值 // !本函数是获取垂直和水平的直方图图值
void getHistogramFeatures(const Mat& image, Mat& features); void getHistogramFeatures(const Mat& image, Mat& features);
// 本函数是获取SIFT特征子 // 本函数是获取SIFT特征子
void getSIFTFeatures(const Mat& image, Mat& features); void getSIFTFeatures(const Mat& image, Mat& features);
// 本函数是获取HOG特征子 // 本函数是获取HOG特征子
void getHOGFeatures(const Mat& image, Mat& features); void getHOGFeatures(const Mat& image, Mat& features);

@ -27,22 +27,22 @@ class CPlateDetect
public: public:
CPlateDetect(); CPlateDetect();
//! 车牌检测:车牌定位与判断 //! 车牌检测:车牌定位与判断
int plateDetect(Mat, vector<Mat>&); int plateDetect(Mat, vector<Mat>&);
//! 装载SVM模型 //! 装载SVM模型
void LoadSVM(string s); void LoadSVM(string s);
//! 生活模式与工业模式切换 //! 生活模式与工业模式切换
inline void setPDLifemode(bool param){m_plateLocate->setLifemode(param);} inline void setPDLifemode(bool param){m_plateLocate->setLifemode(param);}
//! 是否开启调试模式 //! 是否开启调试模式
inline void setPDDebug(int param){ m_plateLocate->setDebug(param);} inline void setPDDebug(int param){ m_plateLocate->setDebug(param);}
//! 获取调试模式状态 //! 获取调试模式状态
inline int getPDDebug(){ return m_plateLocate->getDebug();} inline int getPDDebug(){ return m_plateLocate->getDebug();}
//! 设置与读取变量 //! 设置与读取变量
inline void setGaussianBlurSize(int param){ m_plateLocate->setGaussianBlurSize(param);} inline void setGaussianBlurSize(int param){ m_plateLocate->setGaussianBlurSize(param);}
inline int getGaussianBlurSize() const{ return m_plateLocate->getGaussianBlurSize();} inline int getGaussianBlurSize() const{ return m_plateLocate->getGaussianBlurSize();}
@ -63,10 +63,10 @@ public:
inline void setJudgeAngle(int param){m_plateLocate->setJudgeAngle(param);} inline void setJudgeAngle(int param){m_plateLocate->setJudgeAngle(param);}
private: private:
//!车牌定位 //!车牌定位
CPlateLocate* m_plateLocate; CPlateLocate* m_plateLocate;
//! 车牌判断 //! 车牌判断
CPlateJudge* m_plateJudge; CPlateJudge* m_plateJudge;
}; };

@ -25,34 +25,34 @@ class CPlateJudge
public: public:
CPlateJudge(); CPlateJudge();
//! 车牌判断 //! 车牌判断
int plateJudge(const vector<Mat>&, vector<Mat>&); int plateJudge(const vector<Mat>&, vector<Mat>&);
//! 车牌判断(一副图像) //! 车牌判断(一副图像)
int plateJudge(const Mat& inMat, int& result); int plateJudge(const Mat& inMat, int& result);
//! 直方图均衡 //! 直方图均衡
Mat histeq(Mat); Mat histeq(Mat);
//! 装载SVM模型 //! 装载SVM模型
void LoadModel(); void LoadModel();
//! 装载SVM模型 //! 装载SVM模型
void LoadModel(string s); void LoadModel(string s);
//! 设置与读取模型路径 //! 设置与读取模型路径
inline void setModelPath(string path){ m_path = path; } inline void setModelPath(string path){ m_path = path; }
inline string getModelPath() const{ return m_path; } inline string getModelPath() const{ return m_path; }
private: private:
//使用的SVM模型 //使用的SVM模型
CvSVM svm; CvSVM svm;
// ! EasyPR的getFeatures回调函数 // ! EasyPR的getFeatures回调函数
// 用于从车牌的image生成svm的训练特征features // 用于从车牌的image生成svm的训练特征features
svmCallback m_getFeatures; svmCallback m_getFeatures;
//! 模型存储路径 //! 模型存储路径
string m_path; string m_path;
}; };

@ -25,19 +25,19 @@ class CPlateLocate
public: public:
CPlateLocate(); CPlateLocate();
//! 车牌定位 //! 车牌定位
int plateLocate(Mat, vector<Mat>& ); int plateLocate(Mat, vector<Mat>& );
//! 车牌的尺寸验证 //! 车牌的尺寸验证
bool verifySizes(RotatedRect mr); bool verifySizes(RotatedRect mr);
//! 结果车牌显示 //! 结果车牌显示
Mat showResultMat(Mat src, Size rect_size, Point2f center, int index); Mat showResultMat(Mat src, Size rect_size, Point2f center, int index);
//! 生活模式与工业模式切换 //! 生活模式与工业模式切换
void setLifemode(bool param); void setLifemode(bool param);
//! 设置与读取变量 //! 设置与读取变量
inline void setGaussianBlurSize(int param){ m_GaussianBlurSize = param;} inline void setGaussianBlurSize(int param){ m_GaussianBlurSize = param;}
inline int getGaussianBlurSize() const{ return m_GaussianBlurSize;} inline int getGaussianBlurSize() const{ return m_GaussianBlurSize;}
@ -57,13 +57,13 @@ public:
inline void setJudgeAngle(int param){ m_angle = param;} inline void setJudgeAngle(int param){ m_angle = param;}
//! 是否开启调试模式 //! 是否开启调试模式
inline void setDebug(int param){ m_debug = param;} inline void setDebug(int param){ m_debug = param;}
//! 获取调试模式状态 //! 获取调试模式状态
inline int getDebug(){ return m_debug;} inline int getDebug(){ return m_debug;}
//! PlateLocate所用常量 //! PlateLocate所用常量
static const int DEFAULT_GAUSSIANBLUR_SIZE = 5; static const int DEFAULT_GAUSSIANBLUR_SIZE = 5;
static const int SOBEL_SCALE = 1; static const int SOBEL_SCALE = 1;
static const int SOBEL_DELTA = 0; static const int SOBEL_DELTA = 0;
@ -73,39 +73,39 @@ public:
static const int DEFAULT_MORPH_SIZE_WIDTH = 17; static const int DEFAULT_MORPH_SIZE_WIDTH = 17;
static const int DEFAULT_MORPH_SIZE_HEIGHT = 3; static const int DEFAULT_MORPH_SIZE_HEIGHT = 3;
//! showResultMat所用常量 //! showResultMat所用常量
static const int WIDTH = 136; static const int WIDTH = 136;
static const int HEIGHT = 36; static const int HEIGHT = 36;
static const int TYPE = CV_8UC3; static const int TYPE = CV_8UC3;
//! verifySize所用常量 //! verifySize所用常量
static const int DEFAULT_VERIFY_MIN = 3; static const int DEFAULT_VERIFY_MIN = 3;
static const int DEFAULT_VERIFY_MAX = 20; static const int DEFAULT_VERIFY_MAX = 20;
//! 角度判断所用常量 //! 角度判断所用常量
static const int DEFAULT_ANGLE = 30; static const int DEFAULT_ANGLE = 30;
//! 是否开启调试模式常量默认0代表关闭 //! 是否开启调试模式常量默认0代表关闭
static const int DEFAULT_DEBUG = 0; static const int DEFAULT_DEBUG = 0;
protected: protected:
//! 高斯模糊所用变量 //! 高斯模糊所用变量
int m_GaussianBlurSize; int m_GaussianBlurSize;
//! 连接操作所用变量 //! 连接操作所用变量
int m_MorphSizeWidth; int m_MorphSizeWidth;
int m_MorphSizeHeight; int m_MorphSizeHeight;
//! verifySize所用变量 //! verifySize所用变量
float m_error; float m_error;
float m_aspect; float m_aspect;
int m_verifyMin; int m_verifyMin;
int m_verifyMax; int m_verifyMax;
//! 角度判断所用变量 //! 角度判断所用变量
int m_angle; int m_angle;
//! 是否开启调试模式0关闭非0开启 //! 是否开启调试模式0关闭非0开启
int m_debug; int m_debug;
}; };

@ -27,39 +27,39 @@ class CPlateRecognize : public CPlateDetect, public CCharsRecognise
public: public:
CPlateRecognize(); CPlateRecognize();
//! 车牌检测与字符识别 //! 车牌检测与字符识别
int plateRecognize(Mat, vector<string>&); int plateRecognize(Mat, vector<string>&);
//! 生活模式与工业模式切换 //! 生活模式与工业模式切换
inline void setLifemode(bool param) inline void setLifemode(bool param)
{ {
CPlateDetect::setPDLifemode(param); CPlateDetect::setPDLifemode(param);
} }
//! 是否开启调试模式 //! 是否开启调试模式
inline void setDebug(int param) inline void setDebug(int param)
{ {
CPlateDetect::setPDDebug(param); CPlateDetect::setPDDebug(param);
CCharsRecognise::setCRDebug(param); CCharsRecognise::setCRDebug(param);
} }
////! 车牌定位与判断 ////! 车牌定位与判断
//int plateDetect(Mat, vector<Mat>&); //int plateDetect(Mat, vector<Mat>&);
////! 字符分割与识别 ////! 字符分割与识别
//int charsRecognise(Mat, String&); //int charsRecognise(Mat, String&);
////! 装载SVM ////! 装载SVM
//void LoadSVM(string s); //void LoadSVM(string s);
////! 装载ANN模型 ////! 装载ANN模型
//void LoadANN(string s); //void LoadANN(string s);
private: private:
////!车牌检测 ////!车牌检测
//CPlateDetect* m_plateDetect; //CPlateDetect* m_plateDetect;
////! 字符识别 ////! 字符识别
//CCharsRecognise* m_charsRecognise; //CCharsRecognise* m_charsRecognise;
}; };

@ -2,17 +2,17 @@
#ifndef __UTIL_H__ #ifndef __UTIL_H__
#define __UTIL_H__ #define __UTIL_H__
//C++的获取文件夹函数 //C++的获取文件夹函数
void getFiles(string path, vector<string>& files); void getFiles(string path, vector<string>& files);
//C++的spilt函数 //C++的spilt函数
void SplitString(const string& s, vector<string>& v, const string& c); void SplitString(const string& s, vector<string>& v, const string& c);
//C++的从文件路径名称到文件名称(不包括后缀)的方法 //C++的从文件路径名称到文件名称(不包括后缀)的方法
void getFileName(const string& filepath, string& name); void getFileName(const string& filepath, string& name);
//! levenshtein距离用于计算两个车牌的距离 //! levenshtein距离用于计算两个车牌的距离
//EasyPR中用levenshtein距离衡量车牌识别与真实车牌的误差 //EasyPR中用levenshtein距离衡量车牌识别与真实车牌的误差
template<class T> template<class T>
unsigned int levenshtein_distance(const T &s1, const T & s2) { unsigned int levenshtein_distance(const T &s1, const T & s2) {
const size_t len1 = s1.size(), len2 = s2.size(); const size_t len1 = s1.size(), len2 = s2.size();
@ -31,32 +31,32 @@ unsigned int levenshtein_distance(const T &s1, const T & s2) {
} }
/// test.cpp中方法 /// test.cpp中方法
int testMain(); int testMain();
/// accuracy_test.cpp中方法 /// accuracy_test.cpp中方法
int acurayTest(const string&); int acurayTest(const string&);
/// mc_data_prepare.cpp中方法 /// mc_data_prepare.cpp中方法
void getLearnData(); void getLearnData();
void Code2Province(const string& code, string& province); void Code2Province(const string& code, string& province);
void changeFileName(); void changeFileName();
void getPlateLicense(const string& filepath, string& plateLicense); void getPlateLicense(const string& filepath, string& plateLicense);
/// learn_prepare.cpp中方法 /// learn_prepare.cpp中方法
void label_data(); void label_data();
/// general_test_prepare.cpp中方法 /// general_test_prepare.cpp中方法
int general_test(); int general_test();
// deface.cpp中方法 // deface.cpp中方法
// 反人脸识别函数 // 反人脸识别函数
// 在发布数据到general_test数据集里请先用这里的方法对图像进行处理 // 在发布数据到general_test数据集里请先用这里的方法对图像进行处理
// EasyPR开源项目非常注重保护图片中驾驶人的隐私 // EasyPR开源项目非常注重保护图片中驾驶人的隐私
int deface(); int deface();
/// generate_gdts.cpp中方法 /// generate_gdts.cpp中方法
int generate_gdts(); int generate_gdts();
#endif #endif

@ -18,18 +18,18 @@ extern const string GENERAL_TEST_PATH = "image/general_test";
extern const string NATIVE_TEST_PATH = "image/native_test"; extern const string NATIVE_TEST_PATH = "image/native_test";
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// EasyPR 训练命令行 // EasyPR 训练命令行
const string option[] = const string option[] =
{ {
"1. 测试;" , "1. 测试;" ,
"2. 批量测试;" , "2. 批量测试;" ,
"3. SVM训练;" , "3. SVM训练;" ,
"4. ANN训练(未开放);" , "4. ANN训练(未开放);" ,
"5. GDTS生成;" , "5. GDTS生成;" ,
"6. 开发团队;" , "6. 开发团队;" ,
"7. 感谢名单;" , "7. 感谢名单;" ,
"8. 退出;" , "8. 退出;" ,
}; };
const int optionCount = 8; const int optionCount = 8;
@ -49,7 +49,7 @@ int main()
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << selectOption.str(); cout << selectOption.str();
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << "请选择一项操作:"; cout << "请选择一项操作:";
int select = -1; int select = -1;
bool isRepeat = true; bool isRepeat = true;
@ -75,28 +75,28 @@ int main()
generate_gdts(); generate_gdts();
break; break;
case 6: case 6:
// 开发团队; // 开发团队;
cout << endl; cout << endl;
cout << "我们EasyPR团队目前有一个5人左右的小组在进行EasyPR后续版本的开发工作。" << endl; cout << "我们EasyPR团队目前有一个5人左右的小组在进行EasyPR后续版本的开发工作。" << endl;
cout << "如果你对本项目感兴趣,并且愿意为开源贡献一份力量,我们很欢迎你的加入。" << endl; cout << "如果你对本项目感兴趣,并且愿意为开源贡献一份力量,我们很欢迎你的加入。" << endl;
cout << "目前招聘的主要人才是:车牌定位,图像识别,深度学习,网站建设相关方面的牛人。" << endl; cout << "目前招聘的主要人才是:车牌定位,图像识别,深度学习,网站建设相关方面的牛人。" << endl;
cout << "如果你觉得自己符合条件,请发邮件到地址(easypr_dev@163.com),期待你的加入!" << endl; cout << "如果你觉得自己符合条件,请发邮件到地址(easypr_dev@163.com),期待你的加入!" << endl;
cout << endl; cout << endl;
break; break;
case 7: case 7:
// 感谢名单 // 感谢名单
cout << endl; cout << endl;
cout << "本项目在建设过程中,受到了很多人的帮助,其中以下是对本项目做出突出贡献的" << endl; cout << "本项目在建设过程中,受到了很多人的帮助,其中以下是对本项目做出突出贡献的" << endl;
cout << "(贡献包括有益建议,代码调优,数据提供等等,排名按时间顺序)" << endl; cout << "(贡献包括有益建议,代码调优,数据提供等等,排名按时间顺序)" << endl;
cout << "taotao1233, 唐大侠jsxyhelu如果有一天学习奋斗袁承志圣城小石匠" << endl; cout << "taotao1233, 唐大侠jsxyhelu如果有一天学习奋斗袁承志圣城小石匠" << endl;
cout << "还有很多的同学对本项目也给予了鼓励与支持,在此也一并表示真诚的谢意!" << endl; cout << "还有很多的同学对本项目也给予了鼓励与支持,在此也一并表示真诚的谢意!" << endl;
cout << endl; cout << endl;
break; break;
case 8: case 8:
isExit = true; isExit = true;
break; break;
default: default:
cout << "输入错误,请重新输入:"; cout << "输入错误,请重新输入:";
isRepeat = true; isRepeat = true;
break; break;
} }
@ -104,18 +104,18 @@ int main()
} }
return 0; return 0;
} }
// /EasyPR 训练命令行 结束 // /EasyPR 训练命令行 结束
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// acurayTestMain 命令行 // acurayTestMain 命令行
const string acuray_option[] = const string acuray_option[] =
{ {
"1. general_test;" , "1. general_test;" ,
"2. native_test;" , "2. native_test;" ,
"3. 返回;" , "3. 返回;" ,
}; };
const int acuray_optionCount = 3; const int acuray_optionCount = 3;
@ -135,7 +135,7 @@ int acurayTestMain()
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << selectOption.str(); cout << selectOption.str();
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << "请选择一项操作:"; cout << "请选择一项操作:";
int select = -1; int select = -1;
bool isRepeat = true; bool isRepeat = true;
@ -155,7 +155,7 @@ int acurayTestMain()
isExit = true; isExit = true;
break; break;
default: default:
cout << "输入错误,请重新输入:"; cout << "输入错误,请重新输入:";
isRepeat = true; isRepeat = true;
break; break;
} }
@ -164,22 +164,22 @@ int acurayTestMain()
return 0; return 0;
} }
// acurayTestMain 命令行 // acurayTestMain 命令行
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// SVM 训练命令行 // SVM 训练命令行
const string svm_option[] = const string svm_option[] =
{ {
"1. 生成learndata(调整代码到你的环境后再用);" , "1. 生成learndata(调整代码到你的环境后再用);" ,
"2. 标签learndata;" , "2. 标签learndata;" ,
"3. 车牌检测(not divide and train);" , "3. 车牌检测(not divide and train);" ,
"4. 车牌检测(not train);" , "4. 车牌检测(not train);" ,
"5. 车牌检测(not divide);" , "5. 车牌检测(not divide);" ,
"6. 车牌检测;" , "6. 车牌检测;" ,
"7. 返回;" , "7. 返回;" ,
}; };
const int svm_optionCount = 7; const int svm_optionCount = 7;
@ -199,7 +199,7 @@ int svmMain()
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << selectOption.str(); cout << selectOption.str();
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << "请选择一项操作:"; cout << "请选择一项操作:";
int select = -1; int select = -1;
bool isRepeat = true; bool isRepeat = true;
@ -231,7 +231,7 @@ int svmMain()
isExit = true; isExit = true;
break; break;
default: default:
cout << "输入错误,请重新输入:"; cout << "输入错误,请重新输入:";
isRepeat = true; isRepeat = true;
break; break;
} }
@ -240,5 +240,5 @@ int svmMain()
return 0; return 0;
} }
// SVM 训练命令行 // SVM 训练命令行
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

@ -1,5 +1,5 @@
// 通用正确率测试文件 // 通用正确率测试文件
// AcurayTest对应到main控制命令中的选项2 // AcurayTest对应到main控制命令中的选项2
#include "../include/plate_recognize.h" #include "../include/plate_recognize.h"
#include "../include/util.h" #include "../include/util.h"
@ -9,7 +9,7 @@ using namespace easypr;
int acurayTest(const string& test_path) int acurayTest(const string& test_path)
{ {
////获取该路径下的所有文件 ////获取该路径下的所有文件
vector<string> files; vector<string> files;
getFiles(test_path, files); getFiles(test_path, files);
@ -32,20 +32,20 @@ int acurayTest(const string& test_path)
cout << "Begin to test the easypr accuracy!" << endl; cout << "Begin to test the easypr accuracy!" << endl;
// 总的测试图片数量 // 总的测试图片数量
int count_all = 0; int count_all = 0;
// 错误的图片数量 // 错误的图片数量
int count_err = 0; int count_err = 0;
// 未识别的图片数量 // 未识别的图片数量
int count_norecogin = 0; int count_norecogin = 0;
// 总的字符差距 // 总的字符差距
float diff_all = 0; float diff_all = 0;
// 平均字符差距 // 平均字符差距
float diff_avg = 0; float diff_avg = 0;
// 完全匹配的识别次数 // 完全匹配的识别次数
float match_count = 0; float match_count = 0;
// 完全匹配的识别次数所占识别图片中的比例 // 完全匹配的识别次数所占识别图片中的比例
float match_rate = 0; float match_rate = 0;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
@ -53,13 +53,13 @@ int acurayTest(const string& test_path)
string filepath = files[i].c_str(); string filepath = files[i].c_str();
cout << "------------------" << endl; cout << "------------------" << endl;
// 获取真实的车牌 // 获取真实的车牌
string plateLicense = ""; string plateLicense = "";
getFileName(filepath, plateLicense); getFileName(filepath, plateLicense);
cout << "原牌:" << plateLicense << endl; cout << "原牌:" << plateLicense << endl;
// EasyPR开始判断车牌 // EasyPR开始判断车牌
Mat src = imread(filepath); Mat src = imread(filepath);
vector<string> plateVec; vector<string> plateVec;
int result = pr.plateRecognize(src, plateVec); int result = pr.plateRecognize(src, plateVec);
@ -69,20 +69,20 @@ int acurayTest(const string& test_path)
if (num == 0) if (num == 0)
{ {
cout << ""<< "无车牌" <<endl; cout << ""<< "无车牌" <<endl;
if (plateLicense != "无车牌") if (plateLicense != "无车牌")
count_norecogin++; count_norecogin++;
} }
else if ( num > 1) else if ( num > 1)
{ {
// 多车牌使用diff最小的那个记录 // 多车牌使用diff最小的那个记录
int mindiff = 10000; int mindiff = 10000;
for (int j = 0; j < num; j++) for (int j = 0; j < num; j++)
{ {
cout << plateVec[j] << " (" << j+1 << ")"<<endl; cout << plateVec[j] << " (" << j+1 << ")"<<endl;
string colorplate = plateVec[j]; string colorplate = plateVec[j];
// 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小" // 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小"
vector<string> spilt_plate; vector<string> spilt_plate;
SplitString(colorplate, spilt_plate, ":"); SplitString(colorplate, spilt_plate, ":");
@ -95,23 +95,23 @@ int acurayTest(const string& test_path)
} }
} }
cout << "差距:" << mindiff << "个字符" << endl; cout << "差距:" << mindiff << "个字符" << endl;
if(mindiff == 0) if(mindiff == 0)
{ {
// 完全匹配 // 完全匹配
match_count++; match_count++;
} }
diff_all = diff_all + mindiff; diff_all = diff_all + mindiff;
} }
else else
{ {
// 单车牌只计算一次diff // 单车牌只计算一次diff
for (int j = 0; j < num; j++) for (int j = 0; j < num; j++)
{ {
cout << plateVec[j] <<endl; cout << plateVec[j] <<endl;
string colorplate = plateVec[j]; string colorplate = plateVec[j];
// 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小" // 计算"蓝牌:苏E7KU22"中冒号后面的车牌大小"
vector<string> spilt_plate; vector<string> spilt_plate;
SplitString(colorplate, spilt_plate, ":"); SplitString(colorplate, spilt_plate, ":");
@ -119,11 +119,11 @@ int acurayTest(const string& test_path)
if (size == 2) if (size == 2)
{ {
int diff = levenshtein_distance(plateLicense, spilt_plate[size-1]); int diff = levenshtein_distance(plateLicense, spilt_plate[size-1]);
cout << "差距:" << diff << "个字符" << endl; cout << "差距:" << diff << "个字符" << endl;
if(diff == 0) if(diff == 0)
{ {
// 完全匹配 // 完全匹配
match_count++; match_count++;
} }
diff_all = diff_all + diff; diff_all = diff_all + diff;
@ -134,7 +134,7 @@ int acurayTest(const string& test_path)
} }
else else
{ {
cout << "错误码:" << result << endl; cout << "错误码:" << result << endl;
count_err++; count_err++;
} }
count_all++; count_all++;
@ -144,20 +144,20 @@ int acurayTest(const string& test_path)
cout << "Easypr accuracy test end!" << endl; cout << "Easypr accuracy test end!" << endl;
cout << "------------------" << endl; cout << "------------------" << endl;
cout << endl; cout << endl;
cout << "正确率统计:" << endl; cout << "正确率统计:" << endl;
cout << "总图片数:" << count_all << "张, "; cout << "总图片数:" << count_all << "张, ";
cout << "未识别图片:" << count_norecogin << "张, "; cout << "未识别图片:" << count_norecogin << "张, ";
float count_recogin = count_all - (count_err + count_norecogin); float count_recogin = count_all - (count_err + count_norecogin);
float count_rate = count_recogin / count_all * 100; float count_rate = count_recogin / count_all * 100;
cout << "识别率:" << count_rate << "% " << endl; cout << "识别率:" << count_rate << "% " << endl;
diff_avg = diff_all / count_recogin; diff_avg = diff_all / count_recogin;
match_rate = match_count/ count_recogin * 100; match_rate = match_count/ count_recogin * 100;
cout << "平均字距:" << diff_avg << "个, "; cout << "平均字距:" << diff_avg << "个, ";
cout << "完全匹配数:" << match_count << "张, "; cout << "完全匹配数:" << match_count << "张, ";
cout << "完全匹配率:" << match_rate << "% " << endl; cout << "完全匹配率:" << match_rate << "% " << endl;
cout << endl; cout << endl;
cout << "------------------" << endl; cout << "------------------" << endl;

@ -20,21 +20,21 @@ int test_plate_recognize();
int testMain(); int testMain();
//把你要测试的图片地址写在下面 //把你要测试的图片地址写在下面
const string test_img = ""; const string test_img = "";
const string testOption[] = const string testOption[] =
{ {
"1. test plate_locate(车牌定位);" /* 车牌定位 */, "1. test plate_locate(车牌定位);" /* 车牌定位 */,
"2. test plate_judge(车牌判断);" /* 车牌判断 */, "2. test plate_judge(车牌判断);" /* 车牌判断 */,
"3. test plate_detect(车牌检测);" /* 车牌检测(包含车牌定位与车牌判断) */, "3. test plate_detect(车牌检测);" /* 车牌检测(包含车牌定位与车牌判断) */,
"4. test chars_segment(字符分隔);" /* 字符分隔 */, "4. test chars_segment(字符分隔);" /* 字符分隔 */,
"5. test chars_identify(字符鉴别);" /* 字符鉴别 */, "5. test chars_identify(字符鉴别);" /* 字符鉴别 */,
"6. test chars_recognise(字符识别);" /* 字符识别(包含字符分隔与字符鉴别) */, "6. test chars_recognise(字符识别);" /* 字符识别(包含字符分隔与字符鉴别) */,
"7. test plate_recognize(车牌识别);" /* 车牌识别 */, "7. test plate_recognize(车牌识别);" /* 车牌识别 */,
"8. test all(测试全部);" /* 以上全部 */, "8. test all(测试全部);" /* 以上全部 */,
"9. 返回;" /* 退出 */, "9. 返回;" /* 退出 */,
}; };
const int testOptionCount = 9; const int testOptionCount = 9;
@ -54,7 +54,7 @@ int testMain()
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << selectOption.str(); cout << selectOption.str();
cout << "////////////////////////////////////"<< endl; cout << "////////////////////////////////////"<< endl;
cout << "请选择一项操作:"; cout << "请选择一项操作:";
int select = -1; int select = -1;
bool isRepeat = true; bool isRepeat = true;
@ -100,7 +100,7 @@ int testMain()
isExit = true; isExit = true;
break; break;
default: default:
cout << "输入错误,请重新输入:"; cout << "输入错误,请重新输入:";
isRepeat = true; isRepeat = true;
break; break;
} }
@ -143,10 +143,10 @@ int test_plate_judge()
Mat src = imread("image/plate_judge.jpg"); Mat src = imread("image/plate_judge.jpg");
//可能是车牌的图块集合 //可能是车牌的图块集合
vector<Mat> matVec; vector<Mat> matVec;
//经过SVM判断后得到的图块集合 //经过SVM判断后得到的图块集合
vector<Mat> resultVec; vector<Mat> resultVec;
CPlateLocate lo; CPlateLocate lo;
@ -236,7 +236,7 @@ int test_chars_identify()
Mat resultMat = resultVec[j]; Mat resultMat = resultVec[j];
bool isChinses = false; bool isChinses = false;
//默认首个字符块是中文字符 //默认首个字符块是中文字符
if (j == 0) if (j == 0)
isChinses = true; isChinses = true;
@ -245,7 +245,7 @@ int test_chars_identify()
} }
} }
const string plateLicense = "苏E771H6"; const string plateLicense = "苏E771H6";
cout << "plateLicense: " << plateLicense << endl; cout << "plateLicense: " << plateLicense << endl;
cout << "plateIdentify: " << plateIdentify << endl; cout << "plateIdentify: " << plateIdentify << endl;

@ -1,4 +1,4 @@
// ann_train.cpp : ann模型的训练文件主要用在OCR中 // ann_train.cpp : ann模型的训练文件主要用在OCR中
#include <opencv/cv.h> #include <opencv/cv.h>
#include <opencv/cvaux.h> #include <opencv/cvaux.h>
@ -24,21 +24,21 @@ using namespace easypr;
CvANN_MLP ann; CvANN_MLP ann;
//中国车牌 //中国车牌
const char strCharacters[] = {'0','1','2','3','4','5',\ const char strCharacters[] = {'0','1','2','3','4','5',\
'6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\ '6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\
'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \ 'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \
'U','V', 'W', 'X', 'Y', 'Z'}; 'U','V', 'W', 'X', 'Y', 'Z'};
const int numCharacter = 34; /* 没有I和0,10个数字与24个英文字符之和 */ const int numCharacter = 34; /* 没有I和0,10个数字与24个英文字符之和 */
//以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符 //以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符
//有些后面加数字2的表示在训练时常看到字符的一种变形也作为训练数据存储 //有些后面加数字2的表示在训练时常看到字符的一种变形也作为训练数据存储
const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \ const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \ "zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \
"zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \ "zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \
"zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \ "zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \
"zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\ "zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\
"zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */}; "zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */};
const int numChinese = 20; const int numChinese = 20;
const int numAll = 54; /* 34+20=54 */ const int numAll = 54; /* 34+20=54 */
@ -59,7 +59,7 @@ Mat features(Mat in, int sizeData){
int numCols=vhist.cols+hhist.cols+lowData.cols*lowData.cols; int numCols=vhist.cols+hhist.cols+lowData.cols*lowData.cols;
Mat out=Mat::zeros(1,numCols,CV_32F); Mat out=Mat::zeros(1,numCols,CV_32F);
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量 //Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
int j=0; int j=0;
for(int i=0; i<vhist.cols; i++) for(int i=0; i<vhist.cols; i++)
{ {
@ -148,7 +148,7 @@ int saveTrainData()
trainingDataf10.push_back(f10); trainingDataf10.push_back(f10);
trainingDataf15.push_back(f15); trainingDataf15.push_back(f15);
trainingDataf20.push_back(f20); trainingDataf20.push_back(f20);
trainingLabels.push_back(i); //每一幅字符图片所对应的字符类别索引下标 trainingLabels.push_back(i); //每一幅字符图片所对应的字符类别索引下标
} }
} }
@ -248,7 +248,7 @@ int annMain()
saveTrainData(); saveTrainData();
//可根据需要训练不同的predictSize或者neurons的ANN模型 //可根据需要训练不同的predictSize或者neurons的ANN模型
//for (int i = 2; i <= 2; i ++) //for (int i = 2; i <= 2; i ++)
//{ //{
// int size = i * 5; // int size = i * 5;
@ -259,8 +259,8 @@ int annMain()
// } // }
//} //}
//这里演示只训练model文件夹下的ann.xml此模型是一个predictSize=10,neurons=40的ANN模型。 //这里演示只训练model文件夹下的ann.xml此模型是一个predictSize=10,neurons=40的ANN模型。
//根据机器的不同训练时间不一样但一般需要10分钟左右所以慢慢等一会吧。 //根据机器的不同训练时间不一样但一般需要10分钟左右所以慢慢等一会吧。
saveModel(10, 40); saveModel(10, 40);
cout << "To be end." << endl; cout << "To be end." << endl;

@ -1,4 +1,4 @@
// svm_train.cpp : svm模型的训练文件主要用在plate_detect中 // svm_train.cpp : svm模型的训练文件主要用在plate_detect中
#include "../include/plate_recognize.h" #include "../include/plate_recognize.h"
#include "../include/features.h" #include "../include/features.h"
@ -15,14 +15,14 @@ void learn2HasPlate(float bound = 0.7)
char * filePath = "train/data/plate_detect_svm/learn/HasPlate"; char * filePath = "train/data/plate_detect_svm/learn/HasPlate";
vector<string> files; vector<string> files;
////获取该路径下的所有文件 ////获取该路径下的所有文件
getFiles(filePath, files ); getFiles(filePath, files );
int size = files.size(); int size = files.size();
if (0 == size) if (0 == size)
cout << "No File Found in learn HasPlate!" << endl; cout << "No File Found in learn HasPlate!" << endl;
////随机选取70%作为训练数据30%作为测试数据 ////随机选取70%作为训练数据30%作为测试数据
srand(unsigned(time(NULL))); srand(unsigned(time(NULL)));
random_shuffle(files.begin(), files.end()); random_shuffle(files.begin(), files.end());
@ -61,13 +61,13 @@ void learn2NoPlate(float bound = 0.7)
char * filePath = "train/data/plate_detect_svm/learn/NoPlate"; char * filePath = "train/data/plate_detect_svm/learn/NoPlate";
vector<string> files; vector<string> files;
////获取该路径下的所有文件 ////获取该路径下的所有文件
getFiles(filePath, files ); getFiles(filePath, files );
int size = files.size(); int size = files.size();
if (0 == size) if (0 == size)
cout << "No File Found in learn NoPlate!" << endl; cout << "No File Found in learn NoPlate!" << endl;
////随机选取70%作为训练数据30%作为测试数据 ////随机选取70%作为训练数据30%作为测试数据
srand(unsigned(time(NULL))); srand(unsigned(time(NULL)));
random_shuffle(files.begin(), files.end()); random_shuffle(files.begin(), files.end());
@ -107,7 +107,7 @@ void getHasPlateTrain(Mat& trainingImages, vector<int>& trainingLabels,
char * filePath = "train/data/plate_detect_svm/train/HasPlate"; char * filePath = "train/data/plate_detect_svm/train/HasPlate";
vector<string> files; vector<string> files;
////获取该路径下的所有文件 ////获取该路径下的所有文件
getFiles(filePath, files ); getFiles(filePath, files );
int size = files.size(); int size = files.size();
@ -120,7 +120,7 @@ void getHasPlateTrain(Mat& trainingImages, vector<int>& trainingLabels,
//cout << files[i].c_str() << endl; //cout << files[i].c_str() << endl;
Mat img = imread(files[i].c_str()); Mat img = imread(files[i].c_str());
//调用回调函数决定特征 //调用回调函数决定特征
Mat features; Mat features;
getFeatures(img, features); getFeatures(img, features);
features = features.reshape(1, 1); features = features.reshape(1, 1);
@ -138,7 +138,7 @@ void getNoPlateTrain(Mat& trainingImages, vector<int>& trainingLabels,
char * filePath = "train/data/plate_detect_svm/train/NoPlate"; char * filePath = "train/data/plate_detect_svm/train/NoPlate";
vector<string> files; vector<string> files;
////获取该路径下的所有文件 ////获取该路径下的所有文件
getFiles(filePath, files ); getFiles(filePath, files );
int size = files.size(); int size = files.size();
@ -151,7 +151,7 @@ void getNoPlateTrain(Mat& trainingImages, vector<int>& trainingLabels,
//cout << files[i].c_str() << endl; //cout << files[i].c_str() << endl;
Mat img = imread(files[i].c_str()); Mat img = imread(files[i].c_str());
//调用回调函数决定特征 //调用回调函数决定特征
Mat features; Mat features;
getFeatures(img, features); getFeatures(img, features);
features = features.reshape(1, 1); features = features.reshape(1, 1);
@ -167,7 +167,7 @@ void getHasPlateTest(vector<Mat>& testingImages, vector<int>& testingLabels)
char * filePath = "train/data/plate_detect_svm/test/HasPlate"; char * filePath = "train/data/plate_detect_svm/test/HasPlate";
vector<string> files; vector<string> files;
////获取该路径下的所有文件 ////获取该路径下的所有文件
getFiles(filePath, files ); getFiles(filePath, files );
int size = files.size(); int size = files.size();
@ -191,7 +191,7 @@ void getNoPlateTest(vector<Mat>& testingImages, vector<int>& testingLabels)
char * filePath = "train/data/plate_detect_svm/test/NoPlate"; char * filePath = "train/data/plate_detect_svm/test/NoPlate";
vector<string> files; vector<string> files;
////获取该路径下的所有文件 ////获取该路径下的所有文件
getFiles(filePath, files ); getFiles(filePath, files );
int size = files.size(); int size = files.size();
@ -210,7 +210,7 @@ void getNoPlateTest(vector<Mat>& testingImages, vector<int>& testingLabels)
} }
//! 测试SVM的准确率回归率以及FScore //! 测试SVM的准确率回归率以及FScore
void getAccuracy(Mat& testingclasses_preditc, Mat& testingclasses_real) void getAccuracy(Mat& testingclasses_preditc, Mat& testingclasses_real)
{ {
int channels = testingclasses_preditc.channels(); int channels = testingclasses_preditc.channels();
@ -312,13 +312,13 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
if (dividePrepared == false) if (dividePrepared == false)
{ {
//分割learn里的数据到train和test里 //分割learn里的数据到train和test里
cout << "Divide learn to train and test" << endl; cout << "Divide learn to train and test" << endl;
learn2HasPlate(); learn2HasPlate();
learn2NoPlate(); learn2NoPlate();
} }
//将训练数据加载入内存 //将训练数据加载入内存
if (trainPrepared == false) if (trainPrepared == false)
{ {
cout << "Begin to get train data to memory" << endl; cout << "Begin to get train data to memory" << endl;
@ -335,7 +335,7 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
vector<Mat> testingImages; vector<Mat> testingImages;
vector<int> testingLabels_real; vector<int> testingLabels_real;
//将测试数据加载入内存 //将测试数据加载入内存
cout << "Begin to get test data to memory" << endl; cout << "Begin to get test data to memory" << endl;
getHasPlateTest(testingImages, testingLabels_real); getHasPlateTest(testingImages, testingLabels_real);
getNoPlateTest(testingImages, testingLabels_real); getNoPlateTest(testingImages, testingLabels_real);
@ -345,8 +345,8 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
{ {
CvSVMParams SVM_params; CvSVMParams SVM_params;
SVM_params.svm_type = CvSVM::C_SVC; SVM_params.svm_type = CvSVM::C_SVC;
//SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR; 线型,也就是无核 //SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR; 线型,也就是无核
SVM_params.kernel_type = CvSVM::RBF; //CvSVM::RBF 径向基函数,也就是高斯核 SVM_params.kernel_type = CvSVM::RBF; //CvSVM::RBF 径向基函数,也就是高斯核
SVM_params.degree = 0.1; SVM_params.degree = 0.1;
SVM_params.gamma = 1; SVM_params.gamma = 1;
SVM_params.coef0 = 0.1; SVM_params.coef0 = 0.1;
@ -393,7 +393,7 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
//cout << files[i].c_str() << endl; //cout << files[i].c_str() << endl;
Mat p = testingImages[i]; Mat p = testingImages[i];
//调用回调函数决定特征 //调用回调函数决定特征
Mat features; Mat features;
getFeatures(p, features); getFeatures(p, features);

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

Loading…
Cancel
Save