Browse Source

Prj-linux and Prj-win add double-deck support

new Prj-linux with end-end model
v2
xsl 5 years ago
parent
commit
f6e43f38a0
69 changed files with 3317 additions and 27188 deletions
  1. +1
    -1
      Prj-Linux/CMakeLists.txt
  2. +5
    -39
      Prj-Linux/lpr/CMakeLists.txt
  3. +0
    -24
      Prj-Linux/lpr/include/CNNRecognizer.h
  4. +0
    -18
      Prj-Linux/lpr/include/FastDeskew.h
  5. +0
    -32
      Prj-Linux/lpr/include/FineMapping.h
  6. +18
    -0
      Prj-Linux/lpr/include/Finetune.h
  7. +39
    -59
      Prj-Linux/lpr/include/Pipeline.h
  8. +0
    -25
      Prj-Linux/lpr/include/PlateDetection.h
  9. +23
    -5
      Prj-Linux/lpr/include/PlateInfo.h
  10. +15
    -0
      Prj-Linux/lpr/include/PlateRecognation.h
  11. +0
    -35
      Prj-Linux/lpr/include/PlateSegmentation.h
  12. +23
    -0
      Prj-Linux/lpr/include/Platedetect.h
  13. +0
    -23
      Prj-Linux/lpr/include/Recognizer.h
  14. +0
    -28
      Prj-Linux/lpr/include/SegmentationFreeRecognizer.h
  15. +0
    -103
      Prj-Linux/lpr/include/niBlackThreshold.h
  16. BIN
      Prj-Linux/lpr/model/CharacterRecognization.caffemodel
  17. +0
    -123
      Prj-Linux/lpr/model/CharacterRecognization.prototxt
  18. BIN
      Prj-Linux/lpr/model/HorizonalFinemapping.caffemodel
  19. +11
    -0
      Prj-Linux/lpr/model/README.md
  20. BIN
      Prj-Linux/lpr/model/SegmenationFree-Inception.caffemodel
  21. BIN
      Prj-Linux/lpr/model/Segmentation.caffemodel
  22. +0
    -114
      Prj-Linux/lpr/model/Segmentation.prototxt
  23. +0
    -12117
      Prj-Linux/lpr/model/cascade.xml
  24. +504
    -0
      Prj-Linux/lpr/model/cascade_double.xml
  25. BIN
      Prj-Linux/lpr/model/mininet_ssd_v1.caffemodel
  26. +1462
    -0
      Prj-Linux/lpr/model/mininet_ssd_v1.prototxt
  27. BIN
      Prj-Linux/lpr/model/refinenet.caffemodel
  28. +300
    -0
      Prj-Linux/lpr/model/refinenet.prototxt
  29. BIN
      Prj-Linux/lpr/res/test.jpg
  30. BIN
      Prj-Linux/lpr/res/test_db1.jpg
  31. +0
    -19
      Prj-Linux/lpr/src/CNNRecognizer.cpp
  32. +0
    -108
      Prj-Linux/lpr/src/FastDeskew.cpp
  33. +0
    -163
      Prj-Linux/lpr/src/FineMapping.cpp
  34. +67
    -0
      Prj-Linux/lpr/src/FineTune.cpp
  35. +64
    -68
      Prj-Linux/lpr/src/Pipeline.cpp
  36. +85
    -16
      Prj-Linux/lpr/src/PlateDetection.cpp
  37. +61
    -0
      Prj-Linux/lpr/src/PlateRecognation.cpp
  38. +0
    -404
      Prj-Linux/lpr/src/PlateSegmentation.cpp
  39. +0
    -23
      Prj-Linux/lpr/src/Recognizer.cpp
  40. +0
    -89
      Prj-Linux/lpr/src/SegmentationFreeRecognizer.cpp
  41. +0
    -67
      Prj-Linux/lpr/src/util.h
  42. +28
    -0
      Prj-Linux/lpr/tests/testPipeLine.cpp
  43. +0
    -32
      Prj-Linux/lpr/tests/test_detection.cpp
  44. +0
    -34
      Prj-Linux/lpr/tests/test_fastdeskew.cpp
  45. +0
    -25
      Prj-Linux/lpr/tests/test_finemapping.cpp
  46. +0
    -179
      Prj-Linux/lpr/tests/test_pipeline.cpp
  47. +0
    -54
      Prj-Linux/lpr/tests/test_recognization.cpp
  48. +0
    -43
      Prj-Linux/lpr/tests/test_segmentation.cpp
  49. +0
    -54
      Prj-Linux/lpr/tests/test_segmentationFree.cpp
  50. +4
    -4
      Prj-Win/lpr/include/Pipeline.h
  51. +7
    -0
      Prj-Win/lpr/include/Platedetect.h
  52. +504
    -0
      Prj-Win/lpr/model/cascade_double.xml
  53. +44
    -11
      Prj-Win/lpr/src/Pipeline.cpp
  54. +43
    -0
      Prj-Win/lpr/src/PlateDetection.cpp
  55. +6
    -5
      Prj-Win/lpr/tests/testPipeLine.cpp
  56. +0
    -55
      WebAPI.py
  57. +2
    -2
      hyperlpr_pip_pkg/demo.py
  58. +1
    -0
      hyperlpr_pip_pkg/hyperlpr/table_chs.py
  59. +0
    -12117
      model/cascade.xml
  60. +0
    -842
      model/cascade_lbp.xml
  61. BIN
      model/char_chi_sim.h5
  62. BIN
      model/char_judgement.h5
  63. BIN
      model/char_judgement1.h5
  64. BIN
      model/char_rec.h5
  65. BIN
      model/model12.h5
  66. BIN
      model/ocr_plate_all_gru.h5
  67. BIN
      model/ocr_plate_all_w_rnn_2.h5
  68. BIN
      model/plate_type.h5
  69. +0
    -28
      wxpy_uploader.py

+ 1
- 1
Prj-Linux/CMakeLists.txt View File

@@ -1,3 +1,3 @@
cmake_minimum_required(VERSION 3.6)
project(HyperLPR)
add_subdirectory(hyperlpr)
add_subdirectory(lpr)

+ 5
- 39
Prj-Linux/lpr/CMakeLists.txt View File

@@ -3,49 +3,15 @@ project(SwiftPR)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
find_package(OpenCV 3.3.0 REQUIRED)
find_package(OpenCV 3.4.3 REQUIRED)
include_directories( ${OpenCV_INCLUDE_DIRS})
include_directories(include)

set(SRC_DETECTION src/PlateDetection.cpp src/util.h include/PlateDetection.h)
set(SRC_FINEMAPPING src/FineMapping.cpp )
set(SRC_FASTDESKEW src/FastDeskew.cpp )
set(SRC_SEGMENTATION src/PlateSegmentation.cpp )
set(SRC_RECOGNIZE src/Recognizer.cpp src/CNNRecognizer.cpp)
set(SRC_DETECTION src/PlateDetection.cpp)
set(SRC_FINETUNE src/FineTune.cpp)
set(SRC_RECOGNIZE src/PlateRecognation.cpp)
set(SRC_PIPLINE src/Pipeline.cpp)
set(SRC_SEGMENTATIONFREE src/SegmentationFreeRecognizer.cpp )

#set(SOURCE_FILES main.cpp)
#add_executable(HyperLPR_cpp ${SOURCE_FILES})

#TEST_DETECTION
add_executable(TEST_Detection ${SRC_DETECTION} tests/test_detection.cpp)
target_link_libraries(TEST_Detection ${OpenCV_LIBS})

#TEST_FINEMAPPING
add_executable(TEST_FINEMAPPING ${SRC_FINEMAPPING} tests/test_finemapping.cpp)
target_link_libraries(TEST_FINEMAPPING ${OpenCV_LIBS})

#TEST_DESKEW

add_executable(TEST_FASTDESKEW ${SRC_FASTDESKEW} tests/test_fastdeskew.cpp)
target_link_libraries(TEST_FASTDESKEW ${OpenCV_LIBS})

#TEST_SEGMENTATION

add_executable(TEST_SEGMENTATION ${SRC_SEGMENTATION} ${SRC_RECOGNIZE} tests/test_segmentation.cpp)
target_link_libraries(TEST_SEGMENTATION ${OpenCV_LIBS})

#TEST_RECOGNIZATION

add_executable(TEST_RECOGNIZATION ${SRC_RECOGNIZE} tests/test_recognization.cpp)
target_link_libraries(TEST_RECOGNIZATION ${OpenCV_LIBS})

#TEST_SEGMENTATIONFREE
add_executable(TEST_SEGMENTATIONFREE ${SRC_SEGMENTATIONFREE} tests/test_segmentationFree.cpp)
target_link_libraries(TEST_SEGMENTATIONFREE ${OpenCV_LIBS})

#TEST_PIPELINE

add_executable(TEST_PIPLINE ${SRC_DETECTION} ${SRC_FINEMAPPING} ${SRC_FASTDESKEW} ${SRC_SEGMENTATION} ${SRC_RECOGNIZE} ${SRC_PIPLINE} ${SRC_SEGMENTATIONFREE} tests/test_pipeline.cpp)
add_executable(TEST_PIPLINE ${SRC_DETECTION} ${SRC_FINETUNE} ${SRC_RECOGNIZE} ${SRC_PIPLINE} tests/testPipeLine.cpp)
target_link_libraries(TEST_PIPLINE ${OpenCV_LIBS})

+ 0
- 24
Prj-Linux/lpr/include/CNNRecognizer.h View File

@@ -1,24 +0,0 @@
//
// Created by Jack Yu on 21/10/2017.
//

#ifndef SWIFTPR_CNNRECOGNIZER_H
#define SWIFTPR_CNNRECOGNIZER_H

#include "Recognizer.h"
namespace pr{
class CNNRecognizer: public GeneralRecognizer{
public:
const int CHAR_INPUT_W = 14;
const int CHAR_INPUT_H = 30;

CNNRecognizer(std::string prototxt,std::string caffemodel);
label recognizeCharacter(cv::Mat character);
private:
cv::dnn::Net net;

};

}

#endif //SWIFTPR_CNNRECOGNIZER_H

+ 0
- 18
Prj-Linux/lpr/include/FastDeskew.h View File

@@ -1,18 +0,0 @@
//
// Created by 庾金科 on 22/09/2017.
//

#ifndef SWIFTPR_FASTDESKEW_H
#define SWIFTPR_FASTDESKEW_H

#include <math.h>
#include <opencv2/opencv.hpp>
namespace pr{

cv::Mat fastdeskew(cv::Mat skewImage,int blockSize);
// cv::Mat spatialTransformer(cv::Mat skewImage);

}//namepace pr


#endif //SWIFTPR_FASTDESKEW_H

+ 0
- 32
Prj-Linux/lpr/include/FineMapping.h View File

@@ -1,32 +0,0 @@
//
// Created by 庾金科 on 22/09/2017.
//

#ifndef SWIFTPR_FINEMAPPING_H
#define SWIFTPR_FINEMAPPING_H

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>

#include <string>
namespace pr{
class FineMapping{
public:
FineMapping();


FineMapping(std::string prototxt,std::string caffemodel);
static cv::Mat FineMappingVertical(cv::Mat InputProposal,int sliceNum=15,int upper=0,int lower=-50,int windows_size=17);
cv::Mat FineMappingHorizon(cv::Mat FinedVertical,int leftPadding,int rightPadding);


private:
cv::dnn::Net net;

};




}
#endif //SWIFTPR_FINEMAPPING_H

+ 18
- 0
Prj-Linux/lpr/include/Finetune.h View File

@@ -0,0 +1,18 @@
#ifndef _FINETUNE_H_
#define _FINETUNE_H_
#include<vector>
#include<opencv2/dnn.hpp>
#include<opencv2/opencv.hpp>
namespace pr {
class FineTune {
public:

FineTune(std::string finetune_prototxt, std::string finetune_caffemodel);
void Finetune(cv::Mat img, cv::Mat &resImg);
void to_refine(cv::Mat img, std::vector<cv::Point> pts, cv::Mat &out);
void affine_crop(cv::Mat img, std::vector<cv::Point> pts, cv::Mat &out);
private:
cv::dnn::Net FTNet;
};
}//namespace pr
#endif // !_FINETUNE_H_

+ 39
- 59
Prj-Linux/lpr/include/Pipeline.h View File

@@ -1,60 +1,40 @@
//
// Created by 庾金科 on 22/10/2017.
//

#ifndef SWIFTPR_PIPLINE_H
#define SWIFTPR_PIPLINE_H

#include "PlateDetection.h"
#include "PlateSegmentation.h"
#include "CNNRecognizer.h"
#include "PlateInfo.h"
#include "FastDeskew.h"
#include "FineMapping.h"
#include "Recognizer.h"
#include "SegmentationFreeRecognizer.h"

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{
public:
GeneralRecognizer *generalRecognizer;
PlateDetection *plateDetection;
PlateSegmentation *plateSegmentation;
FineMapping *fineMapping;
SegmentationFreeRecognizer *segmentationFreeRecognizer;

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
);
~PipelinePR();



std::vector<std::string> plateRes;
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat plateImage,int method);







};


#pragma warning(disable:4430)
#ifndef _PIPLINE_H
#define _PIPLINE_H
#include <vector>
#include "Finetune.h"
#include "Platedetect.h"
#include "PlateRecognation.h"
//#include "PlateColor.h"
using namespace std;
using namespace cv;
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","港","学","使","警","澳","挂","军","北","南","广","沈","兰","成","济","海","民","航","空" };


class PipelinePR {

public:
PlateDetection *platedetection;
FineTune *finetune;
PlateRecognation *platerecognation;
DBDetection *dbdetection;


PipelinePR(std::string detect_prototxt, std::string detect_caffemodel,
std::string finetune_prototxt, std::string finetune_caffemodel,
std::string platerec_prototxt, std::string platerec_caffemodel,
std::string dbstring);
~PipelinePR();

std::vector<std::string> plateRes;
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat srcImage,int IsDB);

};
}
#endif //SWIFTPR_PIPLINE_H
#endif // !SWIFTPR_PIPLINE_H

+ 0
- 25
Prj-Linux/lpr/include/PlateDetection.h View File

@@ -1,25 +0,0 @@
//
// Created by 庾金科 on 20/09/2017.
//

#ifndef SWIFTPR_PLATEDETECTION_H
#define SWIFTPR_PLATEDETECTION_H

#include <opencv2/opencv.hpp>
#include <PlateInfo.h>
#include <vector>
namespace pr{
class PlateDetection{
public:
PlateDetection(std::string filename_cascade);
PlateDetection();
void LoadModel(std::string filename_cascade);
void plateDetectionRough(cv::Mat InputImage,std::vector<pr::PlateInfo> &plateInfos,int min_w=36,int max_w=800);
private:
cv::CascadeClassifier cascade;
};

}// namespace pr

#endif //SWIFTPR_PLATEDETECTION_H


+ 23
- 5
Prj-Linux/lpr/include/PlateInfo.h View File

@@ -1,14 +1,14 @@
//
// Created by 庾金科 on 20/09/2017.
//

