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
*.vsp
*.vspx
*.suo
# TFS 2012 Local Workspace
$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 NDEBUG
//中国车牌
//中国车牌
const char strCharacters[] = {'0','1','2','3','4','5',\
'6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\
'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \
'6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\
'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \
'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" /* 赣*/, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \
"zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \
"zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \
"zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\
"zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */};
//以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符
const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \
"zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \
"zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \
"zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\
"zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */};
const int numChinese = 20;
const int numAll = 54; /* 34+20=54 */
@ -36,26 +36,26 @@ CCharsIdentify::CCharsIdentify()
if (m_map.empty())
{
m_map.insert(pair<string, string>("zh_cuan",""));
m_map.insert(pair<string, string>("zh_e",""));
m_map.insert(pair<string, string>("zh_gan",""));
m_map.insert(pair<string, string>("zh_hei",""));
m_map.insert(pair<string, string>("zh_hu",""));
m_map.insert(pair<string, string>("zh_ji",""));
m_map.insert(pair<string, string>("zh_jl",""));
m_map.insert(pair<string, string>("zh_jin",""));
m_map.insert(pair<string, string>("zh_jing",""));
m_map.insert(pair<string, string>("zh_shan",""));
m_map.insert(pair<string, string>("zh_liao",""));
m_map.insert(pair<string, string>("zh_lu",""));
m_map.insert(pair<string, string>("zh_min",""));
m_map.insert(pair<string, string>("zh_ning",""));
m_map.insert(pair<string, string>("zh_su",""));
m_map.insert(pair<string, string>("zh_sx",""));
m_map.insert(pair<string, string>("zh_wan",""));
m_map.insert(pair<string, string>("zh_yu",""));
m_map.insert(pair<string, string>("zh_yue",""));
m_map.insert(pair<string, string>("zh_zhe",""));
m_map.insert(pair<string, string>("zh_cuan",""));
m_map.insert(pair<string, string>("zh_e",""));
m_map.insert(pair<string, string>("zh_gan",""));
m_map.insert(pair<string, string>("zh_hei",""));
m_map.insert(pair<string, string>("zh_hu",""));
m_map.insert(pair<string, string>("zh_ji",""));
m_map.insert(pair<string, string>("zh_jl",""));
m_map.insert(pair<string, string>("zh_jin",""));
m_map.insert(pair<string, string>("zh_jing",""));
m_map.insert(pair<string, string>("zh_shan",""));
m_map.insert(pair<string, string>("zh_liao",""));
m_map.insert(pair<string, string>("zh_lu",""));
m_map.insert(pair<string, string>("zh_min",""));
m_map.insert(pair<string, string>("zh_ning",""));
m_map.insert(pair<string, string>("zh_su",""));
m_map.insert(pair<string, string>("zh_sx",""));
m_map.insert(pair<string, string>("zh_wan",""));
m_map.insert(pair<string, string>("zh_yu",""));
m_map.insert(pair<string, string>("zh_yue",""));
m_map.insert(pair<string, string>("zh_zhe",""));
}
}
@ -72,7 +72,7 @@ void CCharsIdentify::LoadModel(string s)
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)
{
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++){
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
@ -88,12 +88,12 @@ Mat CCharsIdentify::ProjectedHistogram(Mat img, int t)
minMaxLoc(mhist, &min, &max);
if(max>0)
mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图
mhist.convertTo(mhist,-1 , 1.0f/max, 0);//用mhist直方图中的最大值归一化直方图
return mhist;
}
//! 获得字符的特征图
//! 获得字符的特征图
Mat CCharsIdentify::features(Mat in, int sizeData)
{
//Histogram features
@ -109,7 +109,7 @@ Mat CCharsIdentify::features(Mat in, int sizeData)
Mat out = Mat::zeros(1, numCols, CV_32F);
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
int j=0;
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 result = -1;
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)
{
Mat f = features(input, m_predictSize);

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

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

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

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

@ -27,7 +27,7 @@ void CPlateJudge::LoadModel(string s)
svm.load(s.c_str(), "svm");
}
//! 直方图均衡
//! 直方图均衡
Mat CPlateJudge::histeq(Mat in)
{
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)
{
if (m_getFeatures == NULL)
@ -58,7 +58,7 @@ int CPlateJudge::plateJudge(const Mat& inMat,int& result)
Mat features;
m_getFeatures(inMat, features);
//通过直方图均衡化后的彩色图进行预测
//通过直方图均衡化后的彩色图进行预测
Mat p = features.reshape(1, 1);
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,
vector<Mat>& resultVec)
{

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

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

@ -24,39 +24,39 @@ class CCharsIdentify
public:
CCharsIdentify();
//! 字符分割
//! 字符分割
string charsIdentify(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 features(Mat in, int sizeData);
//! 装载ANN模型
//! 装载ANN模型
void LoadModel();
//! 装载ANN模型
//! 装载ANN模型
void LoadModel(string s);
//! 设置与读取模型路径
//! 设置与读取模型路径
inline void setModelPath(string path){ m_path = path; }
inline string getModelPath() const{ return m_path; }
private:
//使用的ANN模型
//使用的ANN模型
CvANN_MLP ann;
//! 模型存储路径
//! 模型存储路径
string m_path;
//! 特征尺寸
//! 特征尺寸
int m_predictSize;
//! 省份对应map
//! 省份对应map
map<string, string> m_map;
};

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

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

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

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

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

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

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

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

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

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

@ -20,21 +20,21 @@ int test_plate_recognize();
int testMain();
//把你要测试的图片地址写在下面
//把你要测试的图片地址写在下面
const string test_img = "";
const string testOption[] =
{
"1. test plate_locate(车牌定位);" /* 车牌定位 */,
"2. test plate_judge(车牌判断);" /* 车牌判断 */,
"3. test plate_detect(车牌检测);" /* 车牌检测(包含车牌定位与车牌判断) */,
"4. test chars_segment(字符分隔);" /* 字符分隔 */,
"5. test chars_identify(字符鉴别);" /* 字符鉴别 */,
"6. test chars_recognise(字符识别);" /* 字符识别(包含字符分隔与字符鉴别) */,
"7. test plate_recognize(车牌识别);" /* 车牌识别 */,
"8. test all(测试全部);" /* 以上全部 */,
"9. 返回;" /* 退出 */,
"1. test plate_locate(车牌定位);" /* 车牌定位 */,
"2. test plate_judge(车牌判断);" /* 车牌判断 */,
"3. test plate_detect(车牌检测);" /* 车牌检测(包含车牌定位与车牌判断) */,
"4. test chars_segment(字符分隔);" /* 字符分隔 */,
"5. test chars_identify(字符鉴别);" /* 字符鉴别 */,
"6. test chars_recognise(字符识别);" /* 字符识别(包含字符分隔与字符鉴别) */,
"7. test plate_recognize(车牌识别);" /* 车牌识别 */,
"8. test all(测试全部);" /* 以上全部 */,
"9. 返回;" /* 退出 */,
};
const int testOptionCount = 9;
@ -54,7 +54,7 @@ int testMain()
cout << "////////////////////////////////////"<< endl;
cout << selectOption.str();
cout << "////////////////////////////////////"<< endl;
cout << "请选择一项操作:";
cout << "请选择一项操作:";
int select = -1;
bool isRepeat = true;
@ -100,7 +100,7 @@ int testMain()
isExit = true;
break;
default:
cout << "输入错误,请重新输入:";
cout << "输入错误,请重新输入:";
isRepeat = true;
break;
}
@ -143,10 +143,10 @@ int test_plate_judge()
Mat src = imread("image/plate_judge.jpg");
//可能是车牌的图块集合
//可能是车牌的图块集合
vector<Mat> matVec;
//经过SVM判断后得到的图块集合
//经过SVM判断后得到的图块集合
vector<Mat> resultVec;
CPlateLocate lo;
@ -236,7 +236,7 @@ int test_chars_identify()
Mat resultMat = resultVec[j];
bool isChinses = false;
//默认首个字符块是中文字符
//默认首个字符块是中文字符
if (j == 0)
isChinses = true;
@ -245,7 +245,7 @@ int test_chars_identify()
}
}
const string plateLicense = "苏E771H6";
const string plateLicense = "苏E771H6";
cout << "plateLicense: " << plateLicense << 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/cvaux.h>
@ -24,21 +24,21 @@ using namespace easypr;
CvANN_MLP ann;
//中国车牌
//中国车牌
const char strCharacters[] = {'0','1','2','3','4','5',\
'6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\
'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \
'6','7','8','9','A','B', 'C', 'D', 'E','F', 'G', 'H', /* 没有I */\
'J', 'K', 'L', 'M', 'N', /* 没有O */ 'P', 'Q', 'R', 'S', 'T', \
'U','V', 'W', 'X', 'Y', 'Z'};
const int numCharacter = 34; /* 没有I和0,10个数字与24个英文字符之和 */
const int numCharacter = 34; /* 没有I和0,10个数字与24个英文字符之和 */
//以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符
//有些后面加数字2的表示在训练时常看到字符的一种变形也作为训练数据存储
const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \
"zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \
"zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \
"zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\
"zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */};
//以下都是我训练时用到的中文字符数据,并不全面,有些省份没有训练数据所以没有字符
//有些后面加数字2的表示在训练时常看到字符的一种变形也作为训练数据存储
const string strChinese[] = {"zh_cuan" /* 川 */, "zh_e" /* 鄂 */, "zh_gan" /* 赣*/, \
"zh_hei" /* 黑 */, "zh_hu" /* 沪 */, "zh_ji" /* 冀 */, \
"zh_jl" /* 吉 */, "zh_jin" /* 津 */, "zh_jing" /* 京 */, "zh_shan" /* 陕 */, \
"zh_liao" /* 辽 */, "zh_lu" /* 鲁 */, "zh_min" /* 闽 */, "zh_ning" /* 宁 */, \
"zh_su" /* 苏 */, "zh_sx" /* 晋 */, "zh_wan" /* 皖 */,\
"zh_yu" /* 豫 */, "zh_yue" /* 粤 */, "zh_zhe" /* 浙 */};
const int numChinese = 20;
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;
Mat out=Mat::zeros(1,numCols,CV_32F);
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
//Asign values to feature,ANN的样本特征为水平、垂直直方图和低分辨率图像所组成的矢量
int j=0;
for(int i=0; i<vhist.cols; i++)
{
@ -148,7 +148,7 @@ int saveTrainData()
trainingDataf10.push_back(f10);
trainingDataf15.push_back(f15);
trainingDataf20.push_back(f20);
trainingLabels.push_back(i); //每一幅字符图片所对应的字符类别索引下标
trainingLabels.push_back(i); //每一幅字符图片所对应的字符类别索引下标
}
}
@ -248,7 +248,7 @@ int annMain()
saveTrainData();
//可根据需要训练不同的predictSize或者neurons的ANN模型
//可根据需要训练不同的predictSize或者neurons的ANN模型
//for (int i = 2; i <= 2; i ++)
//{
// int size = i * 5;
@ -259,8 +259,8 @@ int annMain()
// }
//}
//这里演示只训练model文件夹下的ann.xml此模型是一个predictSize=10,neurons=40的ANN模型。
//根据机器的不同训练时间不一样但一般需要10分钟左右所以慢慢等一会吧。
//这里演示只训练model文件夹下的ann.xml此模型是一个predictSize=10,neurons=40的ANN模型。
//根据机器的不同训练时间不一样但一般需要10分钟左右所以慢慢等一会吧。
saveModel(10, 40);
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/features.h"
@ -15,14 +15,14 @@ void learn2HasPlate(float bound = 0.7)
char * filePath = "train/data/plate_detect_svm/learn/HasPlate";
vector<string> files;
////获取该路径下的所有文件
////获取该路径下的所有文件
getFiles(filePath, files );
int size = files.size();
if (0 == size)
cout << "No File Found in learn HasPlate!" << endl;
////随机选取70%作为训练数据30%作为测试数据
////随机选取70%作为训练数据30%作为测试数据
srand(unsigned(time(NULL)));
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";
vector<string> files;
////获取该路径下的所有文件
////获取该路径下的所有文件
getFiles(filePath, files );
int size = files.size();
if (0 == size)
cout << "No File Found in learn NoPlate!" << endl;
////随机选取70%作为训练数据30%作为测试数据
////随机选取70%作为训练数据30%作为测试数据
srand(unsigned(time(NULL)));
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";
vector<string> files;
////获取该路径下的所有文件
////获取该路径下的所有文件
getFiles(filePath, files );
int size = files.size();
@ -120,7 +120,7 @@ void getHasPlateTrain(Mat& trainingImages, vector<int>& trainingLabels,
//cout << files[i].c_str() << endl;
Mat img = imread(files[i].c_str());
//调用回调函数决定特征
//调用回调函数决定特征
Mat features;
getFeatures(img, features);
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";
vector<string> files;
////获取该路径下的所有文件
////获取该路径下的所有文件
getFiles(filePath, files );
int size = files.size();
@ -151,7 +151,7 @@ void getNoPlateTrain(Mat& trainingImages, vector<int>& trainingLabels,
//cout << files[i].c_str() << endl;
Mat img = imread(files[i].c_str());
//调用回调函数决定特征
//调用回调函数决定特征
Mat features;
getFeatures(img, features);
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";
vector<string> files;
////获取该路径下的所有文件
////获取该路径下的所有文件
getFiles(filePath, files );
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";
vector<string> files;
////获取该路径下的所有文件
////获取该路径下的所有文件
getFiles(filePath, files );
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)
{
int channels = testingclasses_preditc.channels();
@ -312,13 +312,13 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
if (dividePrepared == false)
{
//分割learn里的数据到train和test里
//分割learn里的数据到train和test里
cout << "Divide learn to train and test" << endl;
learn2HasPlate();
learn2NoPlate();
}
//将训练数据加载入内存
//将训练数据加载入内存
if (trainPrepared == false)
{
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<int> testingLabels_real;
//将测试数据加载入内存
//将测试数据加载入内存
cout << "Begin to get test data to memory" << endl;
getHasPlateTest(testingImages, testingLabels_real);
getNoPlateTest(testingImages, testingLabels_real);
@ -345,8 +345,8 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
{
CvSVMParams SVM_params;
SVM_params.svm_type = CvSVM::C_SVC;
//SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR; 线型,也就是无核
SVM_params.kernel_type = CvSVM::RBF; //CvSVM::RBF 径向基函数,也就是高斯核
//SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR; 线型,也就是无核
SVM_params.kernel_type = CvSVM::RBF; //CvSVM::RBF 径向基函数,也就是高斯核
SVM_params.degree = 0.1;
SVM_params.gamma = 1;
SVM_params.coef0 = 0.1;
@ -393,7 +393,7 @@ int svmTrain(bool dividePrepared = true, bool trainPrepared = true,
//cout << files[i].c_str() << endl;
Mat p = testingImages[i];
//调用回调函数决定特征
//调用回调函数决定特征
Mat features;
getFeatures(p, features);

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

Loading…
Cancel
Save