更新vs工程到端到端模型
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
@@ -22,32 +22,32 @@
|
|||||||
<ProjectGuid>{69FAD143-D7C9-4804-A186-90254BD80549}</ProjectGuid>
|
<ProjectGuid>{69FAD143-D7C9-4804-A186-90254BD80549}</ProjectGuid>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<RootNamespace>PrjWin</RootNamespace>
|
<RootNamespace>PrjWin</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -76,9 +76,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>D:\Prj-Win\lpr\include;D:\opencv\build\include\opencv2;D:\opencv\build\include\opencv;D:\opencv\build\include;$(IncludePath)</IncludePath>
|
<IncludePath>D:\Prj-Win\lpr\include;D:\opencv\build\include;D:\opencv\build\include\opencv2;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>D:\opencv\build\x64\vc14\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>D:\opencv\build\x64\vc15\lib;$(LibraryPath)</LibraryPath>
|
||||||
<OutDir>$(SolutionDir)Build</OutDir>
|
<OutDir>$(SolutionDir)Build\</OutDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>opencv_world400d.lib;opencv_world400.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -161,15 +161,18 @@
|
|||||||
<ClInclude Include="..\lpr\include\PlateInfo.h" />
|
<ClInclude Include="..\lpr\include\PlateInfo.h" />
|
||||||
<ClInclude Include="..\lpr\include\PlateSegmentation.h" />
|
<ClInclude Include="..\lpr\include\PlateSegmentation.h" />
|
||||||
<ClInclude Include="..\lpr\include\Recognizer.h" />
|
<ClInclude Include="..\lpr\include\Recognizer.h" />
|
||||||
|
<ClInclude Include="..\lpr\include\SegmentationFreeRecognizer.h" />
|
||||||
<ClInclude Include="..\lpr\src\util.h" />
|
<ClInclude Include="..\lpr\src\util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\lpr\src\CNNRecognizer.cpp" />
|
<ClCompile Include="..\lpr\src\CNNRecognizer.cpp" />
|
||||||
<ClCompile Include="..\lpr\src\FastDeskew.cpp" />
|
<ClCompile Include="..\lpr\src\FastDeskew.cpp" />
|
||||||
<ClCompile Include="..\lpr\src\FineMapping.cpp" />
|
<ClCompile Include="..\lpr\src\FineMapping.cpp" />
|
||||||
|
<ClCompile Include="..\lpr\src\Pipeline.cpp" />
|
||||||
<ClCompile Include="..\lpr\src\PlateDetection.cpp" />
|
<ClCompile Include="..\lpr\src\PlateDetection.cpp" />
|
||||||
<ClCompile Include="..\lpr\src\PlateSegmentation.cpp" />
|
<ClCompile Include="..\lpr\src\PlateSegmentation.cpp" />
|
||||||
<ClCompile Include="..\lpr\src\Recognizer.cpp" />
|
<ClCompile Include="..\lpr\src\Recognizer.cpp" />
|
||||||
|
<ClCompile Include="..\lpr\src\SegmentationFreeRecognizer.cpp" />
|
||||||
<ClCompile Include="..\lpr\tests\test_pipeline.cpp" />
|
<ClCompile Include="..\lpr\tests\test_pipeline.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|||||||
@@ -48,6 +48,9 @@
|
|||||||
<ClInclude Include="..\lpr\src\util.h">
|
<ClInclude Include="..\lpr\src\util.h">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\lpr\include\SegmentationFreeRecognizer.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\lpr\src\CNNRecognizer.cpp">
|
<ClCompile Include="..\lpr\src\CNNRecognizer.cpp">
|
||||||
@@ -71,5 +74,11 @@
|
|||||||
<ClCompile Include="..\lpr\tests\test_pipeline.cpp">
|
<ClCompile Include="..\lpr\tests\test_pipeline.cpp">
|
||||||
<Filter>源文件\test</Filter>
|
<Filter>源文件\test</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lpr\src\Pipeline.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\lpr\src\SegmentationFreeRecognizer.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 21/10/2017.
|
// Created by Jack Yu on 21/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SWIFTPR_CNNRECOGNIZER_H
|
#ifndef SWIFTPR_CNNRECOGNIZER_H
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by ��� on 22/10/2017.
|
// Created by 庾金科 on 22/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SWIFTPR_PIPLINE_H
|
#ifndef SWIFTPR_PIPLINE_H
|
||||||
@@ -12,68 +12,43 @@
|
|||||||
#include "FastDeskew.h"
|
#include "FastDeskew.h"
|
||||||
#include "FineMapping.h"
|
#include "FineMapping.h"
|
||||||
#include "Recognizer.h"
|
#include "Recognizer.h"
|
||||||
|
#include "SegmentationFreeRecognizer.h"
|
||||||
|
|
||||||
namespace pr{
|
namespace pr{
|
||||||
|
|
||||||
|
const std::vector<std::string> CH_PLATE_CODE{"京", "沪", "津", "渝", "冀", "晋", "蒙", "辽", "吉", "黑", "苏", "浙", "皖", "闽", "赣", "鲁", "豫", "鄂", "湘", "粤", "桂",
|
||||||
|
"琼", "川", "贵", "云", "藏", "陕", "甘", "青", "宁", "新", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A",
|
||||||
|
"B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
|
||||||
|
"Y", "Z","港","学","使","警","澳","挂","军","北","南","广","沈","兰","成","济","海","民","航","空"};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int SEGMENTATION_FREE_METHOD = 0;
|
||||||
|
const int SEGMENTATION_BASED_METHOD = 1;
|
||||||
|
|
||||||
class PipelinePR{
|
class PipelinePR{
|
||||||
public:
|
public:
|
||||||
GeneralRecognizer *generalRecognizer;
|
GeneralRecognizer *generalRecognizer;
|
||||||
PlateDetection *plateDetection;
|
PlateDetection *plateDetection;
|
||||||
PlateSegmentation *plateSegmentation;
|
PlateSegmentation *plateSegmentation;
|
||||||
FineMapping *fineMapping;
|
FineMapping *fineMapping;
|
||||||
PipelinePR(std::string detector_filename,
|
SegmentationFreeRecognizer *segmentationFreeRecognizer;
|
||||||
std::string finemapping_prototxt, std::string finemapping_caffemodel,
|
|
||||||
std::string segmentation_prototxt, std::string segmentation_caffemodel,
|
|
||||||
std::string charRecognization_proto, std::string charRecognization_caffemodel
|
|
||||||
) {
|
|
||||||
plateDetection = new PlateDetection(detector_filename);
|
|
||||||
fineMapping = new FineMapping(finemapping_prototxt, finemapping_caffemodel);
|
|
||||||
plateSegmentation = new PlateSegmentation(segmentation_prototxt, segmentation_caffemodel);
|
|
||||||
generalRecognizer = new CNNRecognizer(charRecognization_proto, charRecognization_caffemodel);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PipelinePR() {
|
PipelinePR(std::string detector_filename,
|
||||||
|
std::string finemapping_prototxt,std::string finemapping_caffemodel,
|
||||||
delete plateDetection;
|
std::string segmentation_prototxt,std::string segmentation_caffemodel,
|
||||||
delete fineMapping;
|
std::string charRecognization_proto,std::string charRecognization_caffemodel,
|
||||||
delete plateSegmentation;
|
std::string segmentationfree_proto,std::string segmentationfree_caffemodel
|
||||||
delete generalRecognizer;
|
);
|
||||||
}
|
~PipelinePR();
|
||||||
|
|
||||||
std::vector<std::string> chars_code{ "京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖","闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z" };
|
|
||||||
|
|
||||||
std::vector<std::string> plateRes;
|
std::vector<std::string> plateRes;
|
||||||
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat plateImage) {
|
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat plateImage,int method);
|
||||||
std::vector<PlateInfo> results;
|
|
||||||
std::vector<pr::PlateInfo> plates;
|
|
||||||
plateDetection->plateDetectionRough(plateImage, plates);
|
|
||||||
|
|
||||||
for (pr::PlateInfo plateinfo : plates) {
|
|
||||||
|
|
||||||
cv::Mat image_finemapping = plateinfo.getPlateImage();
|
|
||||||
image_finemapping = fineMapping->FineMappingVertical(image_finemapping);
|
|
||||||
image_finemapping = pr::fastdeskew(image_finemapping, 5);
|
|
||||||
image_finemapping = fineMapping->FineMappingHorizon(image_finemapping, 2, 5);
|
|
||||||
cv::resize(image_finemapping, image_finemapping, cv::Size(136, 36));
|
|
||||||
plateinfo.setPlateImage(image_finemapping);
|
|
||||||
std::vector<cv::Rect> rects;
|
|
||||||
plateSegmentation->segmentPlatePipline(plateinfo, 1, rects);
|
|
||||||
plateSegmentation->ExtractRegions(plateinfo, rects);
|
|
||||||
cv::copyMakeBorder(image_finemapping, image_finemapping, 0, 0, 0, 20, cv::BORDER_REPLICATE);
|
|
||||||
|
|
||||||
plateinfo.setPlateImage(image_finemapping);
|
|
||||||
generalRecognizer->SegmentBasedSequenceRecognition(plateinfo);
|
|
||||||
plateinfo.decodePlateNormal(chars_code);
|
|
||||||
results.push_back(plateinfo);
|
|
||||||
std::cout << plateinfo.getPlateName() << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// for (auto str:results) {
|
|
||||||
// std::cout << str << std::endl;
|
|
||||||
// }
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#define SWIFTPR_PLATEDETECTION_H
|
#define SWIFTPR_PLATEDETECTION_H
|
||||||
|
|
||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
#include "PlateInfo.h"
|
#include <PlateInfo.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
namespace pr{
|
namespace pr{
|
||||||
class PlateDetection{
|
class PlateDetection{
|
||||||
|
|||||||
@@ -10,17 +10,14 @@ namespace pr {
|
|||||||
typedef std::vector<cv::Mat> Character;
|
typedef std::vector<cv::Mat> Character;
|
||||||
|
|
||||||
enum PlateColor { BLUE, YELLOW, WHITE, GREEN, BLACK,UNKNOWN};
|
enum PlateColor { BLUE, YELLOW, WHITE, GREEN, BLACK,UNKNOWN};
|
||||||
enum CharType {CHINESE,LETTER,LETTER_NUMS};
|
enum CharType {CHINESE,LETTER,LETTER_NUMS,INVALID};
|
||||||
|
|
||||||
|
|
||||||
class PlateInfo {
|
class PlateInfo {
|
||||||
public:
|
public:
|
||||||
std::vector<std::pair<CharType,cv::Mat>> plateChars;
|
std::vector<std::pair<CharType,cv::Mat>> plateChars;
|
||||||
std::vector<std::pair<CharType,cv::Mat>> plateCoding;
|
std::vector<std::pair<CharType,cv::Mat>> plateCoding;
|
||||||
|
|
||||||
float confidence = 0;
|
float confidence = 0;
|
||||||
|
|
||||||
|
|
||||||
PlateInfo(const cv::Mat &plateData, std::string plateName, cv::Rect plateRect, PlateColor plateType) {
|
PlateInfo(const cv::Mat &plateData, std::string plateName, cv::Rect plateRect, PlateColor plateType) {
|
||||||
licensePlate = plateData;
|
licensePlate = plateData;
|
||||||
name = plateName;
|
name = plateName;
|
||||||
@@ -93,17 +90,21 @@ namespace pr {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(plate.first == LETTER) {
|
else if(plate.first == LETTER) {
|
||||||
decode += mappingTable[std::max_element(prob+41,prob+65)- prob];
|
decode += mappingTable[std::max_element(prob+41,prob+65)- prob];
|
||||||
confidence+=*std::max_element(prob+41,prob+65);
|
confidence+=*std::max_element(prob+41,prob+65);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(plate.first == LETTER_NUMS) {
|
else if(plate.first == LETTER_NUMS) {
|
||||||
decode += mappingTable[std::max_element(prob+31,prob+65)- prob];
|
decode += mappingTable[std::max_element(prob+31,prob+65)- prob];
|
||||||
confidence+=*std::max_element(prob+31,prob+65);
|
confidence+=*std::max_element(prob+31,prob+65);
|
||||||
// std::cout<<*std::max_element(prob+31,prob+65)<<std::endl;
|
// std::cout<<*std::max_element(prob+31,prob+65)<<std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if(plate.first == INVALID)
|
||||||
|
{
|
||||||
|
decode+='*';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
name = decode;
|
name = decode;
|
||||||
@@ -113,12 +114,10 @@ namespace pr {
|
|||||||
return decode;
|
return decode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cv::Mat licensePlate;
|
cv::Mat licensePlate;
|
||||||
cv::Rect ROI;
|
cv::Rect ROI;
|
||||||
std::string name;
|
std::string name ;
|
||||||
PlateColor Type;
|
PlateColor Type;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
//
|
|
||||||
// Created by 庾金科 on 16/10/2017.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef SWIFTPR_PLATESEGMENTATION_H
|
#ifndef SWIFTPR_PLATESEGMENTATION_H
|
||||||
#define SWIFTPR_PLATESEGMENTATION_H
|
#define SWIFTPR_PLATESEGMENTATION_H
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ namespace pr{
|
|||||||
class GeneralRecognizer{
|
class GeneralRecognizer{
|
||||||
public:
|
public:
|
||||||
virtual label recognizeCharacter(cv::Mat character) = 0;
|
virtual label recognizeCharacter(cv::Mat character) = 0;
|
||||||
|
// virtual cv::Mat SegmentationFreeForSinglePlate(cv::Mat plate) = 0;
|
||||||
void SegmentBasedSequenceRecognition(PlateInfo &plateinfo);
|
void SegmentBasedSequenceRecognition(PlateInfo &plateinfo);
|
||||||
|
void SegmentationFreeSequenceRecognition(PlateInfo &plateInfo);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by 庾金科 on 28/11/2017.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SWIFTPR_SEGMENTATIONFREERECOGNIZER_H
|
||||||
|
#define SWIFTPR_SEGMENTATIONFREERECOGNIZER_H
|
||||||
|
|
||||||
|
#include "Recognizer.h"
|
||||||
|
namespace pr{
|
||||||
|
|
||||||
|
|
||||||
|
class SegmentationFreeRecognizer{
|
||||||
|
public:
|
||||||
|
const int CHAR_INPUT_W = 14;
|
||||||
|
const int CHAR_INPUT_H = 30;
|
||||||
|
const int CHAR_LEN = 84;
|
||||||
|
|
||||||
|
SegmentationFreeRecognizer(std::string prototxt,std::string caffemodel);
|
||||||
|
std::pair<std::string,float> SegmentationFreeForSinglePlate(cv::Mat plate,std::vector<std::string> mapping_table);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::dnn::Net net;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //SWIFTPR_SEGMENTATIONFREERECOGNIZER_H
|
||||||
@@ -62,8 +62,9 @@ void niBlackThreshold( InputArray _src, OutputArray _dst, double maxValue,
|
|||||||
thresh = mean + static_cast<float>(k) * sqrtVarianceMeanSum;
|
thresh = mean + static_cast<float>(k) * sqrtVarianceMeanSum;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CV_Error( CV_StsBadArg, "Unknown binarization method" );
|
// CV_Error( CV_StsBadArg, "Unknown binarization method" );
|
||||||
break;
|
CV_Error(-5, "Unknown binarization method");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
thresh.convertTo(thresh, src.depth());
|
thresh.convertTo(thresh, src.depth());
|
||||||
|
|
||||||
@@ -99,7 +100,8 @@ void niBlackThreshold( InputArray _src, OutputArray _dst, double maxValue,
|
|||||||
src.copyTo(dst, mask);
|
src.copyTo(dst, mask);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CV_Error( CV_StsBadArg, "Unknown threshold type" );
|
// CV_Error( CV_StsBadArg, "Unknown threshold type" );
|
||||||
|
CV_Error(-5, "Unknown threshold type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ HorizonalFinemapping.caffemodel
|
|||||||
|
|
||||||
HorizonalFinemapping.prototxt
|
HorizonalFinemapping.prototxt
|
||||||
|
|
||||||
Segmentation.caffemodel
|
SegmentationFree.caffemodel
|
||||||
|
|
||||||
Segmentation.prototxt
|
SegmentationFree.prototxt
|
||||||
|
|
||||||
放置在该目录
|
放置在该目录
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 21/10/2017.
|
// Created by Jack Yu on 21/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../include/CNNRecognizer.h"
|
#include "../include/CNNRecognizer.h"
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 02/10/2017.
|
// Created by Jack Yu on 02/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "FastDeskew.h"
|
#include <../include/FastDeskew.h>
|
||||||
|
|
||||||
namespace pr{
|
namespace pr{
|
||||||
|
const int ANGLE_MIN = 30 ;
|
||||||
|
|
||||||
const int ANGLE_MIN = 30 ;
|
|
||||||
const int ANGLE_MAX = 150 ;
|
const int ANGLE_MAX = 150 ;
|
||||||
const int PLATE_H = 36;
|
const int PLATE_H = 36;
|
||||||
const int PLATE_W = 136;
|
const int PLATE_W = 136;
|
||||||
@@ -51,59 +49,38 @@ namespace pr{
|
|||||||
|
|
||||||
cv::Mat correctPlateImage(cv::Mat skewPlate,float angle,float maxAngle)
|
cv::Mat correctPlateImage(cv::Mat skewPlate,float angle,float maxAngle)
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Mat dst;
|
cv::Mat dst;
|
||||||
|
|
||||||
cv::Size size_o(skewPlate.cols,skewPlate.rows);
|
cv::Size size_o(skewPlate.cols,skewPlate.rows);
|
||||||
|
|
||||||
|
|
||||||
int extend_padding = 0;
|
int extend_padding = 0;
|
||||||
// if(angle<0)
|
extend_padding = static_cast<int>(skewPlate.rows*tan(cv::abs(angle)/180* 3.14) );
|
||||||
extend_padding = static_cast<int>(skewPlate.rows*tan(cv::abs(angle)/180* 3.14) );
|
|
||||||
// else
|
|
||||||
// extend_padding = static_cast<int>(skewPlate.rows/tan(cv::abs(angle)/180* 3.14) );
|
|
||||||
|
|
||||||
// std::cout<<"extend:"<<extend_padding<<std::endl;
|
|
||||||
|
|
||||||
cv::Size size(skewPlate.cols + extend_padding ,skewPlate.rows);
|
cv::Size size(skewPlate.cols + extend_padding ,skewPlate.rows);
|
||||||
|
|
||||||
float interval = abs(sin((angle /180) * 3.14)* skewPlate.rows);
|
float interval = abs(sin((angle /180) * 3.14)* skewPlate.rows);
|
||||||
// std::cout<<interval<<std::endl;
|
|
||||||
|
|
||||||
cv::Point2f pts1[4] = {cv::Point2f(0,0),cv::Point2f(0,size_o.height),cv::Point2f(size_o.width,0),cv::Point2f(size_o.width,size_o.height)};
|
cv::Point2f pts1[4] = {cv::Point2f(0,0),cv::Point2f(0,size_o.height),cv::Point2f(size_o.width,0),cv::Point2f(size_o.width,size_o.height)};
|
||||||
if(angle>0) {
|
if(angle>0) {
|
||||||
cv::Point2f pts2[4] = {cv::Point2f(interval, 0), cv::Point2f(0, size_o.height),
|
cv::Point2f pts2[4] = {cv::Point2f(interval, 0), cv::Point2f(0, size_o.height),
|
||||||
cv::Point2f(size_o.width, 0), cv::Point2f(size_o.width - interval, size_o.height)};
|
cv::Point2f(size_o.width, 0), cv::Point2f(size_o.width - interval, size_o.height)};
|
||||||
cv::Mat M = cv::getPerspectiveTransform(pts1,pts2);
|
cv::Mat M = cv::getPerspectiveTransform(pts1,pts2);
|
||||||
cv::warpPerspective(skewPlate,dst,M,size);
|
cv::warpPerspective(skewPlate,dst,M,size);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cv::Point2f pts2[4] = {cv::Point2f(0, 0), cv::Point2f(interval, size_o.height), cv::Point2f(size_o.width-interval, 0),
|
cv::Point2f pts2[4] = {cv::Point2f(0, 0), cv::Point2f(interval, size_o.height), cv::Point2f(size_o.width-interval, 0),
|
||||||
cv::Point2f(size_o.width, size_o.height)};
|
cv::Point2f(size_o.width, size_o.height)};
|
||||||
cv::Mat M = cv::getPerspectiveTransform(pts1,pts2);
|
cv::Mat M = cv::getPerspectiveTransform(pts1,pts2);
|
||||||
cv::warpPerspective(skewPlate,dst,M,size,cv::INTER_CUBIC);
|
cv::warpPerspective(skewPlate,dst,M,size,cv::INTER_CUBIC);
|
||||||
|
|
||||||
}
|
}
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
cv::Mat fastdeskew(cv::Mat skewImage,int blockSize){
|
cv::Mat fastdeskew(cv::Mat skewImage,int blockSize){
|
||||||
|
|
||||||
|
|
||||||
const int FILTER_WINDOWS_SIZE = 5;
|
const int FILTER_WINDOWS_SIZE = 5;
|
||||||
std::vector<float> angle_list(180);
|
std::vector<float> angle_list(180);
|
||||||
memset(angle_list.data(),0,angle_list.size()*sizeof(int));
|
memset(angle_list.data(),0,angle_list.size()*sizeof(int));
|
||||||
|
|
||||||
cv::Mat bak;
|
cv::Mat bak;
|
||||||
skewImage.copyTo(bak);
|
skewImage.copyTo(bak);
|
||||||
if(skewImage.channels() == 3)
|
if(skewImage.channels() == 3)
|
||||||
cv::cvtColor(skewImage,skewImage,cv::COLOR_RGB2GRAY);
|
cv::cvtColor(skewImage,skewImage,cv::COLOR_RGB2GRAY);
|
||||||
|
|
||||||
if(skewImage.channels() == 1)
|
if(skewImage.channels() == 1)
|
||||||
{
|
{
|
||||||
cv::Mat eigen;
|
cv::Mat eigen;
|
||||||
|
|
||||||
cv::cornerEigenValsAndVecs(skewImage,eigen,blockSize,5);
|
cv::cornerEigenValsAndVecs(skewImage,eigen,blockSize,5);
|
||||||
for( int j = 0; j < skewImage.rows; j+=blockSize )
|
for( int j = 0; j < skewImage.rows; j+=blockSize )
|
||||||
{ for( int i = 0; i < skewImage.cols; i+=blockSize )
|
{ for( int i = 0; i < skewImage.cols; i+=blockSize )
|
||||||
@@ -112,12 +89,10 @@ namespace pr{
|
|||||||
float y2 = eigen.at<cv::Vec6f>(j, i)[5];
|
float y2 = eigen.at<cv::Vec6f>(j, i)[5];
|
||||||
int angle_cell = angle(x2,y2);
|
int angle_cell = angle(x2,y2);
|
||||||
angle_list[(angle_cell + 180)%180]+=1.0;
|
angle_list[(angle_cell + 180)%180]+=1.0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<float> filtered = avgfilter(angle_list,5);
|
std::vector<float> filtered = avgfilter(angle_list,5);
|
||||||
|
|
||||||
int maxPos = std::max_element(filtered.begin(),filtered.end()) - filtered.begin() + FILTER_WINDOWS_SIZE/2;
|
int maxPos = std::max_element(filtered.begin(),filtered.end()) - filtered.begin() + FILTER_WINDOWS_SIZE/2;
|
||||||
if(maxPos>ANGLE_MAX)
|
if(maxPos>ANGLE_MAX)
|
||||||
maxPos = (-maxPos+90+180)%180;
|
maxPos = (-maxPos+90+180)%180;
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
//
|
|
||||||
// Created by 庾金科 on 22/09/2017.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "FineMapping.h"
|
#include "FineMapping.h"
|
||||||
namespace pr{
|
namespace pr{
|
||||||
|
|
||||||
const int FINEMAPPING_H = 50;
|
const int FINEMAPPING_H = 60 ;
|
||||||
const int FINEMAPPING_W = 120;
|
const int FINEMAPPING_W = 140;
|
||||||
const int PADDING_UP_DOWN = 30;
|
const int PADDING_UP_DOWN = 30;
|
||||||
void drawRect(cv::Mat image,cv::Rect rect)
|
void drawRect(cv::Mat image,cv::Rect rect)
|
||||||
{
|
{
|
||||||
@@ -65,31 +61,21 @@ namespace pr{
|
|||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat FineMapping::FineMappingVertical(cv::Mat InputProposal,int sliceNum,int upper,int lower,int windows_size){
|
cv::Mat FineMapping::FineMappingVertical(cv::Mat InputProposal,int sliceNum,int upper,int lower,int windows_size){
|
||||||
|
|
||||||
|
|
||||||
cv::Mat PreInputProposal;
|
cv::Mat PreInputProposal;
|
||||||
cv::Mat proposal;
|
cv::Mat proposal;
|
||||||
|
|
||||||
cv::resize(InputProposal,PreInputProposal,cv::Size(FINEMAPPING_W,FINEMAPPING_H));
|
cv::resize(InputProposal,PreInputProposal,cv::Size(FINEMAPPING_W,FINEMAPPING_H));
|
||||||
if(InputProposal.channels() == 3)
|
if(InputProposal.channels() == 3)
|
||||||
cv::cvtColor(PreInputProposal,proposal,cv::COLOR_BGR2GRAY);
|
cv::cvtColor(PreInputProposal,proposal,cv::COLOR_BGR2GRAY);
|
||||||
else
|
else
|
||||||
PreInputProposal.copyTo(proposal);
|
PreInputProposal.copyTo(proposal);
|
||||||
|
|
||||||
// proposal = PreInputProposal;
|
|
||||||
|
|
||||||
// this will improve some sen
|
// this will improve some sen
|
||||||
cv::Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(1,3));
|
cv::Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(1,3));
|
||||||
// cv::erode(proposal,proposal,kernal);
|
|
||||||
|
|
||||||
|
|
||||||
float diff = static_cast<float>(upper-lower);
|
float diff = static_cast<float>(upper-lower);
|
||||||
diff/=static_cast<float>(sliceNum-1);
|
diff/=static_cast<float>(sliceNum-1);
|
||||||
cv::Mat binary_adaptive;
|
cv::Mat binary_adaptive;
|
||||||
std::vector<cv::Point> line_upper;
|
std::vector<cv::Point> line_upper;
|
||||||
std::vector<cv::Point> line_lower;
|
std::vector<cv::Point> line_lower;
|
||||||
int contours_nums=0;
|
int contours_nums=0;
|
||||||
|
|
||||||
for(int i = 0 ; i < sliceNum ; i++)
|
for(int i = 0 ; i < sliceNum ; i++)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<cv::Point> > contours;
|
std::vector<std::vector<cv::Point> > contours;
|
||||||
@@ -106,7 +92,6 @@ namespace pr{
|
|||||||
if (( lwRatio>0.7&&bdbox.width*bdbox.height>100 && bdboxAera<300)
|
if (( lwRatio>0.7&&bdbox.width*bdbox.height>100 && bdboxAera<300)
|
||||||
|| (lwRatio>3.0 && bdboxAera<100 && bdboxAera>10))
|
|| (lwRatio>3.0 && bdboxAera<100 && bdboxAera>10))
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Point p1(bdbox.x, bdbox.y);
|
cv::Point p1(bdbox.x, bdbox.y);
|
||||||
cv::Point p2(bdbox.x + bdbox.width, bdbox.y + bdbox.height);
|
cv::Point p2(bdbox.x + bdbox.width, bdbox.y + bdbox.height);
|
||||||
line_upper.push_back(p1);
|
line_upper.push_back(p1);
|
||||||
@@ -115,9 +100,6 @@ namespace pr{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std:: cout<<"contours_nums "<<contours_nums<<std::endl;
|
|
||||||
|
|
||||||
if(contours_nums<41)
|
if(contours_nums<41)
|
||||||
{
|
{
|
||||||
cv::bitwise_not(InputProposal,InputProposal);
|
cv::bitwise_not(InputProposal,InputProposal);
|
||||||
@@ -130,14 +112,11 @@ namespace pr{
|
|||||||
else
|
else
|
||||||
proposal = bak;
|
proposal = bak;
|
||||||
int contours_nums=0;
|
int contours_nums=0;
|
||||||
|
|
||||||
for(int i = 0 ; i < sliceNum ; i++)
|
for(int i = 0 ; i < sliceNum ; i++)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<cv::Point> > contours;
|
std::vector<std::vector<cv::Point> > contours;
|
||||||
float k =lower + i*diff;
|
float k =lower + i*diff;
|
||||||
cv::adaptiveThreshold(proposal,binary_adaptive,255,cv::ADAPTIVE_THRESH_MEAN_C,cv::THRESH_BINARY,windows_size,k);
|
cv::adaptiveThreshold(proposal,binary_adaptive,255,cv::ADAPTIVE_THRESH_MEAN_C,cv::THRESH_BINARY,windows_size,k);
|
||||||
// cv::imshow("image",binary_adaptive);
|
|
||||||
// cv::waitKey(0);
|
|
||||||
cv::Mat draw;
|
cv::Mat draw;
|
||||||
binary_adaptive.copyTo(draw);
|
binary_adaptive.copyTo(draw);
|
||||||
cv::findContours(binary_adaptive,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
|
cv::findContours(binary_adaptive,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
|
||||||
@@ -158,30 +137,19 @@ namespace pr{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// std:: cout<<"contours_nums "<<contours_nums<<std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat rgb;
|
cv::Mat rgb;
|
||||||
cv::copyMakeBorder(PreInputProposal, rgb, 30, 30, 0, 0, cv::BORDER_REPLICATE);
|
cv::copyMakeBorder(PreInputProposal, rgb, PADDING_UP_DOWN, PADDING_UP_DOWN, 0, 0, cv::BORDER_REPLICATE);
|
||||||
// cv::imshow("rgb",rgb);
|
|
||||||
// cv::waitKey(0);
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
std::pair<int, int> A;
|
std::pair<int, int> A;
|
||||||
std::pair<int, int> B;
|
std::pair<int, int> B;
|
||||||
A = FitLineRansac(line_upper, -2);
|
A = FitLineRansac(line_upper, -1);
|
||||||
B = FitLineRansac(line_lower, 2);
|
B = FitLineRansac(line_lower, 1);
|
||||||
int leftyB = A.first;
|
int leftyB = A.first;
|
||||||
int rightyB = A.second;
|
int rightyB = A.second;
|
||||||
int leftyA = B.first;
|
int leftyA = B.first;
|
||||||
int rightyA = B.second;
|
int rightyA = B.second;
|
||||||
int cols = rgb.cols;
|
int cols = rgb.cols;
|
||||||
int rows = rgb.rows;
|
int rows = rgb.rows;
|
||||||
// pts_map1 = np.float32([[cols - 1, rightyA], [0, leftyA],[cols - 1, rightyB], [0, leftyB]])
|
|
||||||
// pts_map2 = np.float32([[136,36],[0,36],[136,0],[0,0]])
|
|
||||||
// mat = cv2.getPerspectiveTransform(pts_map1,pts_map2)
|
|
||||||
// image = cv2.warpPerspective(rgb,mat,(136,36),flags=cv2.INTER_CUBIC)
|
|
||||||
std::vector<cv::Point2f> corners(4);
|
std::vector<cv::Point2f> corners(4);
|
||||||
corners[0] = cv::Point2f(cols - 1, rightyA);
|
corners[0] = cv::Point2f(cols - 1, rightyA);
|
||||||
corners[1] = cv::Point2f(0, leftyA);
|
corners[1] = cv::Point2f(0, leftyA);
|
||||||
@@ -196,10 +164,7 @@ namespace pr{
|
|||||||
cv::Mat quad = cv::Mat::zeros(36, 136, CV_8UC3);
|
cv::Mat quad = cv::Mat::zeros(36, 136, CV_8UC3);
|
||||||
cv::warpPerspective(rgb, quad, transform, quad.size());
|
cv::warpPerspective(rgb, quad, transform, quad.size());
|
||||||
return quad;
|
return quad;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,85 @@
|
|||||||
////
|
//
|
||||||
|
// Created by Jack Yu on 23/10/2017.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../include/Pipeline.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace pr {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int HorizontalPadding = 4;
|
||||||
|
PipelinePR::PipelinePR(std::string detector_filename,
|
||||||
|
std::string finemapping_prototxt, std::string finemapping_caffemodel,
|
||||||
|
std::string segmentation_prototxt, std::string segmentation_caffemodel,
|
||||||
|
std::string charRecognization_proto, std::string charRecognization_caffemodel,
|
||||||
|
std::string segmentationfree_proto,std::string segmentationfree_caffemodel) {
|
||||||
|
plateDetection = new PlateDetection(detector_filename);
|
||||||
|
fineMapping = new FineMapping(finemapping_prototxt, finemapping_caffemodel);
|
||||||
|
plateSegmentation = new PlateSegmentation(segmentation_prototxt, segmentation_caffemodel);
|
||||||
|
generalRecognizer = new CNNRecognizer(charRecognization_proto, charRecognization_caffemodel);
|
||||||
|
segmentationFreeRecognizer = new SegmentationFreeRecognizer(segmentationfree_proto,segmentationfree_caffemodel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelinePR::~PipelinePR() {
|
||||||
|
|
||||||
|
delete plateDetection;
|
||||||
|
delete fineMapping;
|
||||||
|
delete plateSegmentation;
|
||||||
|
delete generalRecognizer;
|
||||||
|
delete segmentationFreeRecognizer;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PlateInfo> PipelinePR:: RunPiplineAsImage(cv::Mat plateImage,int method) {
|
||||||
|
std::vector<PlateInfo> results;
|
||||||
|
std::vector<pr::PlateInfo> plates;
|
||||||
|
plateDetection->plateDetectionRough(plateImage,plates,36,700);
|
||||||
|
|
||||||
|
for (pr::PlateInfo plateinfo:plates) {
|
||||||
|
|
||||||
|
cv::Mat image_finemapping = plateinfo.getPlateImage();
|
||||||
|
image_finemapping = fineMapping->FineMappingVertical(image_finemapping);
|
||||||
|
image_finemapping = pr::fastdeskew(image_finemapping, 5);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Segmentation-based
|
||||||
|
|
||||||
|
if(method==SEGMENTATION_BASED_METHOD)
|
||||||
|
{
|
||||||
|
image_finemapping = fineMapping->FineMappingHorizon(image_finemapping, 2, HorizontalPadding);
|
||||||
|
cv::resize(image_finemapping, image_finemapping, cv::Size(136+HorizontalPadding, 36));
|
||||||
|
plateinfo.setPlateImage(image_finemapping);
|
||||||
|
std::vector<cv::Rect> rects;
|
||||||
|
plateSegmentation->segmentPlatePipline(plateinfo, 1, rects);
|
||||||
|
plateSegmentation->ExtractRegions(plateinfo, rects);
|
||||||
|
cv::copyMakeBorder(image_finemapping, image_finemapping, 0, 0, 0, 20, cv::BORDER_REPLICATE);
|
||||||
|
plateinfo.setPlateImage(image_finemapping);
|
||||||
|
generalRecognizer->SegmentBasedSequenceRecognition(plateinfo);
|
||||||
|
plateinfo.decodePlateNormal(pr::CH_PLATE_CODE);
|
||||||
|
|
||||||
|
}
|
||||||
|
//Segmentation-free
|
||||||
|
else if(method==SEGMENTATION_FREE_METHOD)
|
||||||
|
{
|
||||||
|
image_finemapping = fineMapping->FineMappingHorizon(image_finemapping, 4, HorizontalPadding+3);
|
||||||
|
cv::resize(image_finemapping, image_finemapping, cv::Size(136+HorizontalPadding, 36));
|
||||||
|
plateinfo.setPlateImage(image_finemapping);
|
||||||
|
std::pair<std::string,float> res = segmentationFreeRecognizer->SegmentationFreeForSinglePlate(plateinfo.getPlateImage(),pr::CH_PLATE_CODE);
|
||||||
|
plateinfo.confidence = res.second;
|
||||||
|
plateinfo.setPlateName(res.first);
|
||||||
|
}
|
||||||
|
results.push_back(plateinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
|
||||||
|
}//namespace pr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,45 +1,24 @@
|
|||||||
//
|
|
||||||
// Created by 庾金科 on 20/09/2017.
|
|
||||||
//
|
|
||||||
#include "../include/PlateDetection.h"
|
#include "../include/PlateDetection.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
namespace pr{
|
namespace pr{
|
||||||
|
|
||||||
|
|
||||||
PlateDetection::PlateDetection(std::string filename_cascade){
|
PlateDetection::PlateDetection(std::string filename_cascade){
|
||||||
cascade.load(filename_cascade);
|
cascade.load(filename_cascade);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void PlateDetection::plateDetectionRough(cv::Mat InputImage,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w){
|
void PlateDetection::plateDetectionRough(cv::Mat InputImage,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w){
|
||||||
|
|
||||||
cv::Mat processImage;
|
cv::Mat processImage;
|
||||||
|
cv::cvtColor(InputImage,processImage,cv::COLOR_BGR2GRAY);
|
||||||
cv::cvtColor(InputImage,processImage,cv::COLOR_BGR2GRAY);
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<cv::Rect> platesRegions;
|
std::vector<cv::Rect> platesRegions;
|
||||||
// std::vector<PlateInfo> plates;
|
|
||||||
cv::Size minSize(min_w,min_w/4);
|
cv::Size minSize(min_w,min_w/4);
|
||||||
cv::Size maxSize(max_w,max_w/4);
|
cv::Size maxSize(max_w,max_w/4);
|
||||||
// cv::imshow("input",InputImage);
|
|
||||||
// cv::waitKey(0);
|
|
||||||
cascade.detectMultiScale( processImage, platesRegions,
|
cascade.detectMultiScale( processImage, platesRegions,
|
||||||
1.1, 3, cv::CASCADE_SCALE_IMAGE,minSize,maxSize);
|
1.1, 3, cv::CASCADE_SCALE_IMAGE,minSize,maxSize);
|
||||||
for(auto plate:platesRegions)
|
for(auto plate:platesRegions)
|
||||||
{
|
{
|
||||||
// extend rects
|
int zeroadd_w = static_cast<int>(plate.width*0.30);
|
||||||
// x -= w * 0.14
|
int zeroadd_h = static_cast<int>(plate.height*2);
|
||||||
// w += w * 0.28
|
int zeroadd_x = static_cast<int>(plate.width*0.15);
|
||||||
// y -= h * 0.6
|
int zeroadd_y = static_cast<int>(plate.height*1);
|
||||||
// h += h * 1.1;
|
|
||||||
int zeroadd_w = static_cast<int>(plate.width*0.28);
|
|
||||||
int zeroadd_h = static_cast<int>(plate.height*1.2);
|
|
||||||
int zeroadd_x = static_cast<int>(plate.width*0.14);
|
|
||||||
int zeroadd_y = static_cast<int>(plate.height*0.6);
|
|
||||||
plate.x-=zeroadd_x;
|
plate.x-=zeroadd_x;
|
||||||
plate.y-=zeroadd_y;
|
plate.y-=zeroadd_y;
|
||||||
plate.height += zeroadd_h;
|
plate.height += zeroadd_h;
|
||||||
@@ -50,12 +29,4 @@ namespace pr{
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// std::vector<pr::PlateInfo> PlateDetection::plateDetectionRough(cv::Mat InputImage,cv::Rect roi,int min_w,int max_w){
|
|
||||||
// cv::Mat roi_region = util::cropFromImage(InputImage,roi);
|
|
||||||
// return plateDetectionRough(roi_region,min_w,max_w);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace pr
|
}//namespace pr
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 16/10/2017.
|
// Created by Jack Yu on 16/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../include/PlateSegmentation.h"
|
#include "../include/PlateSegmentation.h"
|
||||||
@@ -94,7 +94,7 @@ namespace pr{
|
|||||||
cv::Mat roi_thres;
|
cv::Mat roi_thres;
|
||||||
// cv::threshold(roiImage,roi_thres,0,255,cv::THRESH_OTSU|cv::THRESH_BINARY);
|
// cv::threshold(roiImage,roi_thres,0,255,cv::THRESH_OTSU|cv::THRESH_BINARY);
|
||||||
|
|
||||||
niBlackThreshold(roiImage,roi_thres,255,cv::THRESH_BINARY,15,0.3,BINARIZATION_NIBLACK);
|
niBlackThreshold(roiImage,roi_thres,255,cv::THRESH_BINARY,15,0.27,BINARIZATION_NIBLACK);
|
||||||
|
|
||||||
std::vector<std::vector<cv::Point>> contours;
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
cv::findContours(roi_thres,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);
|
cv::findContours(roi_thres,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);
|
||||||
@@ -110,7 +110,7 @@ namespace pr{
|
|||||||
cv::Rect bdbox = cv::boundingRect(contour);
|
cv::Rect bdbox = cv::boundingRect(contour);
|
||||||
cv::Point center(bdbox.x+(bdbox.width>>1),bdbox.y + (bdbox.height>>1));
|
cv::Point center(bdbox.x+(bdbox.width>>1),bdbox.y + (bdbox.height>>1));
|
||||||
int dist = (center.x - boxCenter.x)*(center.x - boxCenter.x);
|
int dist = (center.x - boxCenter.x)*(center.x - boxCenter.x);
|
||||||
if(dist<final_dist && bdbox.height > rows>>1)
|
if(dist<final_dist && bdbox.height > rows>>1)
|
||||||
{ final_dist =dist;
|
{ final_dist =dist;
|
||||||
final_center = center;
|
final_center = center;
|
||||||
final_bdbox = bdbox;
|
final_bdbox = bdbox;
|
||||||
@@ -220,7 +220,7 @@ namespace pr{
|
|||||||
|
|
||||||
|
|
||||||
int cp_list[7];
|
int cp_list[7];
|
||||||
float loss_selected = -1;
|
float loss_selected = -10;
|
||||||
|
|
||||||
for(int start = 0 ; start < 20 ; start+=2)
|
for(int start = 0 ; start < 20 ; start+=2)
|
||||||
for(int width = windowsWidth-5; width < windowsWidth+5 ; width++ ){
|
for(int width = windowsWidth-5; width < windowsWidth+5 ; width++ ){
|
||||||
@@ -246,13 +246,10 @@ namespace pr{
|
|||||||
|
|
||||||
if(cp7_p5>=cols)
|
if(cp7_p5>=cols)
|
||||||
continue;
|
continue;
|
||||||
float loss = ch_prob[cp1_ch]+
|
// float loss = ch_prob[cp1_ch]+
|
||||||
engNum_prob[cp2_p0] +engNum_prob[cp3_p1]+engNum_prob[cp4_p2]+engNum_prob[cp5_p3]+engNum_prob[cp6_p4] +engNum_prob[cp7_p5]
|
// engNum_prob[cp2_p0] +engNum_prob[cp3_p1]+engNum_prob[cp4_p2]+engNum_prob[cp5_p3]+engNum_prob[cp6_p4] +engNum_prob[cp7_p5]
|
||||||
+ (false_prob[md2]+false_prob[md3]+false_prob[md4]+false_prob[md5]+false_prob[md5] + false_prob[md6]);
|
// + (false_prob[md2]+false_prob[md3]+false_prob[md4]+false_prob[md5]+false_prob[md5] + false_prob[md6]);
|
||||||
// float loss = ch_prob[cp1_ch]*3 -(false_prob[cp3_p1]+false_prob[cp4_p2]+false_prob[cp5_p3]+false_prob[cp6_p4]+false_prob[cp7_p5]);
|
float loss = ch_prob[cp1_ch]*3 -(false_prob[cp3_p1]+false_prob[cp4_p2]+false_prob[cp5_p3]+false_prob[cp6_p4]+false_prob[cp7_p5]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(loss>loss_selected)
|
if(loss>loss_selected)
|
||||||
{
|
{
|
||||||
@@ -284,15 +281,15 @@ namespace pr{
|
|||||||
void PlateSegmentation::segmentPlateBySlidingWindows(cv::Mat &plateImage,int windowsWidth,int stride,cv::Mat &respones){
|
void PlateSegmentation::segmentPlateBySlidingWindows(cv::Mat &plateImage,int windowsWidth,int stride,cv::Mat &respones){
|
||||||
|
|
||||||
|
|
||||||
cv::resize(plateImage,plateImage,cv::Size(136,36));
|
// cv::resize(plateImage,plateImage,cv::Size(136,36));
|
||||||
|
|
||||||
cv::Mat plateImageGray;
|
cv::Mat plateImageGray;
|
||||||
cv::cvtColor(plateImage,plateImageGray,cv::COLOR_BGR2GRAY);
|
cv::cvtColor(plateImage,plateImageGray,cv::COLOR_BGR2GRAY);
|
||||||
|
int padding = plateImage.cols-136 ;
|
||||||
|
// int padding = 0 ;
|
||||||
int height = plateImage.rows - 1;
|
int height = plateImage.rows - 1;
|
||||||
int width = plateImage.cols - 1;
|
int width = plateImage.cols - 1 - padding;
|
||||||
|
for(int i = 0 ; i < width - windowsWidth +1 ; i +=stride)
|
||||||
for(int i = 0 ; i < plateImage.cols - windowsWidth +1 ; i +=stride)
|
|
||||||
{
|
{
|
||||||
cv::Rect roi(i,0,windowsWidth,height);
|
cv::Rect roi(i,0,windowsWidth,height);
|
||||||
cv::Mat roiImage = plateImageGray(roi);
|
cv::Mat roiImage = plateImageGray(roi);
|
||||||
@@ -348,6 +345,11 @@ namespace pr{
|
|||||||
cv::Mat respones; //three response of every sub region from origin image .
|
cv::Mat respones; //three response of every sub region from origin image .
|
||||||
segmentPlateBySlidingWindows(plateImage,DEFAULT_WIDTH,1,respones);
|
segmentPlateBySlidingWindows(plateImage,DEFAULT_WIDTH,1,respones);
|
||||||
templateMatchFinding(respones,DEFAULT_WIDTH/stride,sections);
|
templateMatchFinding(respones,DEFAULT_WIDTH/stride,sections);
|
||||||
|
for(int i = 0; i < sections.second.size() ; i++)
|
||||||
|
{
|
||||||
|
sections.second[i]*=stride;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// std::cout<<sections<<std::endl;
|
// std::cout<<sections<<std::endl;
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,23 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 22/10/2017.
|
// Created by Jack Yu on 22/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../include/Recognizer.h"
|
#include "../include/Recognizer.h"
|
||||||
|
|
||||||
namespace pr{
|
namespace pr{
|
||||||
void GeneralRecognizer::SegmentBasedSequenceRecognition(PlateInfo &plateinfo){
|
void GeneralRecognizer::SegmentBasedSequenceRecognition(PlateInfo &plateinfo){
|
||||||
|
|
||||||
|
|
||||||
for(auto char_instance:plateinfo.plateChars)
|
for(auto char_instance:plateinfo.plateChars)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
std::pair<CharType,cv::Mat> res;
|
std::pair<CharType,cv::Mat> res;
|
||||||
cv::Mat code_table= recognizeCharacter(char_instance.second);
|
if(char_instance.second.rows*char_instance.second.cols>40) {
|
||||||
res.first = char_instance.first;
|
label code_table = recognizeCharacter(char_instance.second);
|
||||||
code_table.copyTo(res.second);
|
res.first = char_instance.first;
|
||||||
plateinfo.appendPlateCoding(res);
|
code_table.copyTo(res.second);
|
||||||
|
plateinfo.appendPlateCoding(res);
|
||||||
|
} else{
|
||||||
|
res.first = INVALID;
|
||||||
|
plateinfo.appendPlateCoding(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// Created by Jack Yu on 28/11/2017.
|
||||||
|
//
|
||||||
|
#include "../include/SegmentationFreeRecognizer.h"
|
||||||
|
|
||||||
|
namespace pr {
|
||||||
|
SegmentationFreeRecognizer::SegmentationFreeRecognizer(std::string prototxt, std::string caffemodel) {
|
||||||
|
net = cv::dnn::readNetFromCaffe(prototxt, caffemodel);
|
||||||
|
}
|
||||||
|
inline int judgeCharRange(int id)
|
||||||
|
{return id<31 || id>63;
|
||||||
|
}
|
||||||
|
std::pair<std::string,float> decodeResults(cv::Mat code_table,std::vector<std::string> mapping_table,float thres)
|
||||||
|
{
|
||||||
|
cv::MatSize mtsize = code_table.size;
|
||||||
|
int sequencelength = mtsize[2];
|
||||||
|
int labellength = mtsize[1];
|
||||||
|
cv::transpose(code_table.reshape(1,1).reshape(1,labellength),code_table);
|
||||||
|
std::string name = "";
|
||||||
|
std::vector<int> seq(sequencelength);
|
||||||
|
std::vector<std::pair<int,float>> seq_decode_res;
|
||||||
|
for(int i = 0 ; i < sequencelength; i++) {
|
||||||
|
float *fstart = ((float *) (code_table.data) + i * labellength );
|
||||||
|
int id = std::max_element(fstart,fstart+labellength) - fstart;
|
||||||
|
seq[i] =id;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sum_confidence = 0;
|
||||||
|
int plate_lenghth = 0 ;
|
||||||
|
for(int i = 0 ; i< sequencelength ; i++)
|
||||||
|
{
|
||||||
|
if(seq[i]!=labellength-1 && (i==0 || seq[i]!=seq[i-1]))
|
||||||
|
{
|
||||||
|
float *fstart = ((float *) (code_table.data) + i * labellength );
|
||||||
|
float confidence = *(fstart+seq[i]);
|
||||||
|
std::pair<int,float> pair_(seq[i],confidence);
|
||||||
|
seq_decode_res.push_back(pair_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
if (seq_decode_res.size()>1 && judgeCharRange(seq_decode_res[0].first) && judgeCharRange(seq_decode_res[1].first))
|
||||||
|
{
|
||||||
|
i=2;
|
||||||
|
int c = seq_decode_res[0].second<seq_decode_res[1].second;
|
||||||
|
name+=mapping_table[seq_decode_res[c].first];
|
||||||
|
sum_confidence+=seq_decode_res[c].second;
|
||||||
|
plate_lenghth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; i < seq_decode_res.size();i++)
|
||||||
|
{
|
||||||
|
name+=mapping_table[seq_decode_res[i].first];
|
||||||
|
sum_confidence +=seq_decode_res[i].second;
|
||||||
|
plate_lenghth++;
|
||||||
|
}
|
||||||
|
std::pair<std::string,float> res;
|
||||||
|
res.second = sum_confidence/plate_lenghth;
|
||||||
|
res.first = name;
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
std::string decodeResults(cv::Mat code_table,std::vector<std::string> mapping_table)
|
||||||
|
{
|
||||||
|
cv::MatSize mtsize = code_table.size;
|
||||||
|
int sequencelength = mtsize[2];
|
||||||
|
int labellength = mtsize[1];
|
||||||
|
cv::transpose(code_table.reshape(1,1).reshape(1,labellength),code_table);
|
||||||
|
std::string name = "";
|
||||||
|
std::vector<int> seq(sequencelength);
|
||||||
|
for(int i = 0 ; i < sequencelength; i++) {
|
||||||
|
float *fstart = ((float *) (code_table.data) + i * labellength );
|
||||||
|
int id = std::max_element(fstart,fstart+labellength) - fstart;
|
||||||
|
seq[i] =id;
|
||||||
|
}
|
||||||
|
for(int i = 0 ; i< sequencelength ; i++)
|
||||||
|
{
|
||||||
|
if(seq[i]!=labellength-1 && (i==0 || seq[i]!=seq[i-1]))
|
||||||
|
name+=mapping_table[seq[i]];
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
std::pair<std::string,float> SegmentationFreeRecognizer::SegmentationFreeForSinglePlate(cv::Mat Image,std::vector<std::string> mapping_table) {
|
||||||
|
cv::transpose(Image,Image);
|
||||||
|
cv::Mat inputBlob = cv::dnn::blobFromImage(Image, 1 / 255.0, cv::Size(40,160));
|
||||||
|
net.setInput(inputBlob, "data");
|
||||||
|
cv::Mat char_prob_mat = net.forward();
|
||||||
|
return decodeResults(char_prob_mat,mapping_table,0.00);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-15
@@ -1,20 +1,16 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 04/04/2017.
|
// Created by Jack Yu on 04/04/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
namespace util{
|
namespace util{
|
||||||
|
|
||||||
template <class T> void swap ( T& a, T& b )
|
template <class T> void swap ( T& a, T& b )
|
||||||
{
|
{
|
||||||
T c(a); a=b; b=c;
|
T c(a); a=b; b=c;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T min(T& a,T& b )
|
template <class T> T min(T& a,T& b )
|
||||||
{
|
{
|
||||||
return a>b?b:a;
|
return a>b?b:a;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat cropFromImage(const cv::Mat &image,cv::Rect rect){
|
cv::Mat cropFromImage(const cv::Mat &image,cv::Rect rect){
|
||||||
@@ -57,23 +53,16 @@ namespace util{
|
|||||||
int histSize = 256;
|
int histSize = 256;
|
||||||
float range[] = {0,255};
|
float range[] = {0,255};
|
||||||
const float* histRange = {range};
|
const float* histRange = {range};
|
||||||
|
|
||||||
cv::calcHist( &hsv_planes[0], 1, 0, cv::Mat(), hist, 1, &histSize, &histRange,true, true);
|
cv::calcHist( &hsv_planes[0], 1, 0, cv::Mat(), hist, 1, &histSize, &histRange,true, true);
|
||||||
return hist;
|
return hist;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float computeSimilir(const cv::Mat &A,const cv::Mat &B)
|
float computeSimilir(const cv::Mat &A,const cv::Mat &B)
|
||||||
{
|
{
|
||||||
|
|
||||||
cv::Mat histA,histB;
|
cv::Mat histA,histB;
|
||||||
histA = calcHist(A);
|
histA = calcHist(A);
|
||||||
histB = calcHist(B);
|
histB = calcHist(B);
|
||||||
return cv::compareHist(histA,histB,CV_COMP_CORREL);
|
// return cv::compareHist(histA,histB,CV_COMP_CORREL);
|
||||||
|
return cv::compareHist(histA, histB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}//namespace util
|
}//namespace util
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 02/10/2017.
|
// Created by Jack Yu on 02/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 24/09/2017.
|
// Created by Jack Yu on 24/09/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "FineMapping.h"
|
#include "FineMapping.h"
|
||||||
|
|||||||
@@ -1,42 +1,229 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 23/10/2017.
|
// Created by Jack Yu on 23/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../include/Pipeline.h"
|
#include "../include/Pipeline.h"
|
||||||
using namespace pr;
|
#include<fstream>
|
||||||
|
#include<vector>
|
||||||
|
|
||||||
void TEST_PIPELINE(){
|
|
||||||
|
|
||||||
pr::PipelinePR prc("../lpr/model/cascade.xml",
|
|
||||||
"../lpr/model/HorizonalFinemapping.prototxt","../lpr/model/HorizonalFinemapping.caffemodel",
|
|
||||||
"../lpr/model/Segmentation.prototxt","../lpr/model/Segmentation.caffemodel",
|
|
||||||
"../lpr/model/CharacterRecognization.prototxt","../lpr/model/CharacterRecognization.caffemodel"
|
|
||||||
);
|
|
||||||
|
|
||||||
cv::Mat image = cv::imread("../6.jpg");
|
using namespace std;
|
||||||
cv::imshow("image",image);
|
|
||||||
cv::waitKey(0);
|
|
||||||
|
|
||||||
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(image);
|
|
||||||
float conf = 0 ;
|
|
||||||
for(auto st:res) {
|
|
||||||
if(st.confidence>0.1) {
|
|
||||||
std::cout << st.getPlateName() << " " << st.confidence << std::endl;
|
|
||||||
conf += st.confidence;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout<<conf<<std::endl;
|
|
||||||
system("pause");
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static unsigned int levenshtein_distance(const T &s1, const T &s2) {
|
||||||
|
const size_t len1 = s1.size(), len2 = s2.size();
|
||||||
|
std::vector<unsigned int> col(len2 + 1), prevCol(len2 + 1);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < prevCol.size(); i++) prevCol[i] = i;
|
||||||
|
for (unsigned int i = 0; i < len1; i++) {
|
||||||
|
col[0] = i + 1;
|
||||||
|
for (unsigned int j = 0; j < len2; j++)
|
||||||
|
col[j + 1] = min(
|
||||||
|
min(prevCol[1 + j] + 1, col[j] + 1),
|
||||||
|
prevCol[j] + (s1[i] == s2[j] ? 0 : 1));
|
||||||
|
col.swap(prevCol);
|
||||||
|
}
|
||||||
|
return prevCol[len2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TEST_CAM()
|
||||||
|
{
|
||||||
|
cv::VideoCapture capture("test1.mp4");
|
||||||
|
cv::Mat frame;
|
||||||
|
pr::PipelinePR prc("../lpr/model/cascade.xml",
|
||||||
|
"../lpr/model/HorizonalFinemapping.prototxt", "../lpr/model/HorizonalFinemapping.caffemodel",
|
||||||
|
"../lpr/model/Segmentation.prototxt", "../lpr/model/Segmentation.caffemodel",
|
||||||
|
"../lpr/model/CharacterRecognization.prototxt", "../lpr/model/CharacterRecognization.caffemodel",
|
||||||
|
"../lpr/model/SegmentationFree.prototxt", "../lpr/model/SegmentationFree.caffemodel"
|
||||||
|
);
|
||||||
|
while (1) {
|
||||||
|
//读取下一帧
|
||||||
|
if (!capture.read(frame)) {
|
||||||
|
std::cout << "读取视频失败" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// cv::transpose(frame,frame);
|
||||||
|
// cv::flip(frame,frame,2);
|
||||||
|
|
||||||
|
// cv::resize(frame,frame,cv::Size(frame.cols/2,frame.rows/2));
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(frame, pr::SEGMENTATION_FREE_METHOD);
|
||||||
|
|
||||||
|
for (auto st : res) {
|
||||||
|
if (st.confidence > 0.75) {
|
||||||
|
std::cout << st.getPlateName() << " " << st.confidence << std::endl;
|
||||||
|
cv::Rect region = st.getPlateRect();
|
||||||
|
|
||||||
|
cv::rectangle(frame, cv::Point(region.x, region.y), cv::Point(region.x + region.width, region.y + region.height), cv::Scalar(255, 255, 0), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::imshow("image", frame);
|
||||||
|
cv::waitKey(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TEST_ACC() {
|
||||||
|
|
||||||
|
pr::PipelinePR prc("../lpr/model/cascade.xml",
|
||||||
|
"../lpr/model/HorizonalFinemapping.prototxt", "../lpr/model/HorizonalFinemapping.caffemodel",
|
||||||
|
"../lpr/model/Segmentation.prototxt", "../lpr/model/Segmentation.caffemodel",
|
||||||
|
"../lpr/model/CharacterRecognization.prototxt", "../lpr/model/CharacterRecognization.caffemodel",
|
||||||
|
"../lpr/model/SegmentationFree.prototxt", "../lpr/model/SegmentationFree.caffemodel"
|
||||||
|
);
|
||||||
|
|
||||||
|
ifstream file;
|
||||||
|
string imagename;
|
||||||
|
int n = 0, correct = 0, j = 0, sum = 0;
|
||||||
|
char filename[] = "/Users/yujinke/Downloads/general_test/1.txt";
|
||||||
|
string pathh = "/Users/yujinke/Downloads/general_test/";
|
||||||
|
file.open(filename, ios::in);
|
||||||
|
while (!file.eof())
|
||||||
|
{
|
||||||
|
file >> imagename;
|
||||||
|
string imgpath = pathh + imagename;
|
||||||
|
std::cout << "------------------------------------------------" << endl;
|
||||||
|
cout << "图片名:" << imagename << endl;
|
||||||
|
cv::Mat image = cv::imread(imgpath);
|
||||||
|
// cv::imshow("image", image);
|
||||||
|
// cv::waitKey(0);
|
||||||
|
|
||||||
|
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(image, pr::SEGMENTATION_FREE_METHOD);
|
||||||
|
|
||||||
|
float conf = 0;
|
||||||
|
vector<float> con;
|
||||||
|
vector<string> name;
|
||||||
|
for (auto st : res) {
|
||||||
|
if (st.confidence > 0.1) {
|
||||||
|
//std::cout << st.getPlateName() << " " << st.confidence << std::endl;
|
||||||
|
con.push_back(st.confidence);
|
||||||
|
name.push_back(st.getPlateName());
|
||||||
|
//conf += st.confidence;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cout << "no string" << endl;
|
||||||
|
}
|
||||||
|
// std::cout << conf << std::endl;
|
||||||
|
int num = con.size();
|
||||||
|
float max = 0;
|
||||||
|
string platestr, chpr, ch;
|
||||||
|
int diff = 0, dif = 0;
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
|
||||||
|
if (con.at(i) > max)
|
||||||
|
{
|
||||||
|
max = con.at(i);
|
||||||
|
platestr = name.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// cout << "max:"<<max << endl;
|
||||||
|
cout << "string:" << platestr << endl;
|
||||||
|
chpr = platestr.substr(0, 2);
|
||||||
|
ch = imagename.substr(0, 2);
|
||||||
|
diff = levenshtein_distance(imagename, platestr);
|
||||||
|
dif = diff - 4;
|
||||||
|
cout << "差距:" << dif << endl;
|
||||||
|
sum += dif;
|
||||||
|
if (ch != chpr) n++;
|
||||||
|
if (diff == 0) correct++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
float cha = 1 - float(n) / float(j);
|
||||||
|
std::cout << "------------------------------------------------" << endl;
|
||||||
|
cout << "车牌总数:" << j << endl;
|
||||||
|
cout << "汉字识别准确率:" << cha << endl;
|
||||||
|
float chaccuracy = 1 - float(sum - n * 2) / float(j * 8);
|
||||||
|
cout << "字符识别准确率:" << chaccuracy << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
int main()
|
|
||||||
|
|
||||||
|
void TEST_PIPELINE() {
|
||||||
|
|
||||||
|
pr::PipelinePR prc("../lpr/model/cascade.xml",
|
||||||
|
"../lpr/model/HorizonalFinemapping.prototxt", "../lpr/model/HorizonalFinemapping.caffemodel",
|
||||||
|
"../lpr/model/Segmentation.prototxt", "../lpr/model/Segmentation.caffemodel",
|
||||||
|
"../lpr/model/CharacterRecognization.prototxt", "../lpr/model/CharacterRecognization.caffemodel",
|
||||||
|
"../lpr/model/SegmentationFree.prototxt", "../lpr/model/SegmentationFree.caffemodel"
|
||||||
|
);
|
||||||
|
|
||||||
|
cv::Mat image = cv::imread("../lpr/res/test.jpg");
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(image, pr::SEGMENTATION_FREE_METHOD);
|
||||||
|
|
||||||
|
for (auto st : res) {
|
||||||
|
if (st.confidence > 0.75) {
|
||||||
|
std::cout << st.getPlateName() << " " << st.confidence << std::endl;
|
||||||
|
cv::Rect region = st.getPlateRect();
|
||||||
|
|
||||||
|
cv::rectangle(image, cv::Point(region.x, region.y), cv::Point(region.x + region.width, region.y + region.height), cv::Scalar(255, 255, 0), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::imshow("image", image);
|
||||||
|
cv::waitKey(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*void TEST_CAM()
|
||||||
{
|
{
|
||||||
|
|
||||||
TEST_PIPELINE();
|
cv::VideoCapture capture("test1.mp4");
|
||||||
|
cv::Mat frame;
|
||||||
|
|
||||||
|
pr::PipelinePR prc("../lpr/model/cascade.xml",
|
||||||
|
"../lpr/model/HorizonalFinemapping.prototxt", "../lpr/model/HorizonalFinemapping.caffemodel",
|
||||||
|
"../lpr/model/Segmentation.prototxt", "../lpr/model/Segmentation.caffemodel",
|
||||||
|
"../lpr/model/CharacterRecognization.prototxt", "../lpr/model/CharacterRecognization.caffemodel",
|
||||||
|
"../lpr/model/SegmentationFree.prototxt", "../lpr/model/SegmentationFree.caffemodel"
|
||||||
|
);
|
||||||
|
while (1) {
|
||||||
|
//读取下一帧
|
||||||
|
if (!capture.read(frame)) {
|
||||||
|
std::cout << "读取视频失败" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// cv::transpose(frame,frame);
|
||||||
|
// cv::flip(frame,frame,2);
|
||||||
|
|
||||||
|
// cv::resize(frame,frame,cv::Size(frame.cols/2,frame.rows/2));
|
||||||
|
|
||||||
|
|
||||||
return 0 ;
|
|
||||||
|
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(frame, pr::SEGMENTATION_FREE_METHOD);
|
||||||
|
|
||||||
|
for (auto st : res) {
|
||||||
|
if (st.confidence > 0.75) {
|
||||||
|
std::cout << st.getPlateName() << " " << st.confidence << std::endl;
|
||||||
|
cv::Rect region = st.getPlateRect();
|
||||||
|
|
||||||
|
cv::rectangle(frame, cv::Point(region.x, region.y), cv::Point(region.x + region.width, region.y + region.height), cv::Scalar(255, 255, 0), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::imshow("image", frame);
|
||||||
|
cv::waitKey(1);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// TEST_ACC();
|
||||||
|
|
||||||
|
// TEST_CAM();
|
||||||
|
TEST_PIPELINE();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 23/10/2017.
|
// Created by Jack Yu on 23/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../include/CNNRecognizer.h"
|
#include "../include/CNNRecognizer.h"
|
||||||
@@ -16,6 +16,7 @@ void getMaxClass(cv::Mat &probBlob, int *classId, double *classProb)
|
|||||||
cv::Point classNumber;
|
cv::Point classNumber;
|
||||||
|
|
||||||
cv::minMaxLoc(probBlob, NULL, classProb, NULL, &classNumber);
|
cv::minMaxLoc(probBlob, NULL, classProb, NULL, &classNumber);
|
||||||
|
|
||||||
*classId = classNumber.x;
|
*classId = classNumber.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Created by 庾金科 on 16/10/2017.
|
// Created by Jack Yu on 16/10/2017.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// Created by Jack Yu on 29/11/2017.
|
||||||
|
//
|
||||||
|
#include "../include/SegmentationFreeRecognizer.h"
|
||||||
|
#include "../include/Pipeline.h"
|
||||||
|
|
||||||
|
#include "../include/PlateInfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::string decodeResults(cv::Mat code_table,std::vector<std::string> mapping_table)
|
||||||
|
{
|
||||||
|
cv::MatSize mtsize = code_table.size;
|
||||||
|
int sequencelength = mtsize[2];
|
||||||
|
int labellength = mtsize[1];
|
||||||
|
cv::transpose(code_table.reshape(1,1).reshape(1,labellength),code_table);
|
||||||
|
std::string name = "";
|
||||||
|
std::vector<int> seq(sequencelength);
|
||||||
|
for(int i = 0 ; i < sequencelength; i++) {
|
||||||
|
float *fstart = ((float *) (code_table.data) + i * labellength );
|
||||||
|
int id = std::max_element(fstart,fstart+labellength) - fstart;
|
||||||
|
seq[i] =id;
|
||||||
|
}
|
||||||
|
for(int i = 0 ; i< sequencelength ; i++)
|
||||||
|
{
|
||||||
|
if(seq[i]!=labellength-1 && (i==0 || seq[i]!=seq[i-1]))
|
||||||
|
name+=mapping_table[seq[i]];
|
||||||
|
}
|
||||||
|
std::cout<<name;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
cv::Mat image = cv::imread("res/cache/chars_segment.jpg");
|
||||||
|
// cv::transpose(image,image);
|
||||||
|
|
||||||
|
// cv::resize(image,image,cv::Size(160,40));
|
||||||
|
cv::imshow("xxx",image);
|
||||||
|
cv::waitKey(0);
|
||||||
|
pr::SegmentationFreeRecognizer recognizr("model/SegmenationFree-Inception.prototxt","model/ISegmenationFree-Inception.caffemodel");
|
||||||
|
std::pair<std::string,float> res = recognizr.SegmentationFreeForSinglePlate(image,pr::CH_PLATE_CODE);
|
||||||
|
std::cout<<res.first<<" "
|
||||||
|
<<res.second<<std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
// decodeResults(plate,pr::CH_PLATE_CODE);
|
||||||
|
cv::imshow("image",image);
|
||||||
|
cv::waitKey(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user