add windows vs project
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by 庾金科 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,0 +1,18 @@
|
||||
//
|
||||
// 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,0 +1,32 @@
|
||||
//
|
||||
// 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
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
namespace pr{
|
||||
class PipelinePR{
|
||||
public:
|
||||
GeneralRecognizer *generalRecognizer;
|
||||
PlateDetection *plateDetection;
|
||||
PlateSegmentation *plateSegmentation;
|
||||
FineMapping *fineMapping;
|
||||
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
|
||||
) {
|
||||
plateDetection = new PlateDetection(detector_filename);
|
||||
fineMapping = new FineMapping(finemapping_prototxt, finemapping_caffemodel);
|
||||
plateSegmentation = new PlateSegmentation(segmentation_prototxt, segmentation_caffemodel);
|
||||
generalRecognizer = new CNNRecognizer(charRecognization_proto, charRecognization_caffemodel);
|
||||
}
|
||||
|
||||
~PipelinePR() {
|
||||
|
||||
delete plateDetection;
|
||||
delete fineMapping;
|
||||
delete plateSegmentation;
|
||||
delete generalRecognizer;
|
||||
}
|
||||
|
||||
std::vector<std::string> chars_code{ "京","沪","津","渝","冀","晋","蒙","辽","吉","黑","苏","浙","皖","闽","赣","鲁","豫","鄂","湘","粤","桂","琼","川","贵","云","藏","陕","甘","青","宁","新","0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z" };
|
||||
|
||||
std::vector<std::string> plateRes;
|
||||
std::vector<PlateInfo> RunPiplineAsImage(cv::Mat plateImage) {
|
||||
std::vector<PlateInfo> results;
|
||||
std::vector<pr::PlateInfo> plates;
|
||||
plateDetection->plateDetectionRough(plateImage, plates);
|
||||
|
||||
for (pr::PlateInfo plateinfo : plates) {
|
||||
|
||||
cv::Mat image_finemapping = plateinfo.getPlateImage();
|
||||
image_finemapping = fineMapping->FineMappingVertical(image_finemapping);
|
||||
image_finemapping = pr::fastdeskew(image_finemapping, 5);
|
||||
image_finemapping = fineMapping->FineMappingHorizon(image_finemapping, 2, 5);
|
||||
cv::resize(image_finemapping, image_finemapping, cv::Size(136, 36));
|
||||
plateinfo.setPlateImage(image_finemapping);
|
||||
std::vector<cv::Rect> rects;
|
||||
plateSegmentation->segmentPlatePipline(plateinfo, 1, rects);
|
||||
plateSegmentation->ExtractRegions(plateinfo, rects);
|
||||
cv::copyMakeBorder(image_finemapping, image_finemapping, 0, 0, 0, 20, cv::BORDER_REPLICATE);
|
||||
|
||||
plateinfo.setPlateImage(image_finemapping);
|
||||
generalRecognizer->SegmentBasedSequenceRecognition(plateinfo);
|
||||
plateinfo.decodePlateNormal(chars_code);
|
||||
results.push_back(plateinfo);
|
||||
std::cout << plateinfo.getPlateName() << std::endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// for (auto str:results) {
|
||||
// std::cout << str << std::endl;
|
||||
// }
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif //SWIFTPR_PIPLINE_H
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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);
|
||||
// std::vector<pr::PlateInfo> plateDetectionRough(cv::Mat InputImage,int min_w= 60,int max_h = 400);
|
||||
|
||||
|
||||
// std::vector<pr::PlateInfo> plateDetectionRoughByMultiScaleEdge(cv::Mat InputImage);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
cv::CascadeClassifier cascade;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}// namespace pr
|
||||
|
||||
#endif //SWIFTPR_PLATEDETECTION_H
|
||||
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// 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};
|
||||
|
||||
|
||||
class PlateInfo {
|
||||
public:
|
||||
std::vector<std::pair<CharType,cv::Mat>> plateChars;
|
||||
std::vector<std::pair<CharType,cv::Mat>> plateCoding;
|
||||
|
||||
float confidence = 0;
|
||||
|
||||
|
||||
PlateInfo(const cv::Mat &plateData, std::string plateName, cv::Rect plateRect, PlateColor plateType) {
|
||||
licensePlate = plateData;
|
||||
name = plateName;
|
||||
ROI = plateRect;
|
||||
Type = plateType;
|
||||
}
|
||||
PlateInfo(const cv::Mat &plateData, cv::Rect plateRect, PlateColor plateType) {
|
||||
licensePlate = plateData;
|
||||
ROI = plateRect;
|
||||
Type = plateType;
|
||||
}
|
||||
PlateInfo(const cv::Mat &plateData, cv::Rect plateRect) {
|
||||
licensePlate = plateData;
|
||||
ROI = plateRect;
|
||||
}
|
||||
PlateInfo() {
|
||||
|
||||
}
|
||||
|
||||
cv::Mat getPlateImage() {
|
||||
return licensePlate;
|
||||
}
|
||||
|
||||
void setPlateImage(cv::Mat plateImage){
|
||||
licensePlate = plateImage;
|
||||
}
|
||||
|
||||
cv::Rect getPlateRect() {
|
||||
return ROI;
|
||||
}
|
||||
|
||||
void setPlateRect(cv::Rect plateRect) {
|
||||
ROI = plateRect;
|
||||
}
|
||||
cv::String getPlateName() {
|
||||
return name;
|
||||
|
||||
}
|
||||
void setPlateName(cv::String plateName) {
|
||||
name = plateName;
|
||||
}
|
||||
int getPlateType() {
|
||||
return Type;
|
||||
}
|
||||
|
||||
void appendPlateChar(const std::pair<CharType,cv::Mat> &plateChar)
|
||||
{
|
||||
plateChars.push_back(plateChar);
|
||||
}
|
||||
|
||||
void appendPlateCoding(const std::pair<CharType,cv::Mat> &charProb){
|
||||
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) {
|
||||
float *prob = (float *)plate.second.data;
|
||||
if(plate.first == CHINESE) {
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
if(plate.first == LETTER) {
|
||||
decode += mappingTable[std::max_element(prob+41,prob+65)- prob];
|
||||
confidence+=*std::max_element(prob+41,prob+65);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
name = decode;
|
||||
|
||||
confidence/=7;
|
||||
|
||||
return decode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
cv::Mat licensePlate;
|
||||
cv::Rect ROI;
|
||||
std::string name;
|
||||
PlateColor Type;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SWIFTPR_PLATEINFO_H
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Created by 庾金科 on 16/10/2017.
|
||||
//
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// 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;
|
||||
void SegmentBasedSequenceRecognition(PlateInfo &plateinfo);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif //SWIFTPR_RECOGNIZER_H
|
||||
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// 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());
|
||||
//
|
||||
// cv::imshow("imagex",test);
|
||||
// cv::waitKey(0);
|
||||
|
||||
}
|
||||
// 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
|
||||
Reference in New Issue
Block a user