#ifndef SWIFTPR_PLATEINFO_H
#define SWIFTPR_PLATEINFO_H
#include <opencv2/opencv.hpp>
namespace pr {

typedef std::vector<cv::Mat> Character;

enum PlateColor { BLUE, YELLOW, WHITE, GREEN, BLACK,UNKNOWN};
enum CharType {CHINESE,LETTER,LETTER_NUMS,INVALID};


class PlateInfo {
public:
std::vector<std::pair<CharType,cv::Mat>> plateChars;
@@ -58,7 +58,11 @@ namespace pr {
int getPlateType() {
return Type;
}

int setPlateType(PlateColor platetype)
{
Type = platetype;
return 0;
}
void appendPlateChar(const std::pair<CharType,cv::Mat> &plateChar)
{
plateChars.push_back(plateChar);
@@ -68,6 +72,10 @@ namespace pr {
plateCoding.push_back(charProb);
}

// cv::Mat getPlateChars(int id) {
// if(id<PlateChars.size())
// return PlateChars[id];
// }
std::string decodePlateNormal(std::vector<std::string> mappingTable) {
std::string decode;
for(auto plate:plateCoding) {
@@ -76,6 +84,10 @@ namespace pr {

decode += mappingTable[std::max_element(prob,prob+31) - prob];
confidence+=*std::max_element(prob,prob+31);


// std::cout<<*std::max_element(prob,prob+31)<<std::endl;

}

else if(plate.first == LETTER) {
@@ -86,16 +98,22 @@ namespace pr {
else if(plate.first == LETTER_NUMS) {
decode += mappingTable[std::max_element(prob+31,prob+65)- prob];
confidence+=*std::max_element(prob+31,prob+65);
// std::cout<<*std::max_element(prob+31,prob+65)<<std::endl;

}
else if(plate.first == INVALID)
{
decode+='*';
}

}
name = decode;

confidence/=7;

return decode;
}

private:
cv::Mat licensePlate;
cv::Rect ROI;


+ 15
- 0
Prj-Linux/lpr/include/PlateRecognation.h View File

@@ -0,0 +1,15 @@
#ifndef _PLATERECOGNATION_H_
#define _PLATERECOGNATION_H_
#include <opencv2/dnn.hpp>
#include "PlateInfo.h"
namespace pr {
class PlateRecognation {
public:
PlateRecognation(std::string Rec_prototxt, std::string Rec_cafffemodel);
void segmentation_free_recognation(cv::Mat src, pr::PlateInfo &plateinfo);
private:
cv::dnn::Net RecNet;
};
}//namespace pr
#endif // !_PLATERECOGNATION_H_


+ 0
- 35
Prj-Linux/lpr/include/PlateSegmentation.h View File

@@ -1,35 +0,0 @@
#ifndef SWIFTPR_PLATESEGMENTATION_H
#define SWIFTPR_PLATESEGMENTATION_H

#include "opencv2/opencv.hpp"
#include <opencv2/dnn.hpp>
#include "PlateInfo.h"

namespace pr{


class PlateSegmentation{
public:
const int PLATE_NORMAL = 6;
const int PLATE_NORMAL_GREEN = 7;
const int DEFAULT_WIDTH = 20;
PlateSegmentation(std::string phototxt,std::string caffemodel);
PlateSegmentation(){}
void segmentPlatePipline(PlateInfo &plateInfo,int stride,std::vector<cv::Rect> &Char_rects);

void segmentPlateBySlidingWindows(cv::Mat &plateImage,int windowsWidth,int stride,cv::Mat &respones);
void templateMatchFinding(const cv::Mat &respones,int windowsWidth,std::pair<float,std::vector<int>> &candidatePts);
void refineRegion(cv::Mat &plateImage,const std::vector<int> &candidatePts,const int padding,std::vector<cv::Rect> &rects);
void ExtractRegions(PlateInfo &plateInfo,std::vector<cv::Rect> &rects);
cv::Mat classifyResponse(const cv::Mat &cropped);
private:
cv::dnn::Net net;


// RefineRegion()

};

}//namespace pr

#endif //SWIFTPR_PLATESEGMENTATION_H

+ 23
- 0
Prj-Linux/lpr/include/Platedetect.h View File

@@ -0,0 +1,23 @@
#ifndef _PLATEDETECT_H_
#define _PLATEDETECT_H_
#include <opencv2/opencv.hpp>
#include <vector>
#include "PlateInfo.h"
namespace pr
{
class PlateDetection {
public:
PlateDetection(std::string ssd_prototxt, std::string ssd_caffe_model);
void Detectssd(cv::Mat inputImg, std::vector<pr::PlateInfo> &plateInfos);
private:
cv::dnn::Net ssdNet;
};
class DBDetection{
public:
DBDetection(std::string cascadestring);
void DBDetect(cv::Mat inputImg,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w);
private:
cv::CascadeClassifier dbcascade;
};
}//namespace pr
#endif // !_PLATEDETECT_H_

+ 0
- 23
Prj-Linux/lpr/include/Recognizer.h View File

@@ -1,23 +0,0 @@
//
// Created by 庾金科 on 20/10/2017.
//


#ifndef SWIFTPR_RECOGNIZER_H
#define SWIFTPR_RECOGNIZER_H

#include "PlateInfo.h"
#include "opencv2/dnn.hpp"
namespace pr{
typedef cv::Mat label;
class GeneralRecognizer{
public:
virtual label recognizeCharacter(cv::Mat character) = 0;
// virtual cv::Mat SegmentationFreeForSinglePlate(cv::Mat plate) = 0;
void SegmentBasedSequenceRecognition(PlateInfo &plateinfo);
void SegmentationFreeSequenceRecognition(PlateInfo &plateInfo);

};

}
#endif //SWIFTPR_RECOGNIZER_H

+ 0
- 28
Prj-Linux/lpr/include/SegmentationFreeRecognizer.h View File

@@ -1,28 +0,0 @@
//
// 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

+ 0
- 103
Prj-Linux/lpr/include/niBlackThreshold.h View File

@@ -1,103 +0,0 @@
//
// Created by 庾金科 on 26/10/2017.
//

#ifndef SWIFTPR_NIBLACKTHRESHOLD_H
#define SWIFTPR_NIBLACKTHRESHOLD_H


#include <opencv2/opencv.hpp>
using namespace cv;

enum LocalBinarizationMethods{
BINARIZATION_NIBLACK = 0, //!< Classic Niblack binarization. See @cite Niblack1985 .
BINARIZATION_SAUVOLA = 1, //!< Sauvola's technique. See @cite Sauvola1997 .
BINARIZATION_WOLF = 2, //!< Wolf's technique. See @cite Wolf2004 .
BINARIZATION_NICK = 3 //!< NICK technique. See @cite Khurshid2009 .
};


void niBlackThreshold( InputArray _src, OutputArray _dst, double maxValue,
int type, int blockSize, double k, int binarizationMethod )
{
// Input grayscale image
Mat src = _src.getMat();
CV_Assert(src.channels() == 1);
CV_Assert(blockSize % 2 == 1 && blockSize > 1);
if (binarizationMethod == BINARIZATION_SAUVOLA) {
CV_Assert(src.depth() == CV_8U);
}
type &= THRESH_MASK;
// Compute local threshold (T = mean + k * stddev)
// using mean and standard deviation in the neighborhood of each pixel
// (intermediate calculations are done with floating-point precision)
Mat test;
Mat thresh;
{
// note that: Var[X] = E[X^2] - E[X]^2
Mat mean, sqmean, variance, stddev, sqrtVarianceMeanSum;
double srcMin, stddevMax;
boxFilter(src, mean, CV_32F, Size(blockSize, blockSize),
Point(-1,-1), true, BORDER_REPLICATE);
sqrBoxFilter(src, sqmean, CV_32F, Size(blockSize, blockSize),
Point(-1,-1), true, BORDER_REPLICATE);
variance = sqmean - mean.mul(mean);
sqrt(variance, stddev);
switch (binarizationMethod)
{
case BINARIZATION_NIBLACK:
thresh = mean + stddev * static_cast<float>(k);

break;
case BINARIZATION_SAUVOLA:
thresh = mean.mul(1. + static_cast<float>(k) * (stddev / 128.0 - 1.));
break;
case BINARIZATION_WOLF:
minMaxIdx(src, &srcMin,NULL);
minMaxIdx(stddev, NULL, &stddevMax);
thresh = mean - static_cast<float>(k) * (mean - srcMin - stddev.mul(mean - srcMin) / stddevMax);
break;
case BINARIZATION_NICK:
sqrt(variance + sqmean, sqrtVarianceMeanSum);
thresh = mean + static_cast<float>(k) * sqrtVarianceMeanSum;
break;
default:
CV_Error( CV_StsBadArg, "Unknown binarization method" );
break;
}
thresh.convertTo(thresh, src.depth());

thresh.convertTo(test, src.depth());
}
// Prepare output image
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
CV_Assert(src.data != dst.data); // no inplace processing
// Apply thresholding: ( pixel > threshold ) ? foreground : background
Mat mask;
switch (type)
{
case THRESH_BINARY: // dst = (src > thresh) ? maxval : 0
case THRESH_BINARY_INV: // dst = (src > thresh) ? 0 : maxval
compare(src, thresh, mask, (type == THRESH_BINARY ? CMP_GT : CMP_LE));
dst.setTo(0);
dst.setTo(maxValue, mask);
break;
case THRESH_TRUNC: // dst = (src > thresh) ? thresh : src
compare(src, thresh, mask, CMP_GT);
src.copyTo(dst);
thresh.copyTo(dst, mask);
break;
case THRESH_TOZERO: // dst = (src > thresh) ? src : 0
case THRESH_TOZERO_INV: // dst = (src > thresh) ? 0 : src
compare(src, thresh, mask, (type == THRESH_TOZERO ? CMP_GT : CMP_LE));
dst.setTo(0);
src.copyTo(dst, mask);
break;
default:
CV_Error( CV_StsBadArg, "Unknown threshold type" );
break;
}
}

#endif //SWIFTPR_NIBLACKTHRESHOLD_H

BIN
Prj-Linux/lpr/model/CharacterRecognization.caffemodel View File


+ 0
- 123
Prj-Linux/lpr/model/CharacterRecognization.prototxt View File

@@ -1,123 +0,0 @@
input: "data"
input_dim: 1
input_dim: 1
input_dim: 30
input_dim: 14
layer {
name: "conv2d_1"
type: "Convolution"
bottom: "data"
top: "conv2d_1"
convolution_param {
num_output: 32
bias_term: true
pad: 0
kernel_size: 3
stride: 1
}
}
layer {
name: "activation_1"
type: "ReLU"
bottom: "conv2d_1"
top: "activation_1"
}
layer {
name: "max_pooling2d_1"
type: "Pooling"
bottom: "activation_1"
top: "max_pooling2d_1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
pad: 0
}
}
layer {
name: "conv2d_2"
type: "Convolution"
bottom: "max_pooling2d_1"
top: "conv2d_2"
convolution_param {
num_output: 64
bias_term: true
pad: 0
kernel_size: 3
stride: 1
}
}
layer {
name: "activation_2"
type: "ReLU"
bottom: "conv2d_2"
top: "activation_2"
}
layer {
name: "max_pooling2d_2"
type: "Pooling"
bottom: "activation_2"
top: "max_pooling2d_2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
pad: 0
}
}
layer {
name: "conv2d_3"
type: "Convolution"
bottom: "max_pooling2d_2"
top: "conv2d_3"
convolution_param {
num_output: 128
bias_term: true
pad: 0
kernel_size: 2
stride: 1
}
}
layer {
name: "activation_3"
type: "ReLU"
bottom: "conv2d_3"
top: "activation_3"
}
layer {
name: "flatten_1"
type: "Flatten"
bottom: "activation_3"
top: "flatten_1"
}
layer {
name: "dense_1"
type: "InnerProduct"
bottom: "flatten_1"
top: "dense_1"
inner_product_param {
num_output: 256
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "dense_1"
top: "relu2"
}
layer {
name: "dense2"
type: "InnerProduct"
bottom: "relu2"
top: "dense2"
inner_product_param {
num_output: 65
}
}

layer {
name: "prob"
type: "Softmax"
bottom: "dense2"
top: "prob"
}

BIN
Prj-Linux/lpr/model/HorizonalFinemapping.caffemodel View File


+ 11
- 0
Prj-Linux/lpr/model/README.md View File

@@ -0,0 +1,11 @@
将/hyperlpr_pip_pkg/hyperlpr/models/dnn/目录下的

mininet_ssd_v1.caffemodel
mininet_ssd_v1.prototxt
refinenet.caffemodel
refinenet.prototxt
SegmenationFree-Inception.caffemodel
SegmenationFree-Inception.prototxt


放置在该目录

BIN
Prj-Linux/lpr/model/SegmenationFree-Inception.caffemodel View File


BIN
Prj-Linux/lpr/model/Segmentation.caffemodel View File


+ 0
- 114
Prj-Linux/lpr/model/Segmentation.prototxt View File

@@ -1,114 +0,0 @@
input: "data"
input_dim: 1
input_dim: 1
input_dim: 22
input_dim: 22
layer {
name: "conv2d_12"
type: "Convolution"
bottom: "data"
top: "conv2d_12"
convolution_param {
num_output: 16
bias_term: true
pad: 0
kernel_size: 3
stride: 1
}
}
layer {
name: "activation_18"
type: "ReLU"
bottom: "conv2d_12"
top: "activation_18"
}
layer {
name: "max_pooling2d_10"
type: "Pooling"
bottom: "activation_18"
top: "max_pooling2d_10"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
pad: 0
}
}
layer {
name: "conv2d_13"
type: "Convolution"
bottom: "max_pooling2d_10"
top: "conv2d_13"
convolution_param {
num_output: 16
bias_term: true
pad: 0
kernel_size: 3
stride: 1
}
}
layer {
name: "activation_19"
type: "ReLU"
bottom: "conv2d_13"
top: "activation_19"
}
layer {
name: "max_pooling2d_11"
type: "Pooling"
bottom: "activation_19"
top: "max_pooling2d_11"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
pad: 0
}
}
layer {
name: "flatten_6"
type: "Flatten"
bottom: "max_pooling2d_11"
top: "flatten_6"
}
layer {
name: "dense_9"
type: "InnerProduct"
bottom: "flatten_6"
top: "dense_9"
inner_product_param {
num_output: 256
}
}
layer {
name: "dropout_9"
type: "Dropout"
bottom: "dense_9"
top: "dropout_9"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
name: "activation_20"
type: "ReLU"
bottom: "dropout_9"
top: "activation_20"
}
layer {
name: "dense_10"
type: "InnerProduct"
bottom: "activation_20"
top: "dense_10"
inner_product_param {
num_output: 3
}
}


layer {
name: "prob"
type: "Softmax"
bottom: "dense_10"
top: "prob"
}

+ 0
- 12117
Prj-Linux/lpr/model/cascade.xml
File diff suppressed because it is too large
View File


+ 504
- 0
Prj-Linux/lpr/model/cascade_double.xml View File

@@ -0,0 +1,504 @@
<?xml version="1.0"?>
<opencv_storage>
<cascade>
<stageType>BOOST</stageType>
<featureType>LBP</featureType>
<height>24</height>
<width>44</width>
<stageParams>
<boostType>GAB</boostType>
<minHitRate>9.9599999189376831e-01</minHitRate>
<maxFalseAlarm>5.0000000000000000e-01</maxFalseAlarm>
<weightTrimRate>9.4999999999999996e-01</weightTrimRate>
<maxDepth>1</maxDepth>
<maxWeakCount>28</maxWeakCount></stageParams>
<featureParams>
<maxCatCount>256</maxCatCount>
<featSize>1</featSize></featureParams>
<stageNum>11</stageNum>
<stages>
<!-- stage 0 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-1.1049392223358154e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 17 -3334 -513 -573452048 -1057 -1 -267777 -1 -1025</internalNodes>
<leafValues>
-9.4297146797180176e-01 7.8370976448059082e-01</leafValues></_>
<_>
<internalNodes>
0 -1 36 -262198 -12062208 -169869377 -674954752 -7602177
-16781941 -67109937 -1073</internalNodes>
<leafValues>
-8.8537323474884033e-01 7.2940820455551147e-01</leafValues></_>
<_>
<internalNodes>
0 -1 9 1431697887 1431687647 -545270049 -262145 1413609965
1364250775 -1065985 -67108865</internalNodes>
<leafValues>
-8.3008646965026855e-01 7.2340542078018188e-01</leafValues></_></weakClassifiers></_>
<!-- stage 1 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-1.0404651165008545e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 19 -524289 -136314913 1360393719 -2097153 -134219777
-4194817 274068735 -1</internalNodes>
<leafValues>
-8.5476654767990112e-01 8.4671354293823242e-01</leafValues></_>
<_>
<internalNodes>
0 -1 29 -16515073 -150929664 -1 -8650881 -8388609 -11403265
-1 -2097153</internalNodes>
<leafValues>
-7.7620923519134521e-01 7.8929436206817627e-01</leafValues></_>
<_>
<internalNodes>
0 -1 1 2013233135 2147450879 -45760593 2147474943 2146959359
2104754047 2080374783 2147417087</internalNodes>
<leafValues>
-8.9144438505172729e-01 5.9051072597503662e-01</leafValues></_></weakClassifiers></_>
<!-- stage 2 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-1.1397969722747803e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 15 -1041 -8225 -546308113 -1 -33554433 -394753 -2359297
-1</internalNodes>
<leafValues>
-8.5447394847869873e-01 7.4388968944549561e-01</leafValues></_>
<_>
<internalNodes>
0 -1 27 -1053970 -17 -35651601 -1048625 -345331574 -5247030
-74453009 -1</internalNodes>
<leafValues>
-8.6756819486618042e-01 6.3549250364303589e-01</leafValues></_>
<_>
<internalNodes>
0 -1 43 -1050897 -1025 -71304209 -134219793 -1033 -559948801
-67110929 1996976642</internalNodes>
<leafValues>
-8.6068797111511230e-01 5.8224511146545410e-01</leafValues></_></weakClassifiers></_>
<!-- stage 3 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-9.8026764392852783e-01</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 12 -1077953601 -1 -1073758273 -16387 -147457 -1
-1073758209 -1</internalNodes>
<leafValues>
-8.2477015256881714e-01 7.1671992540359497e-01</leafValues></_>
<_>
<internalNodes>
0 -1 47 -4345 -989855745 -271062524 -319815697 -134742265
1423962843 -134218173 -1</internalNodes>
<leafValues>
-7.4230498075485229e-01 7.3275351524353027e-01</leafValues></_>
<_>
<internalNodes>
0 -1 37 -22347778 -3477554 -33554433 -2066 -9438209 -65537
-1 -1048577</internalNodes>
<leafValues>
-8.3125960826873779e-01 5.8680748939514160e-01</leafValues></_></weakClassifiers></_>
<!-- stage 4 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.2986627817153931e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 4 -8388737 -262273 -10485761 -137 -8388745 -129 -262273
-1</internalNodes>
<leafValues>
-8.7727063894271851e-01 6.1173391342163086e-01</leafValues></_>
<_>
<internalNodes>
0 -1 20 -1 -10241 1431688703 -1 -1 -1042 1163263999
2002780159</internalNodes>
<leafValues>
-8.2954949140548706e-01 5.9151750802993774e-01</leafValues></_>
<_>
<internalNodes>
0 -1 3 -44786212 -33726467 -268509185 -17409 -657175332
-2270500 -1198986500 -1148450934</internalNodes>
<leafValues>
-7.6026451587677002e-01 5.8319890499114990e-01</leafValues></_>
<_>
<internalNodes>
0 -1 28 -15794258 -78643282 -821817846 -552742962 -653344834
-91750417 -1622147105 -7340065</internalNodes>
<leafValues>
-7.6077878475189209e-01 5.5891805887222290e-01</leafValues></_>
<_>
<internalNodes>
0 -1 30 1427232247 357954767 1971310559 2012602108
-202375953 -44049 -4456789 -18</internalNodes>
<leafValues>
-6.7643576860427856e-01 6.0950380563735962e-01</leafValues></_></weakClassifiers></_>
<!-- stage 5 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.3029408454895020e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 39 -134218753 -1 -1 -202899593 -1 -4194305 -67108865
-527497</internalNodes>
<leafValues>
-7.5626724958419800e-01 7.5137990713119507e-01</leafValues></_>
<_>
<internalNodes>
0 -1 6 -8388737 -8388737 -1 -1 -8421505 -129 -8388737 -1</internalNodes>
<leafValues>
-7.7118909358978271e-01 6.3570922613143921e-01</leafValues></_>
<_>
<internalNodes>
0 -1 45 -825233914 -654313761 -589830738 -35651585 -16778427
-83886281 -151000316 -1056964737</internalNodes>
<leafValues>
-7.2490030527114868e-01 5.7298541069030762e-01</leafValues></_>
<_>
<internalNodes>
0 -1 18 2002780159 2136866815 -67109377 -19969 2147344383
2101472763 2108680957 2147450607</internalNodes>
<leafValues>
-8.5162043571472168e-01 4.5608481764793396e-01</leafValues></_>
<_>
<internalNodes>
0 -1 16 -7472470 -3505654 -29841 -65536 -1166086177
-67109121 -288690177 -32085</internalNodes>
<leafValues>
-7.9073858261108398e-01 5.0315058231353760e-01</leafValues></_></weakClassifiers></_>
<!-- stage 6 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.3164747953414917e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 41 -1 -1025 -1 -2228225 -8432299 -571189899 -139265 -1</internalNodes>
<leafValues>
-7.8127676248550415e-01 6.5899217128753662e-01</leafValues></_>
<_>
<internalNodes>
0 -1 2 -34275329 -198665 -2113 -12289 -573243396 -590292744
-1049857 -277</internalNodes>
<leafValues>
-7.3563832044601440e-01 6.3897633552551270e-01</leafValues></_>
<_>
<internalNodes>
0 -1 14 -1565523969 -1347420193 -277086209 -1342177313
-134217729 -263169 -285212673 -1459618305</internalNodes>
<leafValues>
-8.1234931945800781e-01 4.9628043174743652e-01</leafValues></_>
<_>
<internalNodes>
0 -1 33 -1079312417 -83826176 -33686017 -570426508
-1627464961 -5377 -277761 -17</internalNodes>
<leafValues>
-7.0463657379150391e-01 5.2093976736068726e-01</leafValues></_>
<_>
<internalNodes>
0 -1 25 -66 -4116 1607291240 -5298489 -9847160 2011036101
357852669 1476259327</internalNodes>
<leafValues>
-8.2066470384597778e-01 4.9184983968734741e-01</leafValues></_></weakClassifiers></_>
<!-- stage 7 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.1098697185516357e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 44 -134217949 -167773185 -404750589 -1 -134744525
-1846018321 -2097357 -1</internalNodes>
<leafValues>
-7.6240319013595581e-01 6.8946647644042969e-01</leafValues></_>
<_>
<internalNodes>
0 -1 7 -12633797 -524321 1058880319 -129 -50790401 -262405
-1075052545 -5</internalNodes>
<leafValues>
-7.1431988477706909e-01 6.2125796079635620e-01</leafValues></_>
<_>
<internalNodes>
0 -1 24 -144703501 -10486797 -134217729 -136317057
-271646721 -174069583 -168952849 -1072726014</internalNodes>
<leafValues>
-6.5710061788558960e-01 6.1531358957290649e-01</leafValues></_>
<_>
<internalNodes>
0 -1 38 -134218774 -149487872 -33554433 -537927872 -69209089
-145228029 -2360849 -524449</internalNodes>
<leafValues>
-7.3570650815963745e-01 4.9681660532951355e-01</leafValues></_>
<_>
<internalNodes>
0 -1 5 -136380419 -8390657 -2228225 -196707 1565810157
2147048386 -268702725 2080373485</internalNodes>
<leafValues>
-7.2735637426376343e-01 5.2713739871978760e-01</leafValues></_></weakClassifiers></_>
<!-- stage 8 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-2.0547957420349121e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 13 -11141121 -44695553 -1 -11144193 -9217 -321
-335811841 -4216577</internalNodes>
<leafValues>
-7.3916637897491455e-01 6.7595410346984863e-01</leafValues></_>
<_>
<internalNodes>
0 -1 26 -369104657 -4194321 -1061429013 -67114529 -251662085
-138412033 3334395 -234882305</internalNodes>
<leafValues>
-6.9217604398727417e-01 5.4744583368301392e-01</leafValues></_>
<_>
<internalNodes>
0 -1 11 1373590751 1373632511 -262169 -33859589 -572533249
-572524625 -135266305 -32833</internalNodes>
<leafValues>
-7.1100026369094849e-01 5.3469187021255493e-01</leafValues></_>
<_>
<internalNodes>
0 -1 23 -3148053 -1054802 -1 -5 -7340125 -3689942 -74448917
-687087094</internalNodes>
<leafValues>
-5.6383520364761353e-01 6.3540917634963989e-01</leafValues></_>
<_>
<internalNodes>
0 -1 8 245501180 -1615197700 -46219265 -1075925028
-307580929 -373826 -1076187139 -1343746644</internalNodes>
<leafValues>
-5.8823972940444946e-01 6.1824375391006470e-01</leafValues></_></weakClassifiers></_>
<!-- stage 9 -->
<_>
<maxWeakCount>6</maxWeakCount>
<stageThreshold>-1.6300759315490723e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 42 -1 -4129 -8193 -135795737 -1 -6417 -1 -137887866</internalNodes>
<leafValues>
-7.7990013360977173e-01 6.1912822723388672e-01</leafValues></_>
<_>
<internalNodes>
0 -1 31 -12845643 -1934361103 -581837313 -1644167171
-1175537153 -1392516625 -1681655299 -1358963807</internalNodes>
<leafValues>
-7.1357387304306030e-01 5.6909996271133423e-01</leafValues></_>
<_>
<internalNodes>
0 -1 34 288428543 -34262659 1976906747 -42117703 858797567
-4965441 2008290292 -1146080848</internalNodes>
<leafValues>
-6.7784935235977173e-01 5.4983222484588623e-01</leafValues></_>
<_>
<internalNodes>
0 -1 22 -25297611 -100663553 -9830515 -570556417 -53741251
-36570627 -67437302 -12583252</internalNodes>
<leafValues>
-6.3567954301834106e-01 5.9044981002807617e-01</leafValues></_>
<_>
<internalNodes>
0 -1 46 -403706354 82769839 -446830048 -989858098 -8921600
1087893408 -100663520 -134217729</internalNodes>
<leafValues>
-7.0569902658462524e-01 5.4874616861343384e-01</leafValues></_>
<_>
<internalNodes>
0 -1 0 -965744853 -420544541 -8392718 -1569784218 -192940313
1744830335 -9 -1003227661</internalNodes>
<leafValues>
-5.7118493318557739e-01 6.4167028665542603e-01</leafValues></_></weakClassifiers></_>
<!-- stage 10 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-2.1370947360992432e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 40 -673196033 -2144789 287251423 -538968593 -1399068449
-73535505 -13631489 -526857</internalNodes>
<leafValues>
-7.2344118356704712e-01 6.8316829204559326e-01</leafValues></_>
<_>
<internalNodes>
0 -1 32 -214216429 -2112561 -445819937 1964790555 -17185861
-303183720 -357832229 -3148837</internalNodes>
<leafValues>
-7.1031409502029419e-01 5.4083776473999023e-01</leafValues></_>
<_>
<internalNodes>
0 -1 10 -9043969 -36118539 2147450623 -4194305 -2246657
-102721404 1073685759 -1366622208</internalNodes>
<leafValues>
-5.8772116899490356e-01 6.4753490686416626e-01</leafValues></_>
<_>
<internalNodes>
0 -1 35 1167938037 16237049 -1120535169 1029034397 9567155
-2001626128 -1146622977 -1142248004</internalNodes>
<leafValues>
-6.4004391431808472e-01 5.6415843963623047e-01</leafValues></_>
<_>
<internalNodes>
0 -1 21 -70126622 -134227061 -536243648 188013035
-1234960385 1416625375 -486868997 62913535</internalNodes>
<leafValues>
-8.8218396902084351e-01 4.1129270195960999e-01</leafValues></_></weakClassifiers></_></stages>
<features>
<_>
<rect>
0 1 1 6</rect></_>
<_>
<rect>
1 0 8 3</rect></_>
<_>
<rect>
1 4 8 3</rect></_>
<_>
<rect>
1 6 13 2</rect></_>
<_>
<rect>
2 1 5 2</rect></_>
<_>
<rect>
2 4 9 2</rect></_>
<_>
<rect>
3 2 5 2</rect></_>
<_>
<rect>
4 0 11 3</rect></_>
<_>
<rect>
4 21 9 1</rect></_>
<_>
<rect>
7 1 5 5</rect></_>
<_>
<rect>
7 7 6 2</rect></_>
<_>
<rect>
10 0 3 5</rect></_>
<_>
<rect>
11 1 9 3</rect></_>
<_>
<rect>
11 2 11 4</rect></_>
<_>
<rect>
12 0 4 3</rect></_>
<_>
<rect>
14 2 5 2</rect></_>
<_>
<rect>
14 6 3 3</rect></_>
<_>
<rect>
15 1 5 4</rect></_>
<_>
<rect>
16 0 9 4</rect></_>
<_>
<rect>
17 3 4 5</rect></_>
<_>
<rect>
17 6 4 3</rect></_>
<_>
<rect>
18 12 3 2</rect></_>
<_>
<rect>
19 0 3 3</rect></_>
<_>
<rect>
19 3 2 6</rect></_>
<_>
<rect>
19 4 2 4</rect></_>
<_>
<rect>
19 12 2 4</rect></_>
<_>
<rect>
21 2 2 5</rect></_>
<_>
<rect>
22 5 3 4</rect></_>
<_>
<rect>
22 14 3 3</rect></_>
<_>
<rect>
24 1 6 5</rect></_>
<_>
<rect>
25 3 4 5</rect></_>
<_>
<rect>
25 6 6 1</rect></_>
<_>
<rect>
26 1 2 5</rect></_>
<_>
<rect>
26 3 5 4</rect></_>
<_>
<rect>
26 21 6 1</rect></_>
<_>
<rect>
27 1 5 1</rect></_>
<_>
<rect>
29 3 4 6</rect></_>
<_>
<rect>
30 0 4 5</rect></_>
<_>
<rect>
30 2 3 7</rect></_>
<_>
<rect>
34 1 3 7</rect></_>
<_>
<rect>
34 8 3 2</rect></_>
<_>
<rect>
34 15 3 3</rect></_>
<_>
<rect>
35 3 2 5</rect></_>
<_>
<rect>
35 5 2 5</rect></_>
<_>
<rect>
39 12 1 3</rect></_>
<_>
<rect>
41 0 1 7</rect></_>
<_>
<rect>
41 10 1 4</rect></_>
<_>
<rect>
41 11 1 3</rect></_></features></cascade>
</opencv_storage>

BIN
Prj-Linux/lpr/model/mininet_ssd_v1.caffemodel View File


+ 1462
- 0
Prj-Linux/lpr/model/mininet_ssd_v1.prototxt
File diff suppressed because it is too large
View File


BIN
Prj-Linux/lpr/model/refinenet.caffemodel View File


+ 300
- 0
Prj-Linux/lpr/model/refinenet.prototxt View File

@@ -0,0 +1,300 @@
name: "ONet"
input: "data"
input_dim: 1
input_dim: 3
input_dim: 48
input_dim: 120

##################################
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
convolution_param {
num_output: 32
kernel_size: 3
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "prelu1"
type: "PReLU"
bottom: "conv1"
top: "conv1"
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
convolution_param {
num_output: 64
kernel_size: 3
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}

layer {
name: "prelu2"
type: "PReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}

layer {
name: "conv3"
type: "Convolution"
bottom: "pool2"
top: "conv3"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
convolution_param {
num_output: 64
kernel_size: 3
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "prelu3"
type: "PReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv4"
type: "Convolution"
bottom: "pool3"
top: "conv4"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
convolution_param {
num_output: 128
kernel_size: 2
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "prelu4"
type: "PReLU"
bottom: "conv4"
top: "conv4"
}


layer {
name: "conv5i"
type: "InnerProduct"
bottom: "conv4"
top: "conv5"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
inner_product_param {
#kernel_size: 3
num_output: 256
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}

layer {
name: "drop5i"
type: "Dropout"
bottom: "conv5"
top: "conv5"
dropout_param {
dropout_ratio: 0.25
}
}
layer {
name: "prelu5"
type: "PReLU"
bottom: "conv5"
top: "conv5"
}


layer {
name: "conv6i-1"
type: "InnerProduct"
bottom: "conv5"
top: "conv6-1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
inner_product_param {
#kernel_size: 1
num_output: 2
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}


layer {
name: "conv6i-2"
type: "InnerProduct"
bottom: "conv5"
top: "conv6-2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
inner_product_param {
#kernel_size: 1
num_output: 4
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}

layer {
name: "conv6-3"
type: "InnerProduct"
bottom: "conv5"
top: "conv6-3"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 1
}
inner_product_param {
#kernel_size: 1
num_output: 8
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0
}
}
}


layer {
name: "prob1"
type: "Softmax"
bottom: "conv6-1"
top: "prob1"
}

BIN
Prj-Linux/lpr/res/test.jpg View File

Before After
Width: 1280  |  Height: 720  |  Size: 188 kB

BIN
Prj-Linux/lpr/res/test_db1.jpg View File

Before After
Width: 2976  |  Height: 3968  |  Size: 3.3 MB

+ 0
- 19
Prj-Linux/lpr/src/CNNRecognizer.cpp View File

@@ -1,19 +0,0 @@
//
// Created by Jack Yu on 21/10/2017.
//

#include "../include/CNNRecognizer.h"

namespace pr{
CNNRecognizer::CNNRecognizer(std::string prototxt,std::string caffemodel){
net = cv::dnn::readNetFromCaffe(prototxt, caffemodel);
}

label CNNRecognizer::recognizeCharacter(cv::Mat charImage){
if(charImage.channels()== 3)
cv::cvtColor(charImage,charImage,cv::COLOR_BGR2GRAY);
cv::Mat inputBlob = cv::dnn::blobFromImage(charImage, 1/255.0, cv::Size(CHAR_INPUT_W,CHAR_INPUT_H), cv::Scalar(0,0,0),false);
net.setInput(inputBlob,"data");
return net.forward();
}
}

+ 0
- 108
Prj-Linux/lpr/src/FastDeskew.cpp View File

@@ -1,108 +0,0 @@
//
// Created by Jack Yu on 02/10/2017.
//



#include <../include/FastDeskew.h>

namespace pr{
const int ANGLE_MIN = 30 ;
const int ANGLE_MAX = 150 ;
const int PLATE_H = 36;
const int PLATE_W = 136;
int angle(float x,float y)
{
return atan2(x,y)*180/3.1415;
}

std::vector<float> avgfilter(std::vector<float> angle_list,int windowsSize) {
std::vector<float> angle_list_filtered(angle_list.size() - windowsSize + 1);
for (int i = 0; i < angle_list.size() - windowsSize + 1; i++) {
float avg = 0.00f;
for (int j = 0; j < windowsSize; j++) {
avg += angle_list[i + j];
}
avg = avg / windowsSize;
angle_list_filtered[i] = avg;
}

return angle_list_filtered;
}


void drawHist(std::vector<float> seq){
cv::Mat image(300,seq.size(),CV_8U);
image.setTo(0);

for(int i = 0;i<seq.size();i++)
{
float l = *std::max_element(seq.begin(),seq.end());

int p = int(float(seq[i])/l*300);

cv::line(image,cv::Point(i,300),cv::Point(i,300-p),cv::Scalar(255,255,255));
}
cv::imshow("vis",image);
}

cv::Mat correctPlateImage(cv::Mat skewPlate,float angle,float maxAngle)
{
cv::Mat dst;
cv::Size size_o(skewPlate.cols,skewPlate.rows);
int extend_padding = 0;
extend_padding = static_cast<int>(skewPlate.rows*tan(cv::abs(angle)/180* 3.14) );
cv::Size size(skewPlate.cols + extend_padding ,skewPlate.rows);
float interval = abs(sin((angle /180) * 3.14)* skewPlate.rows);
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) {
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::Mat M = cv::getPerspectiveTransform(pts1,pts2);
cv::warpPerspective(skewPlate,dst,M,size);
}
else {
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::Mat M = cv::getPerspectiveTransform(pts1,pts2);
cv::warpPerspective(skewPlate,dst,M,size,cv::INTER_CUBIC);
}
return dst;
}
cv::Mat fastdeskew(cv::Mat skewImage,int blockSize){
const int FILTER_WINDOWS_SIZE = 5;
std::vector<float> angle_list(180);
memset(angle_list.data(),0,angle_list.size()*sizeof(int));
cv::Mat bak;
skewImage.copyTo(bak);
if(skewImage.channels() == 3)
cv::cvtColor(skewImage,skewImage,cv::COLOR_RGB2GRAY);
if(skewImage.channels() == 1)
{
cv::Mat eigen;
cv::cornerEigenValsAndVecs(skewImage,eigen,blockSize,5);
for( int j = 0; j < skewImage.rows; j+=blockSize )
{ for( int i = 0; i < skewImage.cols; i+=blockSize )
{
float x2 = eigen.at<cv::Vec6f>(j, i)[4];
float y2 = eigen.at<cv::Vec6f>(j, i)[5];
int angle_cell = angle(x2,y2);
angle_list[(angle_cell + 180)%180]+=1.0;
}
}
}
std::vector<float> filtered = avgfilter(angle_list,5);
int maxPos = std::max_element(filtered.begin(),filtered.end()) - filtered.begin() + FILTER_WINDOWS_SIZE/2;
if(maxPos>ANGLE_MAX)
maxPos = (-maxPos+90+180)%180;
if(maxPos<ANGLE_MIN)
maxPos-=90;
maxPos=90-maxPos;
cv::Mat deskewed = correctPlateImage(bak, static_cast<float>(maxPos),60.0f);
return deskewed;
}



}//namespace pr

+ 0
- 163
Prj-Linux/lpr/src/FineMapping.cpp View File

@@ -1,163 +0,0 @@
#include "FineMapping.h"
namespace pr{
const int FINEMAPPING_H = 60 ;
const int FINEMAPPING_W = 140;
const int PADDING_UP_DOWN = 30;
void drawRect(cv::Mat image,cv::Rect rect)
{
cv::Point p1(rect.x,rect.y);
cv::Point p2(rect.x+rect.width,rect.y+rect.height);
cv::rectangle(image,p1,p2,cv::Scalar(0,255,0),1);
}


FineMapping::FineMapping(std::string prototxt,std::string caffemodel) {
net = cv::dnn::readNetFromCaffe(prototxt, caffemodel);
}

cv::Mat FineMapping::FineMappingHorizon(cv::Mat FinedVertical,int leftPadding,int rightPadding)
{
cv::Mat inputBlob = cv::dnn::blobFromImage(FinedVertical, 1/255.0, cv::Size(66,16),
cv::Scalar(0,0,0),false);
net.setInput(inputBlob,"data");
cv::Mat prob = net.forward();
int front = static_cast<int>(prob.at<float>(0,0)*FinedVertical.cols);
int back = static_cast<int>(prob.at<float>(0,1)*FinedVertical.cols);
front -= leftPadding ;
if(front<0) front = 0;
back +=rightPadding;
if(back>FinedVertical.cols-1) back=FinedVertical.cols - 1;
cv::Mat cropped = FinedVertical.colRange(front,back).clone();
return cropped;
}

std::pair<int,int> FitLineRansac(std::vector<cv::Point> pts,int zeroadd = 0 )
{
std::pair<int,int> res;
if(pts.size()>2)
{
cv::Vec4f line;
cv::fitLine(pts,line,cv::DIST_HUBER,0,0.01,0.01);
float vx = line[0];
float vy = line[1];
float x = line[2];
float y = line[3];
int lefty = static_cast<int>((-x * vy / vx) + y);
int righty = static_cast<int>(((136- x) * vy / vx) + y);
res.first = lefty+PADDING_UP_DOWN+zeroadd;
res.second = righty+PADDING_UP_DOWN+zeroadd;
return res;
}
res.first = zeroadd;
res.second = zeroadd;
return res;
}

cv::Mat FineMapping::FineMappingVertical(cv::Mat InputProposal,int sliceNum,int upper,int lower,int windows_size){
cv::Mat PreInputProposal;
cv::Mat proposal;
cv::resize(InputProposal,PreInputProposal,cv::Size(FINEMAPPING_W,FINEMAPPING_H));
if(InputProposal.channels() == 3)
cv::cvtColor(PreInputProposal,proposal,cv::COLOR_BGR2GRAY);
else
PreInputProposal.copyTo(proposal);
// this will improve some sen
cv::Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(1,3));
float diff = static_cast<float>(upper-lower);
diff/=static_cast<float>(sliceNum-1);
cv::Mat binary_adaptive;
std::vector<cv::Point> line_upper;
std::vector<cv::Point> line_lower;
int contours_nums=0;
for(int i = 0 ; i < sliceNum ; i++)
{
std::vector<std::vector<cv::Point> > contours;
float k =lower + i*diff;
cv::adaptiveThreshold(proposal,binary_adaptive,255,cv::ADAPTIVE_THRESH_MEAN_C,cv::THRESH_BINARY,windows_size,k);
cv::Mat draw;
binary_adaptive.copyTo(draw);
cv::findContours(binary_adaptive,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
for(auto contour: contours)
{
cv::Rect bdbox =cv::boundingRect(contour);
float lwRatio = bdbox.height/static_cast<float>(bdbox.width);
int bdboxAera = bdbox.width*bdbox.height;
if (( lwRatio>0.7&&bdbox.width*bdbox.height>100 && bdboxAera<300)
|| (lwRatio>3.0 && bdboxAera<100 && bdboxAera>10))
{
cv::Point p1(bdbox.x, bdbox.y);
cv::Point p2(bdbox.x + bdbox.width, bdbox.y + bdbox.height);
line_upper.push_back(p1);
line_lower.push_back(p2);
contours_nums+=1;
}
}
}
if(contours_nums<41)
{
cv::bitwise_not(InputProposal,InputProposal);
cv::Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(1,5));
cv::Mat bak;
cv::resize(InputProposal,bak,cv::Size(FINEMAPPING_W,FINEMAPPING_H));
cv::erode(bak,bak,kernal);
if(InputProposal.channels() == 3)
cv::cvtColor(bak,proposal,cv::COLOR_BGR2GRAY);
else
proposal = bak;
int contours_nums=0;
for(int i = 0 ; i < sliceNum ; i++)
{
std::vector<std::vector<cv::Point> > contours;
float k =lower + i*diff;
cv::adaptiveThreshold(proposal,binary_adaptive,255,cv::ADAPTIVE_THRESH_MEAN_C,cv::THRESH_BINARY,windows_size,k);
cv::Mat draw;
binary_adaptive.copyTo(draw);
cv::findContours(binary_adaptive,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
for(auto contour: contours)
{
cv::Rect bdbox =cv::boundingRect(contour);
float lwRatio = bdbox.height/static_cast<float>(bdbox.width);
int bdboxAera = bdbox.width*bdbox.height;
if (( lwRatio>0.7&&bdbox.width*bdbox.height>120 && bdboxAera<300)
|| (lwRatio>3.0 && bdboxAera<100 && bdboxAera>10))
{

cv::Point p1(bdbox.x, bdbox.y);
cv::Point p2(bdbox.x + bdbox.width, bdbox.y + bdbox.height);
line_upper.push_back(p1);
line_lower.push_back(p2);
contours_nums+=1;
}
}
}
}
cv::Mat rgb;
cv::copyMakeBorder(PreInputProposal, rgb, PADDING_UP_DOWN, PADDING_UP_DOWN, 0, 0, cv::BORDER_REPLICATE);
std::pair<int, int> A;
std::pair<int, int> B;
A = FitLineRansac(line_upper, -1);
B = FitLineRansac(line_lower, 1);
int leftyB = A.first;
int rightyB = A.second;
int leftyA = B.first;
int rightyA = B.second;
int cols = rgb.cols;
int rows = rgb.rows;
std::vector<cv::Point2f> corners(4);
corners[0] = cv::Point2f(cols - 1, rightyA);
corners[1] = cv::Point2f(0, leftyA);
corners[2] = cv::Point2f(cols - 1, rightyB);
corners[3] = cv::Point2f(0, leftyB);
std::vector<cv::Point2f> corners_trans(4);
corners_trans[0] = cv::Point2f(136, 36);
corners_trans[1] = cv::Point2f(0, 36);
corners_trans[2] = cv::Point2f(136, 0);
corners_trans[3] = cv::Point2f(0, 0);
cv::Mat transform = cv::getPerspectiveTransform(corners, corners_trans);
cv::Mat quad = cv::Mat::zeros(36, 136, CV_8UC3);
cv::warpPerspective(rgb, quad, transform, quad.size());
return quad;
}
}



+ 67
- 0
Prj-Linux/lpr/src/FineTune.cpp View File

@@ -0,0 +1,67 @@
#include "../include/Finetune.h"
using namespace std;
using namespace cv;

namespace pr {
FineTune::FineTune(string finetune_prototxt, string finetune_caffemodel) {
FTNet = dnn::readNetFromCaffe(finetune_prototxt, finetune_caffemodel);
}
void FineTune::affine_crop(Mat src, vector<Point> pts, Mat &crop)
{
Point2f dst[4] = { Point2f(0,0),Point2f(160,0),Point2f(160,40),Point2f(0,40) };
Point2f srcpt[4] = { Point2f(pts[0]),Point2f(pts[1]) ,Point2f(pts[2]) ,Point2f(pts[3]) };
Mat _mat = getPerspectiveTransform(srcpt, dst);
warpPerspective(src, crop, _mat, Size(160, 40));
}
void FineTune::to_refine(Mat src, vector<Point>pts, Mat& crop)
{
float scale = 3.f;
int cx = 64; int cy = 24;
int cw = 64; int ch = 24;
int tx1 = cx - cw / 2;
int ty1 = cy - ch / 2;
int tx2 = cx + cw / 2;
int ty2 = cy - ch / 2;
int tx3 = cx + cw / 2;
int ty3 = cy + ch / 2;
int tx4 = cx - cw / 2;
int ty4 = cy + ch / 2;
vector<Point2f> dstp(4);
Point2f dst[4] = { (Point2f(tx1*scale, ty1*scale)) ,(Point2f(tx2*scale, ty2*scale)) ,(Point2f(tx3*scale, ty3*scale)) ,(Point2f(tx4*scale, ty4*scale)) };
Point2f pt[4] = { Point2f(pts[0]),Point2f(pts[1]) ,Point2f(pts[2]) ,Point2f(pts[3]) };
//estimater
Mat _mat = getPerspectiveTransform(pt, dst);
warpPerspective(src, crop, _mat, Size(120 * scale, 48 * scale));
}
void FineTune::Finetune(Mat src, Mat& dst)
{
Mat tof;// = src.clone();
resize(src, tof, Size(120, 48));
Mat blob = dnn::blobFromImage(tof, 0.0078125, Size(120, 48), Scalar(127.5, 127.5, 127.5), false, false);
FTNet.setInput(blob);
Mat outblob = FTNet.forward("conv6-3");

float *data = outblob.ptr<float>();
vector<Point> pts(4);
Mat fineMat(Size(2, 4), CV_32F, data);
for (int i = 0; i < fineMat.rows; i++)
{
pts[i].x = fineMat.at<float>(i, 0)*src.cols;
pts[i].y = fineMat.at<float>(i, 1)*src.rows;
}
Mat crop;
to_refine(src, pts, crop);
blob = dnn::blobFromImage(crop, 0.0078128, Size(120, 48), Scalar(127.5, 127.5, 127.5), false, false);
FTNet.setInput(blob);
outblob = FTNet.forward("conv6-3");
data = outblob.ptr<float>();
Mat fineMat2(Size(2, 4), CV_32F, data);
for (int i = 0; i < fineMat.rows; i++)
{
pts[i].x = fineMat2.at<float>(i, 0)*crop.cols;
pts[i].y = fineMat2.at<float>(i, 1)*crop.rows;
}
affine_crop(crop, pts, crop);
dst = crop.clone();
}
}

+ 64
- 68
Prj-Linux/lpr/src/Pipeline.cpp View File

@@ -1,74 +1,70 @@
//
// Created by Jack Yu on 23/10/2017.
//

#include "../include/Pipeline.h"


namespace pr {
PipelinePR::PipelinePR(std::string detect_prototxt, std::string detect_caffemodel,
std::string finetune_prototxt, std::string finetune_caffemodel,
std::string platerec_prototxt, std::string platerec_caffemodel,
std::string dbstring)
{
platedetection = new PlateDetection(detect_prototxt, detect_caffemodel);
finetune = new FineTune(finetune_prototxt, finetune_caffemodel);
platerecognation = new PlateRecognation(platerec_prototxt, platerec_caffemodel);
dbdetection = new DBDetection(dbstring);
}
PipelinePR::~PipelinePR()
{
delete platedetection;
delete finetune;
delete platerecognation;
delete dbdetection;
}
cv::Mat DBcropFromImage(const cv::Mat &image){
cv::Mat cropped;
image.copyTo(cropped);
int cropped_w = cropped.cols;
int cropped_h = cropped.rows;
cv::Rect up,down;
up.y = cropped_h*0.05;up.x = cropped_w*0.2;up.height = cropped_h*0.35;up.width = cropped_w*0.55;
down.y = cropped_h*0.4;down.x = cropped_w*0.05;down.height = cropped_h*0.6;down.width = cropped_w*0.95;
cv::Mat cropUp,cropDown;
cropped(up).copyTo(cropUp);
cropped(down).copyTo(cropDown);
cv::resize(cropUp,cropUp,cv::Size(64,40));
cv::resize(cropDown,cropDown,cv::Size(96,40));
cv::Mat crop = cv::Mat(40,160,CV_8UC3);
cropUp.copyTo(crop(cv::Rect(0,0,64,40)));
cropDown.copyTo(crop(cv::Rect(64,0,96,40)));
return crop;

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



std::vector<PlateInfo> PipelinePR::RunPiplineAsImage(cv::Mat plateimg,int IsDB)
{
std::vector<pr::PlateInfo> plates;
std::vector<PlateInfo> plateres;
if(IsDB==1)
{
dbdetection->DBDetect(plateimg,plates,30,1280);
}
else
{
platedetection->Detectssd(plateimg, plates);
}
for (pr::PlateInfo plateinfo : plates) {
cv::Mat image = plateinfo.getPlateImage();
cv::Mat CropImg;
if(IsDB==1)
{
CropImg = DBcropFromImage(image);
platerecognation->segmentation_free_recognation(CropImg, plateinfo);
}
else
{
finetune->Finetune(image, CropImg);
platerecognation->segmentation_free_recognation(CropImg, plateinfo);
}
plateres.push_back(plateinfo);
}
return plateres;
}
}

+ 85
- 16
Prj-Linux/lpr/src/PlateDetection.cpp View File

@@ -1,34 +1,103 @@
#include "../include/PlateDetection.h"
#include "util.h"
namespace pr{
PlateDetection::PlateDetection(std::string filename_cascade){
cascade.load(filename_cascade);
#include "../include/Platedetect.h"

};
void PlateDetection::plateDetectionRough(cv::Mat InputImage,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w){
cv::Mat processImage;
using namespace cv;
using namespace std;
namespace pr {

PlateDetection::PlateDetection(std::string ssd_prototxt, std::string ssd_caffemodel)
{
ssdNet = cv::dnn::readNetFromCaffe(ssd_prototxt, ssd_caffemodel);
}
DBDetection::DBDetection(std::string cascadestring)
{
dbcascade.load(cascadestring);
}
void PlateDetection::Detectssd(cv::Mat img, std::vector<pr::PlateInfo> &plateInfos)
{
int cols = img.cols;
int rows = img.rows;
Mat in;
img.convertTo(in, CV_32F);
Mat input(img.size(), CV_32FC3);
Mat inputblob1 = input.reshape(1, { 1, 3,rows,cols });
Mat input_blob = dnn::blobFromImages(in, 0.225, Size(), Scalar(103.53, 116.28, 123.675), false);
float *blobdata = input_blob.ptr<float>();
float *blobdata2 = inputblob1.ptr<float>();
{
for (int i = 0; i < rows; i++)
{
memcpy(blobdata2 + i * cols, blobdata + 3 * i * cols, cols * sizeof(float));
memcpy(blobdata2 + i * cols + rows * cols, blobdata + (1 + 3 * i) * cols, cols * sizeof(float));
memcpy(blobdata2 + i * cols + rows * cols * 2, blobdata + (2 + 3 * i) * cols, cols * sizeof(float));
}
}
ssdNet.setInput(inputblob1);

Mat outputBlob = ssdNet.forward("detection_out");

Mat detectmat(outputBlob.size[2], outputBlob.size[3], CV_32F, outputBlob.ptr<float>());
vector<Rect> recs;
vector<float>scs;
for (int i = 0; i < detectmat.rows; i++)
{
float confidence = detectmat.at<float>(i, 2);
if (confidence > 0.5)
{
int x1, x2, y1, y2;
Rect rec;
Mat cimg;
x1 = int(detectmat.at<float>(i, 3) * cols);
y1 = int(detectmat.at<float>(i, 4) * rows);
x2 = int(detectmat.at<float>(i, 5) * cols);
y2 = int(detectmat.at<float>(i, 6) * rows);
x1 = max(x1, 0);
y1 = max(y1, 0);
x2 = min(x2, cols - 1);
y2 = min(y2, rows - 1);
rec.x = x1; rec.y = y1; rec.width = (x2 - x1 + 1); rec.height = (y2 - y1 + 1);
img(rec).copyTo(cimg);
PlateInfo plateInfo(cimg, rec);
plateInfos.push_back(plateInfo);
}
}
}
cv::Mat cropFromImage(const cv::Mat &image,cv::Rect rect){
int w = image.cols-1;
int h = image.rows-1;
rect.x = std::max(rect.x,0);
rect.y = std::max(rect.y,0);
rect.height = std::min(rect.height,h-rect.y);
rect.width = std::min(rect.width,w-rect.x);
cv::Mat temp(rect.size(), image.type());
cv::Mat cropped;
temp = image(rect);
temp.copyTo(cropped);
return cropped;
}
void DBDetection::DBDetect(cv::Mat InputImage,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w)
{
cv::Mat processImage;
cv::cvtColor(InputImage,processImage,cv::COLOR_BGR2GRAY);
std::vector<cv::Rect> platesRegions;
cv::Size minSize(min_w,min_w/4);
cv::Size maxSize(max_w,max_w/4);
if (&processImage == NULL)
return;
cascade.detectMultiScale( processImage, platesRegions,
dbcascade.detectMultiScale( processImage, platesRegions,
1.1, 3, cv::CASCADE_SCALE_IMAGE,minSize,maxSize);
for(auto plate:platesRegions)
{
int zeroadd_w = static_cast<int>(plate.width*0.30);
int zeroadd_h = static_cast<int>(plate.height*2);
int zeroadd_x = static_cast<int>(plate.width*0.15);
int zeroadd_y = static_cast<int>(plate.height*1);
int zeroadd_w = static_cast<int>(plate.width*0.28);
int zeroadd_h = static_cast<int>(plate.height*0.35);
int zeroadd_x = static_cast<int>(plate.width*0.14);
int zeroadd_y = static_cast<int>(plate.height*0.15);
plate.x-=zeroadd_x;
plate.y-=zeroadd_y;
plate.height += zeroadd_h;
plate.width += zeroadd_w;
cv::Mat plateImage = util::cropFromImage(InputImage,plate);
cv::Mat plateImage = cropFromImage(InputImage,plate);
PlateInfo plateInfo(plateImage,plate);
plateInfos.push_back(plateInfo);

}
}
}//namespace pr
}

+ 61
- 0
Prj-Linux/lpr/src/PlateRecognation.cpp View File

@@ -0,0 +1,61 @@
#include "../include/PlateRecognation.h"
#include "../include/Pipeline.h"
using namespace std;
using namespace cv;
namespace pr {

PlateRecognation::PlateRecognation(std::string rec_prototxt, std::string rec_caffemodel)
{
RecNet = cv::dnn::readNetFromCaffe(rec_prototxt, rec_caffemodel);
}
void PlateRecognation::segmentation_free_recognation(cv::Mat src, pr::PlateInfo &plateinfo)
{
float score = 0;
string text = "";
Mat src1 = src.clone();
Mat inputMat(Size(40, 160), CV_8UC3);

for (int j = 0; j < src.rows; j++)
{
for (int i = 0; i < src.cols; i++)
{
inputMat.at<Vec3b>(i, j) = src1.at<Vec3b>(j, i);
}
}
Mat blob = dnn::blobFromImage(inputMat, 1 / 255.f, Size(40, 160), Scalar(0, 0, 0), false, false);
RecNet.setInput(blob);
Mat outblob = RecNet.forward();
int x = outblob.size[2];
int y = outblob.size[0];
float *data = outblob.ptr<float>();
vector<float> scores(84);
vector<int>maxidxs;
vector<float> maxscore;
for (int i = 2; i < 20; i++)
{
for (int j = 0; j < 84; j++)
{
scores[j] = data[j * 20 + i];
}
int idx = max_element(scores.begin(), scores.end()) - scores.begin();
maxidxs.push_back(idx);
maxscore.push_back(scores[idx]);
}
int charnum = 0;
for (int i = 0; i < maxidxs.size(); i++)
{
if (maxidxs[i] < pr::CH_PLATE_CODE.size() && (i == 0 || (maxidxs[i - 1] != maxidxs[i])))
{
text += pr::CH_PLATE_CODE[maxidxs[i]];
score += maxscore[i];
charnum++;
}
}
if (charnum > 0)
{
score /= charnum;
}
plateinfo.setPlateName(text);
plateinfo.confidence = score;
}
}

+ 0
- 404
Prj-Linux/lpr/src/PlateSegmentation.cpp View File

@@ -1,404 +0,0 @@
//
// Created by Jack Yu on 16/10/2017.
//

#include "../include/PlateSegmentation.h"
#include "../include/niBlackThreshold.h"


//#define DEBUG
namespace pr{

PlateSegmentation::PlateSegmentation(std::string prototxt,std::string caffemodel) {
net = cv::dnn::readNetFromCaffe(prototxt, caffemodel);
}
cv::Mat PlateSegmentation::classifyResponse(const cv::Mat &cropped){
cv::Mat inputBlob = cv::dnn::blobFromImage(cropped, 1/255.0, cv::Size(22,22), cv::Scalar(0,0,0),false);
net.setInput(inputBlob,"data");
return net.forward();
}

void drawHist(float* seq,int size,const char* name){
cv::Mat image(300,size,CV_8U);
image.setTo(0);
float* start =seq;
float* end = seq+size;
float l = *std::max_element(start,end);
for(int i = 0;i<size;i++)
{
int p = int(float(seq[i])/l*300);
cv::line(image,cv::Point(i,300),cv::Point(i,300-p),cv::Scalar(255,255,255));
}
cv::resize(image,image,cv::Size(600,100));
cv::imshow(name,image);
}

inline void computeSafeMargin(int &val,const int &rows){
val = std::min(val,rows);
val = std::max(val,0);
}

cv::Rect boxFromCenter(const cv::Point center,int left,int right,int top,int bottom,cv::Size bdSize)
{
cv::Point p1(center.x - left ,center.y - top);
cv::Point p2( center.x + right, center.y + bottom);
p1.x = std::max(0,p1.x);
p1.y = std::max(0,p1.y);
p2.x = std::min(p2.x,bdSize.width-1);
p2.y = std::min(p2.y,bdSize.height-1);
cv::Rect rect(p1,p2);
return rect;
}

cv::Rect boxPadding(cv::Rect rect,int left,int right,int top,int bottom,cv::Size bdSize)
{

cv::Point center(rect.x+(rect.width>>1),rect.y + (rect.height>>1));
int rebuildLeft = (rect.width>>1 )+ left;
int rebuildRight = (rect.width>>1 )+ right;
int rebuildTop = (rect.height>>1 )+ top;
int rebuildBottom = (rect.height>>1 )+ bottom;
return boxFromCenter(center,rebuildLeft,rebuildRight,rebuildTop,rebuildBottom,bdSize);

}



void PlateSegmentation:: refineRegion(cv::Mat &plateImage,const std::vector<int> &candidatePts,const int padding,std::vector<cv::Rect> &rects){
int w = candidatePts[5] - candidatePts[4];
int cols = plateImage.cols;
int rows = plateImage.rows;
for(int i = 0 ; i < candidatePts.size() ; i++)
{
int left = 0;
int right = 0 ;

if(i == 0 ){
left= candidatePts[i];
right = left+w+padding;
}
else {
left = candidatePts[i] - padding;
right = left + w + padding * 2;
}

computeSafeMargin(right,cols);
computeSafeMargin(left,cols);
cv::Rect roi(left,0,right - left,rows-1);
cv::Mat roiImage;
plateImage(roi).copyTo(roiImage);

if (i>=1)
{

cv::Mat roi_thres;
// cv::threshold(roiImage,roi_thres,0,255,cv::THRESH_OTSU|cv::THRESH_BINARY);

niBlackThreshold(roiImage,roi_thres,255,cv::THRESH_BINARY,15,0.27,BINARIZATION_NIBLACK);

std::vector<std::vector<cv::Point>> contours;
cv::findContours(roi_thres,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);
cv::Point boxCenter(roiImage.cols>>1,roiImage.rows>>1);

cv::Rect final_bdbox;
cv::Point final_center;
int final_dist = INT_MAX;


for(auto contour:contours)
{
cv::Rect bdbox = cv::boundingRect(contour);
cv::Point center(bdbox.x+(bdbox.width>>1),bdbox.y + (bdbox.height>>1));
int dist = (center.x - boxCenter.x)*(center.x - boxCenter.x);
if(dist<final_dist and bdbox.height > rows>>1)
{ final_dist =dist;
final_center = center;
final_bdbox = bdbox;
}
}

//rebuild box
if(final_bdbox.height/ static_cast<float>(final_bdbox.width) > 3.5 && final_bdbox.width*final_bdbox.height<10)
final_bdbox = boxFromCenter(final_center,8,8,(rows>>1)-3 , (rows>>1) - 2,roiImage.size());
else {
if(i == candidatePts.size()-1)
final_bdbox = boxPadding(final_bdbox, padding/2, padding, padding/2, padding/2, roiImage.size());
else
final_bdbox = boxPadding(final_bdbox, padding, padding, padding, padding, roiImage.size());


// std::cout<<final_bdbox<<std::endl;
// std::cout<<roiImage.size()<<std::endl;
#ifdef DEBUG
cv::imshow("char_thres",roi_thres);

cv::imshow("char",roiImage(final_bdbox));
cv::waitKey(0);
#endif


}


final_bdbox.x += left;

rects.push_back(final_bdbox);
//

}
else
{
rects.push_back(roi);
}

// else
// {
//
// }

// cv::GaussianBlur(roiImage,roiImage,cv::Size(7,7),3);
//
// cv::imshow("image",roiImage);
// cv::waitKey(0);


}



}
void avgfilter(float *angle_list,int size,int windowsSize) {
float *filterd = new float[size];
for(int i = 0 ; i < size ; i++) filterd [i] = angle_list[i];
// memcpy(filterd,angle_list,size);

cv::Mat kernal_gaussian = cv::getGaussianKernel(windowsSize,3,CV_32F);
float *kernal = (float*)kernal_gaussian.data;
// kernal+=windowsSize;
int r = windowsSize/2;




for (int i = 0; i < size; i++) {
float avg = 0.00f;
for (int j = 0; j < windowsSize; j++) {
if(i+j-r>0&&i+j+r<size-1)
avg += filterd[i + j-r]*kernal[j];
}
// avg = avg / windowsSize;
angle_list[i] = avg;

}

delete filterd;
}

void PlateSegmentation::templateMatchFinding(const cv::Mat &respones,int windowsWidth,std::pair<float,std::vector<int>> &candidatePts){
int rows = respones.rows;
int cols = respones.cols;



float *data = (float*)respones.data;
float *engNum_prob = data;
float *false_prob = data+cols;
float *ch_prob = data+cols*2;

avgfilter(engNum_prob,cols,5);
avgfilter(false_prob,cols,5);
// avgfilter(ch_prob,cols,5);
std::vector<int> candidate_pts(7);
#ifdef DEBUG
drawHist(engNum_prob,cols,"engNum_prob");
drawHist(false_prob,cols,"false_prob");
drawHist(ch_prob,cols,"ch_prob");
cv::waitKey(0);
#endif




int cp_list[7];
float loss_selected = -10;

for(int start = 0 ; start < 20 ; start+=2)
for(int width = windowsWidth-5; width < windowsWidth+5 ; width++ ){
for(int interval = windowsWidth/2; interval < windowsWidth; interval++)
{
int cp1_ch = start;
int cp2_p0 = cp1_ch+ width;
int cp3_p1 = cp2_p0+ width + interval;
int cp4_p2 = cp3_p1 + width;
int cp5_p3 = cp4_p2 + width+1;
int cp6_p4 = cp5_p3 + width+2;
int cp7_p5= cp6_p4+ width+2;

int md1 = (cp1_ch+cp2_p0)>>1;
int md2 = (cp2_p0+cp3_p1)>>1;
int md3 = (cp3_p1+cp4_p2)>>1;
int md4 = (cp4_p2+cp5_p3)>>1;
int md5 = (cp5_p3+cp6_p4)>>1;
int md6 = (cp6_p4+cp7_p5)>>1;




if(cp7_p5>=cols)
continue;
// 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]
// + (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]);

if(loss>loss_selected)
{
loss_selected = loss;
cp_list[0]= cp1_ch;
cp_list[1]= cp2_p0;
cp_list[2]= cp3_p1;
cp_list[3]= cp4_p2;
cp_list[4]= cp5_p3;
cp_list[5]= cp6_p4;
cp_list[6]= cp7_p5;
}
}
}
candidate_pts[0] = cp_list[0];
candidate_pts[1] = cp_list[1];
candidate_pts[2] = cp_list[2];
candidate_pts[3] = cp_list[3];
candidate_pts[4] = cp_list[4];
candidate_pts[5] = cp_list[5];
candidate_pts[6] = cp_list[6];

candidatePts.first = loss_selected;
candidatePts.second = candidate_pts;

};


void PlateSegmentation::segmentPlateBySlidingWindows(cv::Mat &plateImage,int windowsWidth,int stride,cv::Mat &respones){


// cv::resize(plateImage,plateImage,cv::Size(136,36));

cv::Mat plateImageGray;
cv::cvtColor(plateImage,plateImageGray,cv::COLOR_BGR2GRAY);
int padding = plateImage.cols-136 ;
// int padding = 0 ;
int height = plateImage.rows - 1;
int width = plateImage.cols - 1 - padding;
for(int i = 0 ; i < width - windowsWidth +1 ; i +=stride)
{
cv::Rect roi(i,0,windowsWidth,height);
cv::Mat roiImage = plateImageGray(roi);
cv::Mat response = classifyResponse(roiImage);
respones.push_back(response);
}




respones = respones.t();
// std::pair<float,std::vector<int>> images ;
//
//
// std::cout<<images.first<<" ";
// for(int i = 0 ; i < images.second.size() ; i++)
// {
// std::cout<<images.second[i]<<" ";
//// cv::line(plateImageGray,cv::Point(images.second[i],0),cv::Point(images.second[i],36),cv::Scalar(255,255,255),1); //DEBUG
// }

// int w = images.second[5] - images.second[4];

// cv::line(plateImageGray,cv::Point(images.second[5]+w,0),cv::Point(images.second[5]+w,36),cv::Scalar(255,255,255),1); //DEBUG
// cv::line(plateImageGray,cv::Point(images.second[5]+2*w,0),cv::Point(images.second[5]+2*w,36),cv::Scalar(255,255,255),1); //DEBUG


// RefineRegion(plateImageGray,images.second,5);

// std::cout<<w<<std::endl;

// std::cout<<<<std::endl;

// cv::resize(plateImageGray,plateImageGray,cv::Size(600,100));



}

// void filterGaussian(cv::Mat &respones,float sigma){
//
// }


void PlateSegmentation::segmentPlatePipline(PlateInfo &plateInfo,int stride,std::vector<cv::Rect> &Char_rects){
cv::Mat plateImage = plateInfo.getPlateImage(); // get src image .
cv::Mat plateImageGray;
cv::cvtColor(plateImage,plateImageGray,cv::COLOR_BGR2GRAY);
//do binarzation
//
std::pair<float,std::vector<int>> sections ; // segment points variables .

cv::Mat respones; //three response of every sub region from origin image .
segmentPlateBySlidingWindows(plateImage,DEFAULT_WIDTH,1,respones);
templateMatchFinding(respones,DEFAULT_WIDTH/stride,sections);
for(int i = 0; i < sections.second.size() ; i++)
{
sections.second[i]*=stride;

}

// std::cout<<sections<<std::endl;

refineRegion(plateImageGray,sections.second,5,Char_rects);
#ifdef DEBUG
for(int i = 0 ; i < sections.second.size() ; i++)
{
std::cout<<sections.second[i]<<" ";
cv::line(plateImageGray,cv::Point(sections.second[i],0),cv::Point(sections.second[i],36),cv::Scalar(255,255,255),1); //DEBUG
}
cv::imshow("plate",plateImageGray);
cv::waitKey(0);
#endif
// cv::waitKey(0);

}

void PlateSegmentation::ExtractRegions(PlateInfo &plateInfo,std::vector<cv::Rect> &rects){
cv::Mat plateImage = plateInfo.getPlateImage();
for(int i = 0 ; i < rects.size() ; i++){
cv::Mat charImage;
plateImage(rects[i]).copyTo(charImage);
if(charImage.channels())
cv::cvtColor(charImage,charImage,cv::COLOR_BGR2GRAY);
// cv::imshow("image",charImage);
// cv::waitKey(0);
cv::equalizeHist(charImage,charImage);
//

//


std::pair<CharType,cv::Mat> char_instance;
if(i == 0 ){

char_instance.first = CHINESE;


} else if(i == 1){
char_instance.first = LETTER;
}
else{
char_instance.first = LETTER_NUMS;
}
char_instance.second = charImage;
plateInfo.appendPlateChar(char_instance);

}

}

}//namespace pr

+ 0
- 23
Prj-Linux/lpr/src/Recognizer.cpp View File

@@ -1,23 +0,0 @@
//
// Created by Jack Yu on 22/10/2017.
//

#include "../include/Recognizer.h"

namespace pr{
void GeneralRecognizer::SegmentBasedSequenceRecognition(PlateInfo &plateinfo){
for(auto char_instance:plateinfo.plateChars)
{
std::pair<CharType,cv::Mat> res;
if(char_instance.second.rows*char_instance.second.cols>40) {
label code_table = recognizeCharacter(char_instance.second);
res.first = char_instance.first;
code_table.copyTo(res.second);
plateinfo.appendPlateCoding(res);
} else{
res.first = INVALID;
plateinfo.appendPlateCoding(res);
}
}
}
}

+ 0
- 89
Prj-Linux/lpr/src/SegmentationFreeRecognizer.cpp View File

@@ -1,89 +0,0 @@
//
// 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);
}
}

+ 0
- 67
Prj-Linux/lpr/src/util.h View File

@@ -1,67 +0,0 @@
//
// Created by Jack Yu on 04/04/2017.
//

#include <opencv2/opencv.hpp>
namespace util{
template <class T> void swap ( T& a, T& b )
{
T c(a); a=b; b=c;
}
template <class T> T min(T& a,T& b )
{
return a>b?b:a;
}

cv::Mat cropFromImage(const cv::Mat &image,cv::Rect rect){
int w = image.cols-1;
int h = image.rows-1;
rect.x = std::max(rect.x,0);
rect.y = std::max(rect.y,0);
rect.height = std::min(rect.height,h-rect.y);
rect.width = std::min(rect.width,w-rect.x);
cv::Mat temp(rect.size(), image.type());
cv::Mat cropped;
temp = image(rect);
temp.copyTo(cropped);
return cropped;

}

cv::Mat cropBox2dFromImage(const cv::Mat &image,cv::RotatedRect rect)
{
cv::Mat M, rotated, cropped;
float angle = rect.angle;
cv::Size rect_size(rect.size.width,rect.size.height);
if (rect.angle < -45.) {
angle += 90.0;
swap(rect_size.width, rect_size.height);
}
M = cv::getRotationMatrix2D(rect.center, angle, 1.0);
cv::warpAffine(image, rotated, M, image.size(), cv::INTER_CUBIC);
cv::getRectSubPix(rotated, rect_size, rect.center, cropped);
return cropped;
}

cv::Mat calcHist(const cv::Mat &image)
{
cv::Mat hsv;
std::vector<cv::Mat> hsv_planes;
cv::cvtColor(image,hsv,cv::COLOR_BGR2HSV);
cv::split(hsv,hsv_planes);
cv::Mat hist;
int histSize = 256;
float range[] = {0,255};
const float* histRange = {range};
cv::calcHist( &hsv_planes[0], 1, 0, cv::Mat(), hist, 1, &histSize, &histRange,true, true);
return hist;
}
float computeSimilir(const cv::Mat &A,const cv::Mat &B)
{
cv::Mat histA,histB;
histA = calcHist(A);
histB = calcHist(B);
return cv::compareHist(histA,histB,CV_COMP_CORREL);
}
}//namespace util

+ 28
- 0
Prj-Linux/lpr/tests/testPipeLine.cpp View File

@@ -0,0 +1,28 @@
#include"../include/Pipeline.h"

void TEST_PIPELINE()
{
pr::PipelinePR prc("../lpr/model/mininet_ssd_v1.prototxt", "../lpr/model/mininet_ssd_v1.caffemodel",
"../lpr/model/refinenet.prototxt", "../lpr/model/refinenet.caffemodel",
"../lpr/model/SegmenationFree-Inception.prototxt", "../lpr/model/SegmenationFree-Inception.caffemodel",
"../lpr/model/cascade_double.xml");
cv::Mat img = cv::imread("../lpr//res//test.jpg");
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(img,0);
for (auto st : res) {
if (st.confidence > 0.75) {
std::cout << st.getPlateName() << " " << st.confidence << std::endl;
cv::Rect region = st.getPlateRect();

cv::rectangle(img, 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", img);
//cv::waitKey(0);

}
int main()
{
TEST_PIPELINE();
return 0;
}

+ 0
- 32
Prj-Linux/lpr/tests/test_detection.cpp View File

@@ -1,32 +0,0 @@
//
// Created by 庾金科 on 20/09/2017.
//

#include <../include/PlateDetection.h>


void drawRect(cv::Mat image,cv::Rect rect)
{
cv::Point p1(rect.x,rect.y);
cv::Point p2(rect.x+rect.width,rect.y+rect.height);
cv::rectangle(image,p1,p2,cv::Scalar(0,255,0),1);
}


int main()
{
cv::Mat image = cv::imread("res/test1.jpg");
pr::PlateDetection plateDetection("model/cascade.xml");
std::vector<pr::PlateInfo> plates;
plateDetection.plateDetectionRough(image,plates);
for(pr::PlateInfo platex:plates)
{
drawRect(image,platex.getPlateRect());
cv::imwrite("res/cache/test.png",platex.getPlateImage());
cv::imshow("image",platex.getPlateImage());
cv::waitKey(0);
}
cv::imshow("image",image);
cv::waitKey(0);
return 0 ;
}

+ 0
- 34
Prj-Linux/lpr/tests/test_fastdeskew.cpp View File

@@ -1,34 +0,0 @@
//
// Created by Jack Yu on 02/10/2017.
//


#include <../include/FastDeskew.h>


void drawRect(cv::Mat image,cv::Rect rect)
{
cv::Point p1(rect.x,rect.y);
cv::Point p2(rect.x+rect.width,rect.y+rect.height);
cv::rectangle(image,p1,p2,cv::Scalar(0,255,0),1);
}
void TEST_DESKEW(){

cv::Mat image = cv::imread("res/3.png",cv::IMREAD_GRAYSCALE);
// cv::resize(image,image,cv::Size(136*2,36*2));
cv::Mat deskewed = pr::fastdeskew(image,12);
// cv::imwrite("./res/4.png",deskewed);
// cv::Mat deskewed2 = pr::fastdeskew(deskewed,12);
//
cv::imshow("image",deskewed);
cv::waitKey(0);

}
int main()
{

TEST_DESKEW();
return 0 ;


}

+ 0
- 25
Prj-Linux/lpr/tests/test_finemapping.cpp View File

@@ -1,25 +0,0 @@
//
// Created by Jack Yu on 24/09/2017.
//

#include "FineMapping.h"






int main()
{
cv::Mat image = cv::imread("res/cache/test.png");
cv::Mat image_finemapping = pr::FineMapping::FineMappingVertical(image);
pr::FineMapping finemapper = pr::FineMapping("model/HorizonalFinemapping.prototxt","model/HorizonalFinemapping.caffemodel");
image_finemapping = finemapper.FineMappingHorizon(image_finemapping,0,-3);
cv::imwrite("res/cache/finemappingres.png",image_finemapping);
cv::imshow("image",image_finemapping);
cv::waitKey(0);


return 0 ;

}

+ 0
- 179
Prj-Linux/lpr/tests/test_pipeline.cpp View File

@@ -1,179 +0,0 @@
//
// Created by Jack Yu on 23/10/2017.
//

#include "../include/Pipeline.h"




using namespace std;

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_ACC(){

pr::PipelinePR prc("model/cascade.xml",
"model/HorizonalFinemapping.prototxt","model/HorizonalFinemapping.caffemodel",
"model/Segmentation.prototxt","model/Segmentation.caffemodel",
"model/CharacterRecognization.prototxt","model/CharacterRecognization.caffemodel",
"model/SegmenationFree-Inception.prototxt","model/SegmenationFree-Inception.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;

}


void TEST_PIPELINE(){

pr::PipelinePR prc("model/cascade.xml",
"model/HorizonalFinemapping.prototxt","model/HorizonalFinemapping.caffemodel",
"model/Segmentation.prototxt","model/Segmentation.caffemodel",
"model/CharacterRecognization.prototxt","model/CharacterRecognization.caffemodel",
"model/SegmenationFree-Inception.prototxt","model/SegmenationFree-Inception.caffemodel"
);

cv::Mat image = cv::imread("/Users/yujinke/ClionProjects/cpp_ocr_demo/test.png");


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()
{
cv::VideoCapture capture("test1.mp4");
cv::Mat frame;
pr::PipelinePR prc("model/cascade.xml",
"model/HorizonalFinemapping.prototxt","model/HorizonalFinemapping.caffemodel",
"model/Segmentation.prototxt","model/Segmentation.caffemodel",
"model/CharacterRecognization.prototxt","model/CharacterRecognization.caffemodel",
"model/SegmenationFree-Inception.prototxt","model/SegmenationFree-Inception.caffemodel"
);
while(1) {
//读取下一帧
if (!capture.read(frame)) {
std::cout << "读取视频失败" << std::endl;
exit(1);
}
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 ;


}

+ 0
- 54
Prj-Linux/lpr/tests/test_recognization.cpp View File

@@ -1,54 +0,0 @@
//
// Created by Jack Yu on 23/10/2017.
//

#include "../include/CNNRecognizer.h"

std::vector<std::string> chars{"京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖","闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","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"};

#include <opencv2/dnn.hpp>
using namespace cv::dnn;


void getMaxClass(cv::Mat &probBlob, int *classId, double *classProb)
{
// cv::Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix
cv::Point classNumber;

cv::minMaxLoc(probBlob, NULL, classProb, NULL, &classNumber);

*classId = classNumber.x;
}

void TEST_RECOGNIZATION(){
// pr::CNNRecognizer instance("model/CharacterRecognization.prototxt","model/CharacterRecognization.caffemodel");
Net net = cv::dnn::readNetFromCaffe("model/CharacterRecognization.prototxt","model/CharacterRecognization.caffemodel");
cv::Mat image = cv::imread("res/char1.png",cv::IMREAD_GRAYSCALE);
cv::resize(image,image,cv::Size(14,30));
cv::equalizeHist(image,image);
cv::Mat inputBlob = cv::dnn::blobFromImage(image, 1/255.0, cv::Size(14,30), false);

net.setInput(inputBlob,"data");

cv::Mat res = net.forward();
std::cout<<res<<std::endl;
float *p = (float*)res.data;
int maxid= 0;
double prob = 0;

getMaxClass(res,&maxid,&prob);



std::cout<<chars[maxid]<<std::endl;





};
int main()
{TEST_RECOGNIZATION();


}

+ 0
- 43
Prj-Linux/lpr/tests/test_segmentation.cpp View File

@@ -1,43 +0,0 @@
//
// Created by Jack Yu on 16/10/2017.
//


#include "../include/PlateSegmentation.h"
#include "../include/CNNRecognizer.h"
#include "../include/Recognizer.h"


std::vector<std::string> chars{"京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖","闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","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"};


void TEST_SLIDINGWINDOWS_EVAL(){
cv::Mat demo = cv::imread("res/cache/finemappingres.png");
cv::resize(demo,demo,cv::Size(136,36));

cv::Mat respones;
pr::PlateSegmentation plateSegmentation("model/Segmentation.prototxt","model/Segmentation.caffemodel");
pr::PlateInfo plate;
plate.setPlateImage(demo);
std::vector<cv::Rect> rects;
plateSegmentation.segmentPlatePipline(plate,1,rects);
plateSegmentation.ExtractRegions(plate,rects);

pr::GeneralRecognizer *recognizer = new pr::CNNRecognizer("model/CharacterRecognization.prototxt","model/CharacterRecognization.caffemodel");
recognizer->SegmentBasedSequenceRecognition(plate);
std::cout<<plate.decodePlateNormal(chars)<<std::endl;


delete(recognizer);





}
int main(){

TEST_SLIDINGWINDOWS_EVAL();

return 0;
}

+ 0
- 54
Prj-Linux/lpr/tests/test_segmentationFree.cpp View File

@@ -1,54 +0,0 @@
//
// 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;

}

+ 4
- 4
Prj-Win/lpr/include/Pipeline.h View File

@@ -22,18 +22,18 @@ namespace pr
PlateDetection *platedetection;
FineTune *finetune;
PlateRecognation *platerecognation;
//PlateColorClass *platecolorclass;
DBDetection *dbdetection;


PipelinePR(std::string detect_prototxt, std::string detect_caffemodel,
std::string finetune_prototxt, std::string finetune_caffemodel,
std::string platerec_prototxt, std::string platerec_caffemodel/*,
std::string platecolor_mnn*/);
std::string platerec_prototxt, std::string platerec_caffemodel,
std::string dbstring);
~PipelinePR();

std::vector<std::string> plateRes;
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat srcImage);
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat srcImage,int IsDB);

};
}

+ 7
- 0
Prj-Win/lpr/include/Platedetect.h View File

@@ -12,5 +12,12 @@ namespace pr
private:
cv::dnn::Net ssdNet;
};
class DBDetection{
public:
DBDetection(std::string cascadestring);
void DBDetect(cv::Mat inputImg,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w);
private:
cv::CascadeClassifier dbcascade;
};
}//namespace pr
#endif // !_PLATEDETECT_H_

+ 504
- 0
Prj-Win/lpr/model/cascade_double.xml View File

@@ -0,0 +1,504 @@
<?xml version="1.0"?>
<opencv_storage>
<cascade>
<stageType>BOOST</stageType>
<featureType>LBP</featureType>
<height>24</height>
<width>44</width>
<stageParams>
<boostType>GAB</boostType>
<minHitRate>9.9599999189376831e-01</minHitRate>
<maxFalseAlarm>5.0000000000000000e-01</maxFalseAlarm>
<weightTrimRate>9.4999999999999996e-01</weightTrimRate>
<maxDepth>1</maxDepth>
<maxWeakCount>28</maxWeakCount></stageParams>
<featureParams>
<maxCatCount>256</maxCatCount>
<featSize>1</featSize></featureParams>
<stageNum>11</stageNum>
<stages>
<!-- stage 0 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-1.1049392223358154e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 17 -3334 -513 -573452048 -1057 -1 -267777 -1 -1025</internalNodes>
<leafValues>
-9.4297146797180176e-01 7.8370976448059082e-01</leafValues></_>
<_>
<internalNodes>
0 -1 36 -262198 -12062208 -169869377 -674954752 -7602177
-16781941 -67109937 -1073</internalNodes>
<leafValues>
-8.8537323474884033e-01 7.2940820455551147e-01</leafValues></_>
<_>
<internalNodes>
0 -1 9 1431697887 1431687647 -545270049 -262145 1413609965
1364250775 -1065985 -67108865</internalNodes>
<leafValues>
-8.3008646965026855e-01 7.2340542078018188e-01</leafValues></_></weakClassifiers></_>
<!-- stage 1 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-1.0404651165008545e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 19 -524289 -136314913 1360393719 -2097153 -134219777
-4194817 274068735 -1</internalNodes>
<leafValues>
-8.5476654767990112e-01 8.4671354293823242e-01</leafValues></_>
<_>
<internalNodes>
0 -1 29 -16515073 -150929664 -1 -8650881 -8388609 -11403265
-1 -2097153</internalNodes>
<leafValues>
-7.7620923519134521e-01 7.8929436206817627e-01</leafValues></_>
<_>
<internalNodes>
0 -1 1 2013233135 2147450879 -45760593 2147474943 2146959359
2104754047 2080374783 2147417087</internalNodes>
<leafValues>
-8.9144438505172729e-01 5.9051072597503662e-01</leafValues></_></weakClassifiers></_>
<!-- stage 2 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-1.1397969722747803e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 15 -1041 -8225 -546308113 -1 -33554433 -394753 -2359297
-1</internalNodes>
<leafValues>
-8.5447394847869873e-01 7.4388968944549561e-01</leafValues></_>
<_>
<internalNodes>
0 -1 27 -1053970 -17 -35651601 -1048625 -345331574 -5247030
-74453009 -1</internalNodes>
<leafValues>
-8.6756819486618042e-01 6.3549250364303589e-01</leafValues></_>
<_>
<internalNodes>
0 -1 43 -1050897 -1025 -71304209 -134219793 -1033 -559948801
-67110929 1996976642</internalNodes>
<leafValues>
-8.6068797111511230e-01 5.8224511146545410e-01</leafValues></_></weakClassifiers></_>
<!-- stage 3 -->
<_>
<maxWeakCount>3</maxWeakCount>
<stageThreshold>-9.8026764392852783e-01</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 12 -1077953601 -1 -1073758273 -16387 -147457 -1
-1073758209 -1</internalNodes>
<leafValues>
-8.2477015256881714e-01 7.1671992540359497e-01</leafValues></_>
<_>
<internalNodes>
0 -1 47 -4345 -989855745 -271062524 -319815697 -134742265
1423962843 -134218173 -1</internalNodes>
<leafValues>
-7.4230498075485229e-01 7.3275351524353027e-01</leafValues></_>
<_>
<internalNodes>
0 -1 37 -22347778 -3477554 -33554433 -2066 -9438209 -65537
-1 -1048577</internalNodes>
<leafValues>
-8.3125960826873779e-01 5.8680748939514160e-01</leafValues></_></weakClassifiers></_>
<!-- stage 4 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.2986627817153931e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 4 -8388737 -262273 -10485761 -137 -8388745 -129 -262273
-1</internalNodes>
<leafValues>
-8.7727063894271851e-01 6.1173391342163086e-01</leafValues></_>
<_>
<internalNodes>
0 -1 20 -1 -10241 1431688703 -1 -1 -1042 1163263999
2002780159</internalNodes>
<leafValues>
-8.2954949140548706e-01 5.9151750802993774e-01</leafValues></_>
<_>
<internalNodes>
0 -1 3 -44786212 -33726467 -268509185 -17409 -657175332
-2270500 -1198986500 -1148450934</internalNodes>
<leafValues>
-7.6026451587677002e-01 5.8319890499114990e-01</leafValues></_>
<_>
<internalNodes>
0 -1 28 -15794258 -78643282 -821817846 -552742962 -653344834
-91750417 -1622147105 -7340065</internalNodes>
<leafValues>
-7.6077878475189209e-01 5.5891805887222290e-01</leafValues></_>
<_>
<internalNodes>
0 -1 30 1427232247 357954767 1971310559 2012602108
-202375953 -44049 -4456789 -18</internalNodes>
<leafValues>
-6.7643576860427856e-01 6.0950380563735962e-01</leafValues></_></weakClassifiers></_>
<!-- stage 5 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.3029408454895020e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 39 -134218753 -1 -1 -202899593 -1 -4194305 -67108865
-527497</internalNodes>
<leafValues>
-7.5626724958419800e-01 7.5137990713119507e-01</leafValues></_>
<_>
<internalNodes>
0 -1 6 -8388737 -8388737 -1 -1 -8421505 -129 -8388737 -1</internalNodes>
<leafValues>
-7.7118909358978271e-01 6.3570922613143921e-01</leafValues></_>
<_>
<internalNodes>
0 -1 45 -825233914 -654313761 -589830738 -35651585 -16778427
-83886281 -151000316 -1056964737</internalNodes>
<leafValues>
-7.2490030527114868e-01 5.7298541069030762e-01</leafValues></_>
<_>
<internalNodes>
0 -1 18 2002780159 2136866815 -67109377 -19969 2147344383
2101472763 2108680957 2147450607</internalNodes>
<leafValues>
-8.5162043571472168e-01 4.5608481764793396e-01</leafValues></_>
<_>
<internalNodes>
0 -1 16 -7472470 -3505654 -29841 -65536 -1166086177
-67109121 -288690177 -32085</internalNodes>
<leafValues>
-7.9073858261108398e-01 5.0315058231353760e-01</leafValues></_></weakClassifiers></_>
<!-- stage 6 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.3164747953414917e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 41 -1 -1025 -1 -2228225 -8432299 -571189899 -139265 -1</internalNodes>
<leafValues>
-7.8127676248550415e-01 6.5899217128753662e-01</leafValues></_>
<_>
<internalNodes>
0 -1 2 -34275329 -198665 -2113 -12289 -573243396 -590292744
-1049857 -277</internalNodes>
<leafValues>
-7.3563832044601440e-01 6.3897633552551270e-01</leafValues></_>
<_>
<internalNodes>
0 -1 14 -1565523969 -1347420193 -277086209 -1342177313
-134217729 -263169 -285212673 -1459618305</internalNodes>
<leafValues>
-8.1234931945800781e-01 4.9628043174743652e-01</leafValues></_>
<_>
<internalNodes>
0 -1 33 -1079312417 -83826176 -33686017 -570426508
-1627464961 -5377 -277761 -17</internalNodes>
<leafValues>
-7.0463657379150391e-01 5.2093976736068726e-01</leafValues></_>
<_>
<internalNodes>
0 -1 25 -66 -4116 1607291240 -5298489 -9847160 2011036101
357852669 1476259327</internalNodes>
<leafValues>
-8.2066470384597778e-01 4.9184983968734741e-01</leafValues></_></weakClassifiers></_>
<!-- stage 7 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.1098697185516357e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 44 -134217949 -167773185 -404750589 -1 -134744525
-1846018321 -2097357 -1</internalNodes>
<leafValues>
-7.6240319013595581e-01 6.8946647644042969e-01</leafValues></_>
<_>
<internalNodes>
0 -1 7 -12633797 -524321 1058880319 -129 -50790401 -262405
-1075052545 -5</internalNodes>
<leafValues>
-7.1431988477706909e-01 6.2125796079635620e-01</leafValues></_>
<_>
<internalNodes>
0 -1 24 -144703501 -10486797 -134217729 -136317057
-271646721 -174069583 -168952849 -1072726014</internalNodes>
<leafValues>
-6.5710061788558960e-01 6.1531358957290649e-01</leafValues></_>
<_>
<internalNodes>
0 -1 38 -134218774 -149487872 -33554433 -537927872 -69209089
-145228029 -2360849 -524449</internalNodes>
<leafValues>
-7.3570650815963745e-01 4.9681660532951355e-01</leafValues></_>
<_>
<internalNodes>
0 -1 5 -136380419 -8390657 -2228225 -196707 1565810157
2147048386 -268702725 2080373485</internalNodes>
<leafValues>
-7.2735637426376343e-01 5.2713739871978760e-01</leafValues></_></weakClassifiers></_>
<!-- stage 8 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-2.0547957420349121e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 13 -11141121 -44695553 -1 -11144193 -9217 -321
-335811841 -4216577</internalNodes>
<leafValues>
-7.3916637897491455e-01 6.7595410346984863e-01</leafValues></_>
<_>
<internalNodes>
0 -1 26 -369104657 -4194321 -1061429013 -67114529 -251662085
-138412033 3334395 -234882305</internalNodes>
<leafValues>
-6.9217604398727417e-01 5.4744583368301392e-01</leafValues></_>
<_>
<internalNodes>
0 -1 11 1373590751 1373632511 -262169 -33859589 -572533249
-572524625 -135266305 -32833</internalNodes>
<leafValues>
-7.1100026369094849e-01 5.3469187021255493e-01</leafValues></_>
<_>
<internalNodes>
0 -1 23 -3148053 -1054802 -1 -5 -7340125 -3689942 -74448917
-687087094</internalNodes>
<leafValues>
-5.6383520364761353e-01 6.3540917634963989e-01</leafValues></_>
<_>
<internalNodes>
0 -1 8 245501180 -1615197700 -46219265 -1075925028
-307580929 -373826 -1076187139 -1343746644</internalNodes>
<leafValues>
-5.8823972940444946e-01 6.1824375391006470e-01</leafValues></_></weakClassifiers></_>
<!-- stage 9 -->
<_>
<maxWeakCount>6</maxWeakCount>
<stageThreshold>-1.6300759315490723e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 42 -1 -4129 -8193 -135795737 -1 -6417 -1 -137887866</internalNodes>
<leafValues>
-7.7990013360977173e-01 6.1912822723388672e-01</leafValues></_>
<_>
<internalNodes>
0 -1 31 -12845643 -1934361103 -581837313 -1644167171
-1175537153 -1392516625 -1681655299 -1358963807</internalNodes>
<leafValues>
-7.1357387304306030e-01 5.6909996271133423e-01</leafValues></_>
<_>
<internalNodes>
0 -1 34 288428543 -34262659 1976906747 -42117703 858797567
-4965441 2008290292 -1146080848</internalNodes>
<leafValues>
-6.7784935235977173e-01 5.4983222484588623e-01</leafValues></_>
<_>
<internalNodes>
0 -1 22 -25297611 -100663553 -9830515 -570556417 -53741251
-36570627 -67437302 -12583252</internalNodes>
<leafValues>
-6.3567954301834106e-01 5.9044981002807617e-01</leafValues></_>
<_>
<internalNodes>
0 -1 46 -403706354 82769839 -446830048 -989858098 -8921600
1087893408 -100663520 -134217729</internalNodes>
<leafValues>
-7.0569902658462524e-01 5.4874616861343384e-01</leafValues></_>
<_>
<internalNodes>
0 -1 0 -965744853 -420544541 -8392718 -1569784218 -192940313
1744830335 -9 -1003227661</internalNodes>
<leafValues>
-5.7118493318557739e-01 6.4167028665542603e-01</leafValues></_></weakClassifiers></_>
<!-- stage 10 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-2.1370947360992432e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 40 -673196033 -2144789 287251423 -538968593 -1399068449
-73535505 -13631489 -526857</internalNodes>
<leafValues>
-7.2344118356704712e-01 6.8316829204559326e-01</leafValues></_>
<_>
<internalNodes>
0 -1 32 -214216429 -2112561 -445819937 1964790555 -17185861
-303183720 -357832229 -3148837</internalNodes>
<leafValues>
-7.1031409502029419e-01 5.4083776473999023e-01</leafValues></_>
<_>
<internalNodes>
0 -1 10 -9043969 -36118539 2147450623 -4194305 -2246657
-102721404 1073685759 -1366622208</internalNodes>
<leafValues>
-5.8772116899490356e-01 6.4753490686416626e-01</leafValues></_>
<_>
<internalNodes>
0 -1 35 1167938037 16237049 -1120535169 1029034397 9567155
-2001626128 -1146622977 -1142248004</internalNodes>
<leafValues>
-6.4004391431808472e-01 5.6415843963623047e-01</leafValues></_>
<_>
<internalNodes>
0 -1 21 -70126622 -134227061 -536243648 188013035
-1234960385 1416625375 -486868997 62913535</internalNodes>
<leafValues>
-8.8218396902084351e-01 4.1129270195960999e-01</leafValues></_></weakClassifiers></_></stages>
<features>
<_>
<rect>
0 1 1 6</rect></_>
<_>
<rect>
1 0 8 3</rect></_>
<_>
<rect>
1 4 8 3</rect></_>
<_>
<rect>
1 6 13 2</rect></_>
<_>
<rect>
2 1 5 2</rect></_>
<_>
<rect>
2 4 9 2</rect></_>
<_>
<rect>
3 2 5 2</rect></_>
<_>
<rect>
4 0 11 3</rect></_>
<_>
<rect>
4 21 9 1</rect></_>
<_>
<rect>
7 1 5 5</rect></_>
<_>
<rect>
7 7 6 2</rect></_>
<_>
<rect>
10 0 3 5</rect></_>
<_>
<rect>
11 1 9 3</rect></_>
<_>
<rect>
11 2 11 4</rect></_>
<_>
<rect>
12 0 4 3</rect></_>
<_>
<rect>
14 2 5 2</rect></_>
<_>
<rect>
14 6 3 3</rect></_>
<_>
<rect>
15 1 5 4</rect></_>
<_>
<rect>
16 0 9 4</rect></_>
<_>
<rect>
17 3 4 5</rect></_>
<_>
<rect>
17 6 4 3</rect></_>
<_>
<rect>
18 12 3 2</rect></_>
<_>
<rect>
19 0 3 3</rect></_>
<_>
<rect>
19 3 2 6</rect></_>
<_>
<rect>
19 4 2 4</rect></_>
<_>
<rect>
19 12 2 4</rect></_>
<_>
<rect>
21 2 2 5</rect></_>
<_>
<rect>
22 5 3 4</rect></_>
<_>
<rect>
22 14 3 3</rect></_>
<_>
<rect>
24 1 6 5</rect></_>
<_>
<rect>
25 3 4 5</rect></_>
<_>
<rect>
25 6 6 1</rect></_>
<_>
<rect>
26 1 2 5</rect></_>
<_>
<rect>
26 3 5 4</rect></_>
<_>
<rect>
26 21 6 1</rect></_>
<_>
<rect>
27 1 5 1</rect></_>
<_>
<rect>
29 3 4 6</rect></_>
<_>
<rect>
30 0 4 5</rect></_>
<_>
<rect>
30 2 3 7</rect></_>
<_>
<rect>
34 1 3 7</rect></_>
<_>
<rect>
34 8 3 2</rect></_>
<_>
<rect>
34 15 3 3</rect></_>
<_>
<rect>
35 3 2 5</rect></_>
<_>
<rect>
35 5 2 5</rect></_>
<_>
<rect>
39 12 1 3</rect></_>
<_>
<rect>
41 0 1 7</rect></_>
<_>
<rect>
41 10 1 4</rect></_>
<_>
<rect>
41 11 1 3</rect></_></features></cascade>
</opencv_storage>

+ 44
- 11
Prj-Win/lpr/src/Pipeline.cpp View File

@@ -3,35 +3,68 @@
namespace pr {
PipelinePR::PipelinePR(std::string detect_prototxt, std::string detect_caffemodel,
std::string finetune_prototxt, std::string finetune_caffemodel,
std::string platerec_prototxt, std::string platerec_caffemodel/*,
std::string platecolor_color*/)
std::string platerec_prototxt, std::string platerec_caffemodel,
std::string dbstring)
{
platedetection = new PlateDetection(detect_prototxt, detect_caffemodel);
finetune = new FineTune(finetune_prototxt, finetune_caffemodel);
platerecognation = new PlateRecognation(platerec_prototxt, platerec_caffemodel);
//platecolorclass = new PlateColorClass(platecolor_color);
dbdetection = new DBDetection(dbstring);
}
PipelinePR::~PipelinePR()
{
delete platedetection;
delete finetune;
delete platerecognation;
//delete platecolorclass;
delete dbdetection;
}
std::vector<PlateInfo> PipelinePR::RunPiplineAsImage(cv::Mat plateimg)
cv::Mat DBcropFromImage(const cv::Mat &image){
cv::Mat cropped;
image.copyTo(cropped);
int cropped_w = cropped.cols;
int cropped_h = cropped.rows;
cv::Rect up,down;
up.y = cropped_h*0.05;up.x = cropped_w*0.2;up.height = cropped_h*0.35;up.width = cropped_w*0.55;
down.y = cropped_h*0.4;down.x = cropped_w*0.05;down.height = cropped_h*0.6;down.width = cropped_w*0.95;
cv::Mat cropUp,cropDown;
cropped(up).copyTo(cropUp);
cropped(down).copyTo(cropDown);
cv::resize(cropUp,cropUp,cv::Size(64,40));
cv::resize(cropDown,cropDown,cv::Size(96,40));
cv::Mat crop = cv::Mat(40,160,CV_8UC3);
cropUp.copyTo(crop(cv::Rect(0,0,64,40)));
cropDown.copyTo(crop(cv::Rect(64,0,96,40)));
return crop;

}
std::vector<PlateInfo> PipelinePR::RunPiplineAsImage(cv::Mat plateimg,int IsDB)
{
std::vector<pr::PlateInfo> plates;
std::vector<PlateInfo> plateres;

platedetection->Detectssd(plateimg, plates);
if(IsDB==1)
{
dbdetection->DBDetect(plateimg,plates,30,1280);
}
else
{
platedetection->Detectssd(plateimg, plates);
}
for (pr::PlateInfo plateinfo : plates) {
cv::Mat image = plateinfo.getPlateImage();
cv::Mat CropImg;
finetune->Finetune(image, CropImg);
platerecognation->segmentation_free_recognation(CropImg, plateinfo);
//platecolorclass->plateColor(CropImg, plateinfo);
if(IsDB==1)
{
CropImg = DBcropFromImage(image);
platerecognation->segmentation_free_recognation(CropImg, plateinfo);
}
else
{
finetune->Finetune(image, CropImg);
platerecognation->segmentation_free_recognation(CropImg, plateinfo);
}
plateres.push_back(plateinfo);
}
return plateres;
}
}
}

+ 43
- 0
Prj-Win/lpr/src/PlateDetection.cpp View File

@@ -8,6 +8,10 @@ namespace pr {
{
ssdNet = cv::dnn::readNetFromCaffe(ssd_prototxt, ssd_caffemodel);
}
DBDetection::DBDetection(std::string cascadestring)
{
dbcascade.load(cascadestring);
}
void PlateDetection::Detectssd(cv::Mat img, std::vector<pr::PlateInfo> &plateInfos)
{
int cols = img.cols;
@@ -57,4 +61,43 @@ namespace pr {
}
}
}
cv::Mat cropFromImage(const cv::Mat &image,cv::Rect rect){
int w = image.cols-1;
int h = image.rows-1;
rect.x = std::max(rect.x,0);
rect.y = std::max(rect.y,0);
rect.height = std::min(rect.height,h-rect.y);
rect.width = std::min(rect.width,w-rect.x);
cv::Mat temp(rect.size(), image.type());
cv::Mat cropped;
temp = image(rect);
temp.copyTo(cropped);
return cropped;
}
void DBDetection::DBDetect(cv::Mat InputImage,std::vector<pr::PlateInfo> &plateInfos,int min_w,int max_w)
{
cv::Mat processImage;
cv::cvtColor(InputImage,processImage,cv::COLOR_BGR2GRAY);
std::vector<cv::Rect> platesRegions;
cv::Size minSize(min_w,min_w/4);
cv::Size maxSize(max_w,max_w/4);
if (&processImage == NULL)
return;
dbcascade.detectMultiScale( processImage, platesRegions,
1.1, 3, cv::CASCADE_SCALE_IMAGE,minSize,maxSize);
for(auto plate:platesRegions)
{
int zeroadd_w = static_cast<int>(plate.width*0.28);
int zeroadd_h = static_cast<int>(plate.height*0.35);
int zeroadd_x = static_cast<int>(plate.width*0.14);
int zeroadd_y = static_cast<int>(plate.height*0.15);
plate.x-=zeroadd_x;
plate.y-=zeroadd_y;
plate.height += zeroadd_h;
plate.width += zeroadd_w;
cv::Mat plateImage = cropFromImage(InputImage,plate);
PlateInfo plateInfo(plateImage,plate);
plateInfos.push_back(plateInfo);
}
}
}

+ 6
- 5
Prj-Win/lpr/tests/testPipeLine.cpp View File

@@ -4,9 +4,10 @@ void TEST_PIPELINE()
{
pr::PipelinePR prc("../lpr\\model\\mininet_ssd_v1.prototxt", "../lpr\\model\\mininet_ssd_v1.caffemodel",
"../lpr\\model\\refinenet.prototxt", "../lpr\\model\\refinenet.caffemodel",
"../lpr\\model\\SegmenationFree-Inception.prototxt", "../lpr\\model\\SegmenationFree-Inception.caffemodel");
"../lpr\\model\\SegmenationFree-Inception.prototxt", "../lpr\\model\\SegmenationFree-Inception.caffemodel",
"../lpr\\model\\cascade_double.xml");
cv::Mat img = cv::imread("../lpr\\res\\test.jpg");
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(img);
std::vector<pr::PlateInfo> res = prc.RunPiplineAsImage(img,0);
for (auto st : res) {
if (st.confidence > 0.75) {
std::cout << st.getPlateName() << " " << st.confidence << std::endl;
@@ -16,12 +17,12 @@ void TEST_PIPELINE()
}
}

cv::imshow("image", img);
cv::waitKey(0);
//cv::imshow("image", img);
//cv::waitKey(0);

}
int main()
{
TEST_PIPELINE();
return 0;
}
}

+ 0
- 55
WebAPI.py View File

@@ -1,55 +0,0 @@
#coding=utf-8
from flask import Flask, render_template, request
from werkzeug import secure_filename

import cv2
import numpy as np

#导入opencv

from hyperlpr import pipline
#导入车牌识别库


app = Flask(__name__)
#设置App name


def recognize(filename):
image = cv2.imread(filename)
return HyperLPR_plate_recognition(image)
#return pipline.RecognizePlateJson(image)

import base64

def recognizeBase64(base64_code):
file_bytes = np.asarray(bytearray(base64.b64decode(base64_code)),dtype=np.uint8)
image_data_ndarray = cv2.imdecode(file_bytes,1)
return pipline.RecognizePlateJson(image_data_ndarray)


import time

@app.route('/uploader', methods=['GET', 'POST'])#设置请求路由
def upload_file():
if request.method == 'POST':
#如果请求方法是POST
f = request.files['file']
f.save("./images_rec/"+secure_filename(f.filename))
#保存请求上来的文件
t0 = time.time()
res = recognize("./images_rec/"+secure_filename(f.filename))
print "识别时间",time.time() - t0
return res
#返回识别结果
# return 'file uploaded successfully'
return render_template('upload.html')



if __name__ == '__main__':
#入口函数

app.run("0.0.0.0",port=8000)
#运行app 指定IP 指定端口


+ 2
- 2
hyperlpr_pip_pkg/demo.py View File

@@ -1,5 +1,5 @@
import cv2
from hyperlpr import *

image = cv2.imread("./test_images/test_db2.jpg")
print(HyperLPR_plate_recognition(image, 16, charSelectionDeskew=False, DB=True))
image = cv2.imread("./test_images/test.jpg")
print(HyperLPR_plate_recognition(image, 16, charSelectionDeskew=False, DB=False))

+ 1
- 0
hyperlpr_pip_pkg/hyperlpr/table_chs.py View File

@@ -1,3 +1,4 @@
#coding=utf-8
chars = [
u"京", u"沪", u"津", u"渝", u"冀", u"晋", u"蒙", u"辽", u"吉", u"黑", u"苏", u"浙", u"皖", u"闽", u"赣", u"鲁",
u"豫", u"鄂", u"湘", u"粤", u"桂", u"琼", u"川", u"贵", u"云", u"藏", u"陕", u"甘", u"青", u"宁", u"新", u"0",


+ 0
- 12117
model/cascade.xml
File diff suppressed because it is too large
View File


+ 0
- 842
model/cascade_lbp.xml View File

@@ -1,842 +0,0 @@
<?xml version="1.0"?>
<opencv_storage>
<cascade>
<stageType>BOOST</stageType>
<featureType>LBP</featureType>
<height>16</height>
<width>64</width>
<stageParams>
<boostType>GAB</boostType>
<minHitRate>9.9500000476837158e-01</minHitRate>
<maxFalseAlarm>5.0000000000000000e-01</maxFalseAlarm>
<weightTrimRate>9.4999999999999996e-01</weightTrimRate>
<maxDepth>1</maxDepth>
<maxWeakCount>25</maxWeakCount></stageParams>
<featureParams>
<maxCatCount>256</maxCatCount>
<featSize>1</featSize></featureParams>
<stageNum>13</stageNum>
<stages>
<!-- stage 0 -->
<_>
<maxWeakCount>4</maxWeakCount>
<stageThreshold>-1.6219481229782104e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 43 -2561 -234882069 -578037494 -3147793 -203032597
1902231761 -3407926 -2049</internalNodes>
<leafValues>
-7.8116589784622192e-01 6.8186044692993164e-01</leafValues></_>
<_>
<internalNodes>
0 -1 57 352326928 1058083280 1502920181 -6613668 -1735873027
-1141159777 -1142412372 -1157101560</internalNodes>
<leafValues>
-7.9259228706359863e-01 6.2141162157058716e-01</leafValues></_>
<_>
<internalNodes>
0 -1 28 -50 -586226738 -552468344 -110118166 -717113442
21449 1474142699 1442839519</internalNodes>
<leafValues>
-7.1683514118194580e-01 6.0926103591918945e-01</leafValues></_>
<_>
<internalNodes>
0 -1 3 -1054002 -460394782 -286332350 -487653842 -134742175
74798917 -545795120 -176179201</internalNodes>
<leafValues>
-6.4934897422790527e-01 6.6864526271820068e-01</leafValues></_></weakClassifiers></_>
<!-- stage 1 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.2461665868759155e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 40 -134217745 -235407873 -767164534 -9442626 -134744129
1358279167 -1572882 -167772417</internalNodes>
<leafValues>
-8.2479608058929443e-01 4.7822877764701843e-01</leafValues></_>
<_>
<internalNodes>
0 -1 7 -1845456648 -585870960 319829493 -45086460 -922740488
-776006 -1433921089 1000341512</internalNodes>
<leafValues>
-7.0899802446365356e-01 5.1915192604064941e-01</leafValues></_>
<_>
<internalNodes>
0 -1 81 -67371134 -487394324 -649661312 -1031543834
-1149046011 34820455 2002998528 -764152457</internalNodes>
<leafValues>
-7.0243948698043823e-01 5.5623692274093628e-01</leafValues></_>
<_>
<internalNodes>
0 -1 52 605031448 -1084468744 -1655103491 2147294680
-1316447491 -637769064 -1074216962 -1144512372</internalNodes>
<leafValues>
-7.3613041639328003e-01 5.2777582406997681e-01</leafValues></_>
<_>
<internalNodes>
0 -1 74 -17825814 -209070806 1224757760 1301260154
-243867776 537980928 822665600 1453848575</internalNodes>
<leafValues>
-7.6585876941680908e-01 5.4007095098495483e-01</leafValues></_></weakClassifiers></_>
<!-- stage 2 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.0288889408111572e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 45 -142606337 -234884105 -942669937 -168820737
-738200065 -235472937 -526384 -2057</internalNodes>
<leafValues>
-7.3661798238754272e-01 4.7879859805107117e-01</leafValues></_>
<_>
<internalNodes>
0 -1 26 -1600126800 -183469583 124855 -78637583 -133643336
-1129276228 -1952969795 -1469053824</internalNodes>
<leafValues>
-7.1075737476348877e-01 4.3283107876777649e-01</leafValues></_>
<_>
<internalNodes>
0 -1 2 -17830162 -523507506 -335297938 -989868310 -672663705
1651099457 -144248732 -144193705</internalNodes>
<leafValues>
-6.8117302656173706e-01 5.0106960535049438e-01</leafValues></_>
<_>
<internalNodes>
0 -1 14 -167772178 -4341761 -537399902 -4117 -167905793
-1795293185 1442162154 -1276139602</internalNodes>
<leafValues>
-5.5162549018859863e-01 5.6729644536972046e-01</leafValues></_>
<_>
<internalNodes>
0 -1 0 286273977 1901156160 1976515063 1475813144 692299752
-843064354 2005724111 231539854</internalNodes>
<leafValues>
-5.9739047288894653e-01 5.3236293792724609e-01</leafValues></_></weakClassifiers></_>
<!-- stage 3 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.2924413681030273e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 37 -2097153 -235144257 -545392210 -33572114 -16780289
1910626738 -1 -2109697</internalNodes>
<leafValues>
-7.6233702898025513e-01 3.0888170003890991e-01</leafValues></_>
<_>
<internalNodes>
0 -1 36 -258 -175194962 -135991606 -738599954 -136863745
366325164 2013083647 2012741631</internalNodes>
<leafValues>
-7.0845782756805420e-01 4.1357228159904480e-01</leafValues></_>
<_>
<internalNodes>
0 -1 82 -536870966 -536613905 -1852834560 -1027083697
-1955475901 22082080 1935632198 -212339385</internalNodes>
<leafValues>
-5.8534580469131470e-01 4.9082395434379578e-01</leafValues></_>
<_>
<internalNodes>
0 -1 63 -4196358 -179655702 1326732016 301789054 -186638920
1174458592 226521599 1464860671</internalNodes>
<leafValues>
-7.0115524530410767e-01 4.0752482414245605e-01</leafValues></_>
<_>
<internalNodes>
0 -1 56 344981520 -136703748 356261887 -163428 796983036
-72533315 -1115116035 780141600</internalNodes>
<leafValues>
-7.1504431962966919e-01 4.2116415500640869e-01</leafValues></_></weakClassifiers></_>
<!-- stage 4 -->
<_>
<maxWeakCount>5</maxWeakCount>
<stageThreshold>-1.1838985681533813e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 46 -67110917 -202115085 -271581201 -336592945
-143140905 -201984013 -3407928 -2097185</internalNodes>
<leafValues>
-7.0421242713928223e-01 3.7325173616409302e-01</leafValues></_>
<_>
<internalNodes>
0 -1 55 352326877 2003836272 -1617349227 1058474396
747657468 -41936696 479268351 455090176</internalNodes>
<leafValues>
-6.5891182422637939e-01 4.0733435750007629e-01</leafValues></_>
<_>
<internalNodes>
0 -1 35 -68158522 -420809853 -2142795414 -531650130
1605890899 74375236 1962914631 -1048595537</internalNodes>
<leafValues>
-5.8815896511077881e-01 4.4766652584075928e-01</leafValues></_>
<_>
<internalNodes>
0 -1 66 270536848 -720105612 1574215605 -1118474876
-1309562435 -17718535 -1417101588 480510216</internalNodes>
<leafValues>
-6.9849157333374023e-01 3.8642087578773499e-01</leafValues></_>
<_>
<internalNodes>
0 -1 83 -2134 -409219102 -855378432 -960304344 -1279021055
69585478 1405350480 -168296489</internalNodes>
<leafValues>
-6.0635018348693848e-01 4.3005070090293884e-01</leafValues></_></weakClassifiers></_>
<!-- stage 5 -->
<_>
<maxWeakCount>6</maxWeakCount>
<stageThreshold>-1.8914896249771118e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 48 -134219777 -788532525 -812650611 -1048593 -150998049
-239602953 -2097204 -2177</internalNodes>
<leafValues>
-7.1383845806121826e-01 3.2626426219940186e-01</leafValues></_>
<_>
<internalNodes>
0 -1 61 -1048594 -607129886 -487669600 -141563137 -136579627
1077113951 -638069761 -136315521</internalNodes>
<leafValues>
-5.5788379907608032e-01 4.3335753679275513e-01</leafValues></_>
<_>
<internalNodes>
0 -1 60 1015027472 1065203709 -75 -1073881153 -57885763
-88097793 -67356484 -1097200384</internalNodes>
<leafValues>
-6.2508052587509155e-01 3.9868113398551941e-01</leafValues></_>
<_>
<internalNodes>
0 -1 8 -454234450 -318771793 -1284575442 -17830674
-1040451841 -184827938 -196 1961355182</internalNodes>
<leafValues>
-7.3622447252273560e-01 3.3065965771675110e-01</leafValues></_>
<_>
<internalNodes>
0 -1 21 -269484068 -33607937 -309449564 1060105967
-239086164 351597820 -1517504612 1912370687</internalNodes>
<leafValues>
-7.0256131887435913e-01 3.3312633633613586e-01</leafValues></_>
<_>
<internalNodes>
0 -1 71 -1050758 -5312152 1166557700 992935900 1736637342
860234746 161275919 2131755007</internalNodes>
<leafValues>
-6.1535042524337769e-01 3.6958575248718262e-01</leafValues></_></weakClassifiers></_>
<!-- stage 6 -->
<_>
<maxWeakCount>6</maxWeakCount>
<stageThreshold>-1.7857444286346436e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 18 -33597695 -16777351 2143250303 -67108865 -51445761
-353435649 -529138753 -520094209</internalNodes>
<leafValues>
-7.5571727752685547e-01 1.9621904194355011e-01</leafValues></_>
<_>
<internalNodes>
0 -1 77 -6166 -22028630 -1867890622 -208930962 -257952369
1694687690 -710676022 -676593681</internalNodes>
<leafValues>
-5.7280772924423218e-01 3.8669580221176147e-01</leafValues></_>
<_>
<internalNodes>
0 -1 72 -4197398 -13667294 1264456776 520898368 -236866168
1017143276 287104651 2131754991</internalNodes>
<leafValues>
-6.6346269845962524e-01 3.3237108588218689e-01</leafValues></_>
<_>
<internalNodes>
0 -1 39 -143130677 -235151367 -135405656 -1052726 -135202887
1901097317 -663602 -236987138</internalNodes>
<leafValues>
-5.5477285385131836e-01 3.9316710829734802e-01</leafValues></_>
<_>
<internalNodes>
0 -1 65 83891216 2111053808 -1758445707 -1076331011
-1186415942 -34267768 1072316092 1010306064</internalNodes>
<leafValues>
-7.1728479862213135e-01 3.6254638433456421e-01</leafValues></_>
<_>
<internalNodes>
0 -1 67 -1082 1715970504 1179800832 1409279439 1903162828
1141306437 -757074473 -792726017</internalNodes>
<leafValues>
-5.5629384517669678e-01 3.9846968650817871e-01</leafValues></_></weakClassifiers></_>
<!-- stage 7 -->
<_>
<maxWeakCount>7</maxWeakCount>
<stageThreshold>-2.2031784057617188e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 11 -2301 -8519809 -144966345 -8388737 -17039361
-889196545 -234950661 -855703553</internalNodes>
<leafValues>
-6.9055068492889404e-01 2.6715686917304993e-01</leafValues></_>
<_>
<internalNodes>
0 -1 4 -1052950 -1030756626 1719921160 -892344210 -403215392
1145536103 -144186425 -145229969</internalNodes>
<leafValues>
-6.1277091503143311e-01 3.3642357587814331e-01</leafValues></_>
<_>
<internalNodes>
0 -1 59 286531033 2098207187 1602043383 -1080477187
763371006 -537104396 -1175175713 794824808</internalNodes>
<leafValues>
-5.6694328784942627e-01 3.9781469106674194e-01</leafValues></_>
<_>
<internalNodes>
0 -1 47 -134219777 -266078729 -1053010 -202441777 -671090829
-252189705 -138421290 -201853577</internalNodes>
<leafValues>
-5.0729566812515259e-01 4.4068849086761475e-01</leafValues></_>
<_>
<internalNodes>
0 -1 27 -234883080 223281098 -67191924 -536895489 1966425827
1107107294 1911366826 1912600478</internalNodes>
<leafValues>
-6.2338167428970337e-01 3.5619020462036133e-01</leafValues></_>
<_>
<internalNodes>
0 -1 13 17914830 930939132 2064627679 2012686036 851311614
867926958 1870789886 999286414</internalNodes>
<leafValues>
-6.3150572776794434e-01 3.1903952360153198e-01</leafValues></_>
<_>
<internalNodes>
0 -1 33 136839352 1566392105 320846289 -6316560 1264845256
-310635363 1001921756 -16707584</internalNodes>
<leafValues>
-5.1506024599075317e-01 3.9011520147323608e-01</leafValues></_></weakClassifiers></_>
<!-- stage 8 -->
<_>
<maxWeakCount>8</maxWeakCount>
<stageThreshold>-1.7945843935012817e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 12 1398267901 2147439612 2123268094 -151554 1609564158
-1094717490 -536936450 -2</internalNodes>
<leafValues>
-6.9123697280883789e-01 2.4225576221942902e-01</leafValues></_>
<_>
<internalNodes>
0 -1 19 288649975 1896962996 2147358687 -2755801 1995717118
-45818920 -5591569 -1410850678</internalNodes>
<leafValues>
-5.0494408607482910e-01 3.8951012492179871e-01</leafValues></_>
<_>
<internalNodes>
0 -1 25 2009589607 2013210605 -854692018 -538983793
2007497719 837252003 1087274958 2012479430</internalNodes>
<leafValues>
-5.8543336391448975e-01 3.5037690401077271e-01</leafValues></_>
<_>
<internalNodes>
0 -1 44 -235146869 -791101327 -808456274 -355467793
-243272351 1365733749 -40903860 -202381833</internalNodes>
<leafValues>
-6.2743508815765381e-01 3.0872401595115662e-01</leafValues></_>
<_>
<internalNodes>
0 -1 69 -187194750 -949043 71655182 -674369691 -605047809
-135273794 1667695530 1407134219</internalNodes>
<leafValues>
-6.2414431571960449e-01 3.2251501083374023e-01</leafValues></_>
<_>
<internalNodes>
0 -1 38 2230525 -135137994 -976214793 -135232159 -1292857608
-34534659 -1266151425 -1391460176</internalNodes>
<leafValues>
-4.6821090579032898e-01 4.0499693155288696e-01</leafValues></_>
<_>
<internalNodes>
0 -1 5 -3223809 -319881490 -827446787 -522134804 1969192959
-917472815 1527129084 -596115457</internalNodes>
<leafValues>
-4.4530543684959412e-01 4.5620110630989075e-01</leafValues></_>
<_>
<internalNodes>
0 -1 70 -269484046 -5976 -1394343700 265170172 -983433284
1613669713 774045688 1422913527</internalNodes>
<leafValues>
-6.2135016918182373e-01 3.1382775306701660e-01</leafValues></_></weakClassifiers></_>
<!-- stage 9 -->
<_>
<maxWeakCount>7</maxWeakCount>
<stageThreshold>-1.3709685802459717e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 53 288627701 -539716099 -1080189441 -5377221 -198147
-19267681 -1077347329 -1078052480</internalNodes>
<leafValues>
-7.3079609870910645e-01 1.3688945770263672e-01</leafValues></_>
<_>
<internalNodes>
0 -1 31 -101188633 2046427005 -879759474 -406213026
-177474373 1347479032 -5645426 -704709665</internalNodes>
<leafValues>
-6.4822560548782349e-01 2.8430926799774170e-01</leafValues></_>
<_>
<internalNodes>
0 -1 23 -79716865 -12726529 -1346466401 -1618014737
-1246112259 1894838525 -1109410565 -4327171</internalNodes>
<leafValues>
-3.9296570420265198e-01 5.5672270059585571e-01</leafValues></_>
<_>
<internalNodes>
0 -1 62 -2 -505680692 1156072780 1223288575 -852013125
912326647 1144182782 1173618679</internalNodes>
<leafValues>
-5.9236258268356323e-01 3.3399465680122375e-01</leafValues></_>
<_>
<internalNodes>
0 -1 32 -574640434 -573771794 -1188549526 -103946518
865156840 86802270 2004682734 905399423</internalNodes>
<leafValues>
-6.8310183286666870e-01 2.9013493657112122e-01</leafValues></_>
<_>
<internalNodes>
0 -1 29 -1608481027 -193948235 -1374540865 -174836947
-1939801614 -436954268 -5239873 -1357379910</internalNodes>
<leafValues>
-4.5706689357757568e-01 3.9714139699935913e-01</leafValues></_>
<_>
<internalNodes>
0 -1 51 -162535922 1965750879 1716452687 -608058379
-943998986 1691930644 -9438210 -143655097</internalNodes>
<leafValues>
-5.1470088958740234e-01 3.5138621926307678e-01</leafValues></_></weakClassifiers></_>
<!-- stage 10 -->
<_>
<maxWeakCount>8</maxWeakCount>
<stageThreshold>-1.8140829801559448e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 17 1895692285 2011002740 -68714497 -67588 -290538497
-5192712 -320164114 -34755958</internalNodes>
<leafValues>
-6.8089890480041504e-01 1.8467432260513306e-01</leafValues></_>
<_>
<internalNodes>
0 -1 6 -288362774 -1064894778 1088554026 -326172954
-204517530 1413968503 1931725632 -1000342529</internalNodes>
<leafValues>
-6.7872363328933716e-01 2.3477107286453247e-01</leafValues></_>
<_>
<internalNodes>
0 -1 76 -571549462 -3149082 1359301463 1440727651
-1074794578 -319326653 -681836625 -607405349</internalNodes>
<leafValues>
-4.2193624377250671e-01 4.7977572679519653e-01</leafValues></_>
<_>
<internalNodes>
0 -1 58 90969104 1066153948 1606262773 -12624417 972370428
-2511873 -90161928 -1170469880</internalNodes>
<leafValues>
-6.5543127059936523e-01 2.9713174700737000e-01</leafValues></_>
<_>
<internalNodes>
0 -1 20 2137390587 -4991721 -273880438 -404424826 -686509057
1908479685 -11534354 -957683766</internalNodes>
<leafValues>
-4.1799837350845337e-01 4.4941714406013489e-01</leafValues></_>
<_>
<internalNodes>
0 -1 34 1101522914 1643078770 1866900971 -1443209225
-941264961 1875766127 1743137767 1088907182</internalNodes>
<leafValues>
-6.5640193223953247e-01 2.8259485960006714e-01</leafValues></_>
<_>
<internalNodes>
0 -1 50 -340085256 -169869874 1295644543 -235208722
-74778165 -126150213 -284165896 2029932510</internalNodes>
<leafValues>
-5.2174586057662964e-01 3.1938755512237549e-01</leafValues></_>
<_>
<internalNodes>
0 -1 16 -1995780178 -1883579764 -1956835649 1064315450
298883276 -1651703672 1332547571 1529284110</internalNodes>
<leafValues>
-5.4796940088272095e-01 3.2749336957931519e-01</leafValues></_></weakClassifiers></_>
<!-- stage 11 -->
<_>
<maxWeakCount>9</maxWeakCount>
<stageThreshold>-1.5766727924346924e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 41 -10485775 -72630274 -168403503 -5964094 -608191528
-1968703489 -6309394 -71303233</internalNodes>
<leafValues>
-6.4981359243392944e-01 2.7962529659271240e-01</leafValues></_>
<_>
<internalNodes>
0 -1 49 -101713997 -795348237 -915944721 -923795474
-470288461 -256416651 -1081606200 -5257787</internalNodes>
<leafValues>
-5.0733184814453125e-01 3.5640156269073486e-01</leafValues></_>
<_>
<internalNodes>
0 -1 73 1360329646 1599450239 23042491 -168978051 499616426
88342532 -777262661 1474147167</internalNodes>
<leafValues>
-6.1151152849197388e-01 2.8293263912200928e-01</leafValues></_>
<_>
<internalNodes>
0 -1 22 856699153 925965308 830177791 -540057732 601830333
1704204720 -127190050 -1372115764</internalNodes>
<leafValues>
-4.9403667449951172e-01 3.5013946890830994e-01</leafValues></_>
<_>
<internalNodes>
0 -1 79 -321916242 1152275189 -491893242 16111322 463437710
1086714099 2129657567 1087328726</internalNodes>
<leafValues>
-6.8547970056533813e-01 2.7414512634277344e-01</leafValues></_>
<_>
<internalNodes>
0 -1 9 -332399838 -20285713 1825214839 -572523876 -158433654
-2075201062 705039115 -1061224609</internalNodes>
<leafValues>
-5.5482965707778931e-01 3.0516105890274048e-01</leafValues></_>
<_>
<internalNodes>
0 -1 80 -7341158 -203165398 -1749860256 -1653488455
-2040406360 554027584 121097696 1963982023</internalNodes>
<leafValues>
-6.0809975862503052e-01 2.5005647540092468e-01</leafValues></_>
<_>
<internalNodes>
0 -1 15 -540144966 -1079535658 -1090185032 -1691418456
361506040 159694616 -1294064641 2139999194</internalNodes>
<leafValues>
-5.0468754768371582e-01 3.4012636542320251e-01</leafValues></_>
<_>
<internalNodes>
0 -1 68 -104141110 -680827386 1995132851 -771791126
-805863425 -830722433 1196418559 -1010052981</internalNodes>
<leafValues>
-4.0247300267219543e-01 4.3415176868438721e-01</leafValues></_></weakClassifiers></_>
<!-- stage 12 -->
<_>
<maxWeakCount>9</maxWeakCount>
<stageThreshold>-1.9237215518951416e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 54 1413290975 -545156659 1762334687 995038615
-1182692869 -28249912 1821541343 -1079362594</internalNodes>
<leafValues>
-6.6381055116653442e-01 2.0693928003311157e-01</leafValues></_>
<_>
<internalNodes>
0 -1 42 -109322241 1901183449 -402552948 -12846715
-254880830 -238557903 -423887388 -100666383</internalNodes>
<leafValues>
-5.0527763366699219e-01 3.7808817625045776e-01</leafValues></_>
<_>
<internalNodes>
0 -1 75 -134421258 -607673390 1476174026 -539383820
-1617971461 -1156643126 -1778528769 -618974305</internalNodes>
<leafValues>
-4.0830761194229126e-01 4.5279026031494141e-01</leafValues></_>
<_>
<internalNodes>
0 -1 10 -295002612 -1077350325 1608785181 1606605447
-289670661 -354703719 -1915751721 402921239</internalNodes>
<leafValues>
-6.6798114776611328e-01 2.7213498950004578e-01</leafValues></_>
<_>
<internalNodes>
0 -1 64 -881856086 1245839822 1690357408 1846439984
-341085116 50727050 45514960 -207634376</internalNodes>
<leafValues>
-5.0356233119964600e-01 3.6370992660522461e-01</leafValues></_>
<_>
<internalNodes>
0 -1 1 -606082066 -1265701494 -1056798134 -1031390972
-880152291 1073768584 272887680 1893072868</internalNodes>
<leafValues>
-5.9699869155883789e-01 2.9342302680015564e-01</leafValues></_>
<_>
<internalNodes>
0 -1 78 21984971 1535111923 325570343 -149214718 -2105559317
1757475362 -67371041 -70256225</internalNodes>
<leafValues>
-3.7804242968559265e-01 5.3985476493835449e-01</leafValues></_>
<_>
<internalNodes>
0 -1 24 -904405842 -1866599595 -1878614625 848639499
-502574588 -2096331903 -959214770 990902271</internalNodes>
<leafValues>
-5.5267244577407837e-01 3.5786947607994080e-01</leafValues></_>
<_>
<internalNodes>
0 -1 30 -1029177089 1587125753 2012491709 -235919449
-34069603 -146812932 -58834961 -80475869</internalNodes>
<leafValues>
-3.6617991328239441e-01 5.0907015800476074e-01</leafValues></_></weakClassifiers></_></stages>
<features>
<_>
<rect>
0 0 15 2</rect></_>
<_>
<rect>
0 1 1 5</rect></_>
<_>
<rect>
0 3 1 2</rect></_>
<_>
<rect>
0 4 1 3</rect></_>
<_>
<rect>
0 7 1 2</rect></_>
<_>
<rect>
0 7 2 3</rect></_>
<_>
<rect>
0 8 1 2</rect></_>
<_>
<rect>
0 13 20 1</rect></_>
<_>
<rect>
1 1 3 3</rect></_>
<_>
<rect>
1 1 7 3</rect></_>
<_>
<rect>
2 0 2 5</rect></_>
<_>
<rect>
2 0 7 4</rect></_>
<_>
<rect>
2 0 10 3</rect></_>
<_>
<rect>
2 0 14 3</rect></_>
<_>
<rect>
2 1 3 5</rect></_>
<_>
<rect>
2 9 12 2</rect></_>
<_>
<rect>
2 10 20 2</rect></_>
<_>
<rect>
3 0 4 3</rect></_>
<_>
<rect>
3 0 6 3</rect></_>
<_>
<rect>
3 0 11 1</rect></_>
<_>
<rect>
3 4 14 3</rect></_>
<_>
<rect>
3 6 3 3</rect></_>
<_>
<rect>
4 1 3 1</rect></_>
<_>
<rect>
4 4 4 4</rect></_>
<_>
<rect>
4 9 6 2</rect></_>
<_>
<rect>
5 1 3 3</rect></_>
<_>
<rect>
5 13 12 1</rect></_>
<_>
<rect>
7 1 2 5</rect></_>
<_>
<rect>
7 4 2 4</rect></_>
<_>
<rect>
7 13 9 1</rect></_>
<_>
<rect>
7 13 12 1</rect></_>
<_>
<rect>
8 3 7 4</rect></_>
<_>
<rect>
8 6 2 3</rect></_>
<_>
<rect>
8 12 18 1</rect></_>
<_>
<rect>
9 0 2 3</rect></_>
<_>
<rect>
9 4 1 3</rect></_>
<_>
<rect>
9 4 2 4</rect></_>
<_>
<rect>
10 4 6 3</rect></_>
<_>
<rect>
10 13 7 1</rect></_>
<_>
<rect>
11 3 5 4</rect></_>
<_>
<rect>
12 2 5 4</rect></_>
<_>
<rect>
12 10 3 2</rect></_>
<_>
<rect>
13 3 4 3</rect></_>
<_>
<rect>
13 3 4 4</rect></_>
<_>
<rect>
13 4 4 3</rect></_>
<_>
<rect>
14 2 4 4</rect></_>
<_>
<rect>
14 3 3 4</rect></_>
<_>
<rect>
14 4 4 3</rect></_>
<_>
<rect>
15 2 3 4</rect></_>
<_>
<rect>
15 3 3 4</rect></_>
<_>
<rect>
18 4 1 3</rect></_>
<_>
<rect>
19 0 4 4</rect></_>
<_>
<rect>
19 0 8 1</rect></_>
<_>
<rect>
20 0 5 1</rect></_>
<_>
<rect>
21 1 5 1</rect></_>
<_>
<rect>
21 1 14 1</rect></_>
<_>
<rect>
21 13 7 1</rect></_>
<_>
<rect>
22 0 11 1</rect></_>
<_>
<rect>
23 0 9 1</rect></_>
<_>
<rect>
24 0 13 1</rect></_>
<_>
<rect>
27 0 8 1</rect></_>
<_>
<rect>
28 3 2 3</rect></_>
<_>
<rect>
28 4 2 4</rect></_>
<_>
<rect>
30 4 2 4</rect></_>
<_>
<rect>
30 5 1 2</rect></_>
<_>
<rect>
30 13 7 1</rect></_>
<_>
<rect>
32 13 10 1</rect></_>
<_>
<rect>
33 4 2 3</rect></_>
<_>
<rect>
36 1 2 2</rect></_>
<_>
<rect>
36 1 4 2</rect></_>
<_>
<rect>
37 4 2 4</rect></_>
<_>
<rect>
39 4 2 4</rect></_>
<_>
<rect>
39 6 2 3</rect></_>
<_>
<rect>
41 0 4 2</rect></_>
<_>
<rect>
41 4 2 4</rect></_>
<_>
<rect>
44 10 3 2</rect></_>
<_>
<rect>
45 1 3 2</rect></_>
<_>
<rect>
47 4 2 3</rect></_>
<_>
<rect>
48 0 4 3</rect></_>
<_>
<rect>
52 2 2 4</rect></_>
<_>
<rect>
56 3 2 4</rect></_>
<_>
<rect>
61 2 1 3</rect></_>
<_>
<rect>
61 2 1 4</rect></_>
<_>
<rect>
61 8 1 2</rect></_></features></cascade>
</opencv_storage>

BIN
model/char_chi_sim.h5 View File


BIN
model/char_judgement.h5 View File


BIN
model/char_judgement1.h5 View File


BIN
model/char_rec.h5 View File


BIN
model/model12.h5 View File


BIN
model/ocr_plate_all_gru.h5 View File


BIN
model/ocr_plate_all_w_rnn_2.h5 View File


BIN
model/plate_type.h5 View File


+ 0
- 28
wxpy_uploader.py View File

@@ -1,28 +0,0 @@
#coding=utf-8

from wxpy import *
import numpy
import cv2
import time
import os
from hyperlpr import pipline

def recognize(filename):
image = cv2.imread(filename)
return pipline.RecognizePlateJson(image)

bot = Bot(console_qr=True, cache_path=True)

@bot.register(Friend,PICTURE)
def pr_msg(msg):
image_name = msg.file_name
friend = msg.chat
print(msg.chat)
print('接收图片')
# face(image_name)
msg.get_file('' + msg.file_name)
json_text = recognize(image_name)
msg.reply(json_text)
msg.reply_image("0.jpg")
os.remove(image_name)
embed()

Loading…
Cancel
Save