diff --git a/easyPR-doc/algorithm.md b/easyPR-doc/algorithm.md new file mode 100644 index 00000000..8fa945e6 --- /dev/null +++ b/easyPR-doc/algorithm.md @@ -0,0 +1,4 @@ + - NMS(非极大值抑制) + - 选取邻近区域中得分最高的矩形块,以区分多个矩形重叠的情况 + - SVM(支持向量机) + - diff --git a/easyPR-doc/classDemo.md b/easyPR-doc/classDemo.md new file mode 100644 index 00000000..9bcd3898 --- /dev/null +++ b/easyPR-doc/classDemo.md @@ -0,0 +1,9 @@ +### Class + +#### Properties + +#### Functions + +*** + +*** diff --git a/easyPR-doc/core/chars_identify.md b/easyPR-doc/core/chars_identify.md new file mode 100644 index 00000000..a5d4e2e9 --- /dev/null +++ b/easyPR-doc/core/chars_identify.md @@ -0,0 +1,34 @@ +### Class CharsIdentify + +#### Properties + - (private:) + - [`annCallback extractFeature`](#extractFeature) + - [`static CharsIdentify* instance_`](#instance_) + - [`cv::Ptr ann_`](#ann_) + - [`cv::Ptr annChinese_`](#annChinese_) + - [`cv::Ptr annGray_`](#annGray_) + - [`std::shared_ptr kv_`](#kv_) + +#### Functions + - (public:) + - [`static CharsIdentify* instance()`](#instance) + - [`int classify(cv::Mat f, float& maxVal, bool isChinses = false, bool isAlphabet = false)`](#classify1) + - [`void classify(cv::Mat featureRows, std::vector& out_maxIndexs,std::vector& out_maxVals, std::vector isChineseVec)`](#classify2) + - [`void classify(std::vector& charVec)`](#classify3) + - [`void classifyChinese(std::vector& charVec)`](#classifyChinese) + - [`void classifyChineseGray(std::vector& charVec)`](#classifyChineseGray) + - [`std::pair identify(cv::Mat input, bool isChinese = false, bool isAlphabet = false)`](#identify1) + - [`int identify(std::vector inputs, std::vector>& outputs,std::vector isChineseVec)`](#identify2) + - [`std::pair identifyChinese(cv::Mat input, float& result, bool& isChinese)`](#identifyChinese) + - [`std::pair identifyChineseGray(cv::Mat input, float& result, bool& isChinese)`](#identifyChineseGray) + - [`bool isCharacter(cv::Mat input, std::string& label, float& maxVal, bool isChinese = false)`](#isCharacter) + - [`void LoadModel(std::string path)`](#LoadModel) + - [`void LoadChineseModel(std::string path)`](#LoadChineseModel) + - [`void LoadGrayChANN(std::string path)`](#LoadGrayChANN) + - [`void LoadChineseMapping(std::string path)`](#LoadChineseMapping) + - (private:) + - [`CharsIdentify()`](#CharsIdentify) + +*** + +*** diff --git a/easyPR-doc/core/feature.md b/easyPR-doc/core/feature.md new file mode 100644 index 00000000..d51fd9ce --- /dev/null +++ b/easyPR-doc/core/feature.md @@ -0,0 +1,85 @@ +### feature + +#### Functions + - [`cv::Mat getHistogram(cv::Mat in)`](#getHistogram) + - [`typedef void (*svmCallback)(const cv::Mat& image, cv::Mat& features)`](#svmCallback) + - [`typedef void (*annCallback)(const cv::Mat& image, cv::Mat& features)`](#annCallback) + - [`void getGrayPlusProject(const cv::Mat& grayChar, cv::Mat& features)`](#getGrayPlusProject) + - [`void getHistogramFeatures(const cv::Mat& image, cv::Mat& features)`](#getHistogramFeatures) + - [`void getSIFTFeatures(const cv::Mat& image, cv::Mat& features)`](#getSIFTFeatures) + - [`void getHOGFeatures(const cv::Mat& image, cv::Mat& features)`](#getHOGFeatures) + - [`void getHSVHistFeatures(const cv::Mat& image, cv::Mat& features)`](#getHSVHistFeatures) + - [`void getLBPFeatures(const cv::Mat& image, cv::Mat& features)`](#getLBPFeatures) + - [`void getColorFeatures(const cv::Mat& src, cv::Mat& features)`](#getColorFeatures) + - [`void getHistomPlusColoFeatures(const cv::Mat& image, cv::Mat& features)`](#getHistomPlusColoFeatures) + - [`cv::Mat charFeatures(cv::Mat in, int sizeData)`](#charFeatures) + - [`cv::Mat charFeatures2(cv::Mat in, int sizeData)`](#charFeatures2) + - [`void getLBPplusHistFeatures(const cv::Mat& image, cv::Mat& features)`](#getLBPplusHistFeatures) + - [`void getGrayCharFeatures(const cv::Mat& grayChar, cv::Mat& features)`](#getGrayCharFeatures) + - [`void getGrayPlusLBP(const Mat& grayChar, Mat& features)`](#getGrayPlusLBP) + +*** + +#### cv::Mat getHistogram(cv::Mat in) + - 获得车牌的特征数 + + +#### typedef void (*svmCallback)(const cv::Mat& image, cv::Mat& features) + - EasyPR的getFeatures回调函数 + - 用于从车牌的image生成svm的训练特征features + + +#### typedef void (*annCallback)(const cv::Mat& image, cv::Mat& features) + - EasyPR的getFeatures回调函数 + - convert from images to features used by gray char ann + + +#### void getGrayPlusProject(const cv::Mat& grayChar, cv::Mat& features) + - gray and project feature + + +#### void getHistogramFeatures(const cv::Mat& image, cv::Mat& features) + - EasyPR的getFeatures回调函数 + - 本函数是获取垂直和水平的直方图图值 + + +#### void getSIFTFeatures(const cv::Mat& image, cv::Mat& features) + - 本函数是获取SIFT特征子 + + +#### void getHOGFeatures(const cv::Mat& image, cv::Mat& features) + - 本函数是获取HOG特征子 + + +#### void getHSVHistFeatures(const cv::Mat& image, cv::Mat& features) + - 本函数是获取HSV空间量化的直方图特征子 + + +#### void getLBPFeatures(const cv::Mat& image, cv::Mat& features) + - LBP feature + + +#### void getColorFeatures(const cv::Mat& src, cv::Mat& features) + - color feature + + +#### void getHistomPlusColoFeatures(const cv::Mat& image, cv::Mat& features) + - color feature and histom + + +#### cv::Mat charFeatures(cv::Mat in, int sizeData) + - get character feature + + +#### cv::Mat charFeatures2(cv::Mat in, int sizeData) + - get character feature + + +#### void getLBPplusHistFeatures(const cv::Mat& image, cv::Mat& features) + - LBP feature + Histom feature + + +#### void getGrayCharFeatures(const cv::Mat& grayChar, cv::Mat& features) + + +#### void getGrayPlusLBP(const Mat& grayChar, Mat& features) diff --git a/easyPR-doc/core/plate.md b/easyPR-doc/core/plate.md new file mode 100644 index 00000000..6a13154a --- /dev/null +++ b/easyPR-doc/core/plate.md @@ -0,0 +1,16 @@ +### Class + +#### Properties + - (private:) + - [`Mat m_plateMat`](#m_plateMat) + - [`RotatedRect m_platePos`](#m_platePos) + - [`double m_score`](#m_score) + +#### Functions + +*** + +####double m_score + - 保存了`SVM`后的分数,越大证明越可能是车牌 + +*** diff --git a/easyPR-doc/core/plate_detect.md b/easyPR-doc/core/plate_detect.md new file mode 100644 index 00000000..a789f78c --- /dev/null +++ b/easyPR-doc/core/plate_detect.md @@ -0,0 +1,29 @@ +### Class CPlateDetect + +#### Properties + - (priavte:) + - [`int m_maxPlates`](#m_maxPlates) + - [`CPlateLocate* m_plateLocate`](#m_plateLocate) + - [`int m_type`](#m_type) + - [`static std::string m_pathSvm`](#m_pathSvm) + - [`bool m_showDetect`](#m_showDetect) + +#### Functions + - (public:) + - [`int plateDetect(Mat src, s td::vector &resultVec, int type,bool showDetectArea, int img_index = 0)`](#plateDetect1) + - [`int plateDetect(Mat src, std::vector &resultVec, int img_index = 0)`](#plateDetect2) + - [`void LoadSVM(std::string s)`](#LoadSVM) + +*** + +#### int m_maxPlates(`get|set`) + + +#### CPlateLocate* m_plateLocate + - 用于车牌定位的对象,完成了所有车牌定位的操作 + + +#### m_type(`set`) + - + +*** diff --git a/easyPR-doc/core/plate_judge.md b/easyPR-doc/core/plate_judge.md new file mode 100644 index 00000000..bd24c327 --- /dev/null +++ b/easyPR-doc/core/plate_judge.md @@ -0,0 +1,71 @@ +### Class PlateJudge + +#### Properties + - (private:) + - [`static PlateJudge* instance_`](#instance_) + - [`svmCallback extractFeature`](#extractFeature) + - [`cv::Ptr svm_`](#svm_) + +#### Functions + - (public:) + - [`static PlateJudge* instance()`](#instance) + - [`void LoadModel(std::string path)`](#LoadModel) + - [`int plateJudgeUsingNMS(const std::vector&, std::vector&, int maxPlates = 5)`](#plateJudgeUsingNMS) + - [`int plateSetScore(CPlate& plate)`](#plateSetScore) + - [`int plateJudge(const Mat& plateMat)`](#plateJudge1) + - [`int plateJudge(const std::vector &inVec,std::vector &resultVec)`](#plateJudge2) + - [`int plateJudge(const std::vector &inVec,std::vector &resultVec)`](#plateJudge3) + - [`void NMS(std::vector &inVec, std::vector &resultVec, double overlap)`](#NMS) + - [`int PlateJudge::plateJudgeUsingNMS(const std::vector &inVec, std::vector &resultVec, int maxPlates)`](#plateJudgeUsingNMS) + - (private:) + - [`PlateJudge()`](#PlateJudge) + +*** + +#### static PlateJudge* instance_ + - 静态变量`instance_`,用于单例模式 + +*** + +#### static PlateJudge* instance() + - 单例模式初始化方法,当`instance_`为`nullptr`时,初始化一个`PlateJudge` + - 返回`instance_` + + +#### PlateJudge() + - 加载`svm`的模型,在`config.h`中配置模型路径 + - 可选择是否使用`LBP`模型,因为暂时没有这个模型,所以使用的是`Hist` + + +#### void LoadModel(std::string path) + - 输入参数为路径`path` + - 如果`path`与默认`kDefaultSvmPath`路径不同,则加载`path`下的模型,如果相同,那么加载的模型和`kDefaultSvmPath`路径下的相同 + + +#### int plateSetScore(CPlate& plate) + - 这个函数通过`SVM`为输入的`CPlate`计算分数,小于0且越小为车牌的可能性越大 + - 方法判定`score`大于`0.5`的`CPlate`为不是车牌 + - 返回值为`0`表示是车牌,返回值为`-1`表示不是车牌 + + +#### int plateJudge(const Mat& plateMat) + - 调用`plateSetScore`得到`0/-1`并返回,`0`代表是车牌,`1`表示不是车牌 + + +#### int plateJudge(const std::vector &inVec,std::vector &resultVec) + - 输入为`Mat`的集合`inVec`,代表了需要判断的`Mat`的集合 + - 输出为`resultVec`,代表了所有可能是车牌的集合 + - `return 0` + + +#### int plateJudge(const std::vector &inVec,std::vector &resultVec) + - 输入为`CPlate`的集合`inVec`,代表了需要判断的`CPlate`的集合 + - 输出为`resultVec`,代表了所有可能是车牌的集合 + - 和`int plateJudge(const std::vector &inVec,std::vector &resultVec)`不同的是,在这个方法中会进行一次矩形的缩小再判断 + - `return 0` + + +#### void NMS(std::vector &inVec, std::vector &resultVec, double overlap) + + +#### int PlateJudge::plateJudgeUsingNMS(const std::vector &inVec, std::vector &resultVec, int maxPlates) diff --git a/easyPR-doc/core/plate_locate.md b/easyPR-doc/core/plate_locate.md new file mode 100644 index 00000000..b4109812 --- /dev/null +++ b/easyPR-doc/core/plate_locate.md @@ -0,0 +1,198 @@ +### Class CPlateLocate + +#### Properties + - (protected:) + - [`int m_GaussianBlurSize`](#m_GaussianBlurSize) + - [`int m_MorphSizeWidth`](#m_MorphSizeWidth) + - [`int m_MorphSizeHeight`](#m_MorphSizeHeight) + - [`float m_error`](#m_error) + - [`float m_aspect`](#m_aspect) + - [`int m_verifyMin`](#m_verifyMin) + - [`int m_verifyMax`](#m_verifyMax) + - [`int m_angle`](#m_angle) + - [`bool m_debug`](#m_debug) + +#### Functions + - (public:) + - [`bool CPlateLocate::verifySizes(RotatedRect mr)`](#verifySizes) + - [`int CPlateLocate::mserSearch(const Mat &src,vector &out,vector>& out_plateVec, bool usePlateMser, vector>& out_plateRRect,int img_index, bool showDebug)`](#mserSearch) + - [`void CPlateLocate::setLifemode(bool param)`](#setLifemode) + - [`int CPlateLocate::colorSearch(const Mat &src, const Color r, Mat &out,vector &outRects)`](#colorSearch) + - [`int CPlateLocate::sobelFrtSearch(const Mat &src,vector> &outRects)`](#sobelFrtSearch) + - [`int CPlateLocate::sobelOper(const Mat &in, Mat &out, int blurSize, int morphW, int morphH)`](#sobelOper) + - [`int CPlateLocate::deskew(const Mat &src, const Mat &src_b,vector &inRects,vector &outPlates, bool useDeteleArea, Color color)`](#deskew) + - [`bool CPlateLocate::isdeflection(const Mat &in, const double angle,double &slope)`](#isdeflection) + - [`bool CPlateLocate::rotation(Mat &in, Mat &out, const Size rect_size, const Point2f center, const double angle)`](#rotation) + - [`int CPlateLocate::plateColorLocate(Mat src, vector &candPlates,int index)`](#plateColorLocate) + - [`int CPlateLocate::plateMserLocate(Mat src, vector &candPlates, int img_index)`](#plateMserLocate) + - [`int CPlateLocate::sobelOperT(const Mat &in, Mat &out, int blurSize, int morphW,int morphH)`](#sobelOperT) + - [`int CPlateLocate::plateSobelLocate(Mat src, vector &candPlates,int index)`](#plateSobelLocate) + - [`int plateLocate(Mat, std::vector&, int = 0)`](#plateLocate1) + - [`int plateLocate(Mat, std::vector&, int = 0)`](#plateLocate2) + +*** + +#### int m_GaussianBlurSize(`get|set`) + - 高斯模糊所用的变量 + + +#### int m_MorphSizeWidth(`get|set`) + - 选定闭操作时的宽度 + + +#### int m_MorphSizeHeight(`get|set`) + - 选定闭操作时的长度 + + +#### float m_error(`get|set`) + - 允许的误差比 + + +#### float m_aspect(`get|set`) + - 车牌的长宽比 + + +#### int m_verifyMin(`set`) + - 筛选长宽比时的最小比例 + + +#### int m_verifyMax(`set`) + - 筛选长宽比时的最大比例 + + +#### int m_angle(`set`) + - 角度判断所用变量,正负超过这个角度的筛选出来的矩形都会被舍弃 + + +#### bool m_debug(`get|set`) + - 是否开启调试模式,0关闭,非0开启 + +*** + +#### bool CPlateLocate::verifySizes(RotatedRect mr) + - 输入旋转矩阵`mr` + - 函数内部设置了车牌的长宽比,通过长宽比来确定是不是车牌区域 + - 如果是,就返回true,否则就返回false + + +#### mserSearch(const Mat &src,vector &out,vector>& out_plateVec, bool usePlateMser, vector>& out_plateRRect,int img_index, bool showDebug) + - MSER区域提取原理:对图像取阈值在[0,255]之间的灰度化,当选取区域大小最为稳定的区域 + - mser in opencv + - 该函数对输入图像进行了`MSER`区域提取并输出 + + +#### void CPlateLocate::setLifemode(bool param) + - 如果有`param`传入,对`GaussianBlurSize`等一系列参数进行设置 + - 如果没有参数传入,就采用默认的参数 + + +#### int CPlateLocate::colorSearch(const Mat &src, const Color r, Mat &out,vector &outRects) + - 此函数的作用是:对于输入的图片`src`和颜色`r`,对`src`进行`r`的颜色匹配 + - 匹配流程为(省略具体参数) + - `colorMatch`:灰度化 + - `threshold`:二值化 + - `getStructuringElement`:规定`10x2`的`kernel` + - `morphologyEx`:针对`kernel`进行闭操作(先erode再dilate) + - `findContours`:闭操作完寻找轮廓以确定(蓝牌或黄牌)的区域 + - `out`里存储的是二值化结果,`outRects`里存储的是寻找到的区域 + - 调用`verifySizes`筛选出符合长宽比的区域 + - `return 0` + + +#### int CPlateLocate::sobelFrtSearch(const Mat &src,vector> &outRects) + - 输入: + - 原始图片`Mat &src` + - 输出集合`vector> &outRects` + - 执行过程 + - `sobelOper`:对图像进行预处理 + - `verifySizes`:对处理完的矩形集合进行筛选 + - 存储到outRects中 + + +#### int CPlateLocate::sobelOper(const Mat &in, Mat &out, int blurSize, int morphW, int morphH) + - 输入 + - 原始图片`Mat &in` + - 输出图片`Mat &out` + - 滤波窗口大小`blurSize` + - 闭操作`kernel`的宽度`morphW` + - 闭操作`kernel`的长度`morphH` + - 函数流程(省略具体参数): + - `GaussianBlur`:高斯滤波 + - `cvtColor`:灰度化 + - `Sobel`:sobel算子 + - `threshold`:二值化 + - `morphologyEx`:闭操作 + - 将结果`Mat`赋值到`out`里 + - `return 0` + + +#### int CPlateLocate::deskew(const Mat &src, const Mat &src_b,vector &inRects,vector &outPlates, bool useDeteleArea, Color color) + - 输入: + - `Mat &src`:原始图片 + - `Mat &src_b`:二值化后的图片 + - `vector &inRects`:闭操作识别颜色后的区域矩形块。 + - `vector &outPlates`:输出`vector` + - `bool useDeteleArea`: + - `Color color`:输入的颜色(蓝牌或者黄牌) + - 对识别的区域进行旋转后,删除其中角度大于`m_angle`的,并对矩形进行划线(0,255,255)(BGR),之后存储到`CPlate类型中`,再保存到`outPlates`中 + + +#### bool CPlateLocate::isdeflection(const Mat &in, const double angle,double &slope) + - 判断是否倾斜 + + +#### bool CPlateLocate::rotation(Mat &in, Mat &out, const Size rect_size, const Point2f center, const double angle) + - 判断旋转 + + +#### int CPlateLocate::plateColorLocate(Mat src, vector &candPlates,int index) + - 输入: + - `Mat src`:原始图片,`vector &candPlates`:存储颜色筛选完并旋转的图 + - 对`src`进行黄牌和蓝牌的并行计算 + - `return 0` + + +#### int CPlateLocate::plateMserLocate(Mat src, vector &candPlates, int img_index) + - 基本操作类似于`color`和`sobel` + - 采取的核心算法是`mser` + - 最终结果存储在`candPlates`中 + + +#### int CPlateLocate::sobelOperT(const Mat &in, Mat &out, int blurSize, int morphW,int morphH) + - 输入 + - 原始图片`Mat &in` + - 输出图片`Mat &out` + - 滤波窗口大小`blurSize` + - 闭操作`kernel`的宽度`morphW` + - 闭操作`kernel`的长度`morphH` + - 处理等同于[`sobelOper`](#sobelOper),只不过在每一步操作时,都将分步的图片存储到了`/resources/image/tmp/`目录下 + + +#### int CPlateLocate::plateSobelLocate(Mat src, vector &candPlates,int index) + - 采取sobel算子进行筛选 + - 输入 + - `Mat src`:输入图像 + - `vector &candPlates`:输出图像集合 + - 执行过程 + - `sobelFrtSearch`:矩形筛选 + - 放大矩形区域 + - 二次切割加入 + - `deskew`旋转筛选 + - 存储到`candPlates`中 + + +#### int plateLocate(Mat src, std::vector &resultVec, int index = 0) + - 输入`src`和`resultVec` + - 将`src`进行车牌定位检测,检测到的结果放置到`resultVec`中 + - 检测过程如下: + - `plateColorLocate` | `plateSobelLocate` | `plateMserLocate` + - 三种检测手段得到的车牌候选矩形都会被放进`resultVec`中 + - `resultVec`中放置的类型是`Mat` + - `return 0` + + +#### int plateLocate(Mat src, std::vector &resultVec, int = 0) + - 输入`src`和`resultVec` + - 将`src`进行车牌定位检测,检测到的结果放置到`resultVec`中 + - `resultVec`中放置的类型是`CPlate` + - `return 0` diff --git a/easyPR-doc/core/plate_recognize.md b/easyPR-doc/core/plate_recognize.md new file mode 100644 index 00000000..e69de29b diff --git a/easyPR-doc/easyPR.md b/easyPR-doc/easyPR.md new file mode 100644 index 00000000..82019f63 --- /dev/null +++ b/easyPR-doc/easyPR.md @@ -0,0 +1,10 @@ +### document index + - `class Kv` + - `class Utils` + - `class Generator` + - `class plate` + - `class CPlateLocate` + - `class PlateJudge` + - `class CPlateDetect` + - `feature` + - `config.h`:配置文件 diff --git a/easyPR-doc/img/SVM.png b/easyPR-doc/img/SVM.png new file mode 100644 index 00000000..e3bda3d8 Binary files /dev/null and b/easyPR-doc/img/SVM.png differ diff --git a/easyPR-doc/test/main.md b/easyPR-doc/test/main.md new file mode 100644 index 00000000..e69de29b diff --git a/easyPR-doc/util/Kv.md b/easyPR-doc/util/Kv.md new file mode 100644 index 00000000..fd01d8f6 --- /dev/null +++ b/easyPR-doc/util/Kv.md @@ -0,0 +1,53 @@ +### Class Kv + +#### Properties + - [`std::map data_`](#data) + +#### Functions + - [`Kv()`](#Kv) + - [`void load(const std::string &file)`](#load) + - [`std::string get(const std::string &key)`](#get) + - [`void add(const std::string &key,const std::string &value)`](#add) + - [`void remove(const std::string &key)`](#remove) + - [`void clear()`](#clear) + +*** + + +#### std::map< std::string,std::string > data_ + - 存储了`map< string string >`类型的数据 + +*** + + +#### Kv() + - 无 + + +#### void load(const std::string &file) + - 参数为`file`,即要读入的文件名 + - 解析之前会先将`data_`清空,即调用`this.clear()` + - 内部解析文件,文件的存储格式都为`string(空格)string\n` + - 将`space`前的`string`存储在`data_`的第一个`string里`,将空格后的`string`存储在`data_`的第二个`string`里 + + +#### std::string get(const std::string &key) + - 参数为在`data_`中的`key` + - 返回值为`key`对应的`value` + - 当`value`不存在时,会打印`[Kv] cannot find ${key}`,并返回`""` + + +#### void add(const std::string &key,const std::string &value) + - 参数为`string key`和`string value` + - 在`data_`中添加`key:value` + - 如果在`data_`中已经存在`key`时,打印`[Kv] find duplicate: %s = %s , ignore\n` + + +#### void remove(const std::string &key) + - 参数为`string key` + - 删除`data_`中`key`为`string key`的值 + - 如果没有这个`key`,打印`[Kv] cannot find ${key}` + + +#### void clear() + - 执行`data_.clear()`,清空`data_` diff --git a/easyPR-doc/util/Utils.md b/easyPR-doc/util/Utils.md new file mode 100644 index 00000000..46975b28 --- /dev/null +++ b/easyPR-doc/util/Utils.md @@ -0,0 +1,84 @@ +### Class Utils + +#### Properties + - + +#### Functions + - [`static long getTimestamp()`](#getTimestamp) + - [`static std::string getFileName(const std::string &path,const bool postfix = false)`](#getFileName) + - [`static std::vector splitString(const std::string &str,const char delimiter)`](#splitString) + - [`static T min(const T &v1, const T &v2)`](#min) + - [`static std::vector getFiles(const std::string &folder,const bool all = true)`](#getFiles) + - [`static void print_str_lines(const char** lines)`](#print_str_lines1) + - [`static void print_str_lines(const std::initializer_list &lines)`](#print_str_lines2) + - [`static void print_file_lines(const std::string &file)`](#print_file_lines) + - [`static unsigned int levenshtein_distance(const T &s1, const T &s2)`](#levenshtein_distance) + - [`static bool mkdir(const std::string folder)`](#mkdir) + - [`static bool imwrite(const std::string &file, const cv::Mat &image)`](#imwrite) + - [`(private)static std::size_t get_last_slash(const std::string &path)`](#get_last_slash) + +*** + +*** + + +#### long getTimestamp() + - windows: + - 返回`cv::getTickCount()`,即系统启动到当前的时间 + - `cv::getTickCount()`经常用于`opencv`下计算代码运行时间 + - linux: + - 使用linux时间结构体`timespes`,`CLOCK_MONOTONIC`为系统启动时间 + - 以毫秒的形式返回系统启动到当前的时间 + - macOS: + - 使用了1970/1/1来代替计算时间 + + +#### std::string getFileName(const std::string &path,const bool postfix = false) + - 输入`string &path`:文件名,`bool postfix`:是否需要后缀 + - 返回文件名(是否有后缀取决于postfix的值) + + +#### static std::vector< std::string > splitString(const std::string &str,const char delimiter) + - 输入`string &str`和`const char delimiter`分隔符 + - 返回`vector`,存储了用分隔符分割的字符串 + + +#### static T min(const T &v1, const T &v2) + - 返回`(v1 < v2) ? v1 : v2`; + + +#### static std::vector< std::string > getFiles(const std::string &folder,const bool all = true) + - 输入`string &folder`:目录,`bool all`:是否搜索子目录 + - 返回`vector`:文件的集合 + + +#### static void print\_str\_lines(const char** lines) + - 打印行 + + +#### static void print\_str\_lines(const std::initializer_list &lines) + - 打印行 + + +#### static void print\_file\_lines(const std::string &file) + - 读取`file`中的内容,并打印 + + +#### static unsigned int levenshtein_distance(const T &s1, const T &s2) + - 输入两个`T`类型`&s1`和`&s2` + - 返回这两个数据的编辑距离(Levenshtein Distance),即从s1转化到s2需要的最小步数. + + +#### static bool mkdir(const std::string folder) + - 输入`string folder`:需要创建的目录 + - 返回:`bool`,表示创建成功或者失败 + + +#### static bool imwrite(const std::string &file, const cv::Mat &image) + - 输入`string &file`:路径,`Mat &image`:图片 + - 输出:是否存储成功 + + +#### std::size\_t get\_last\_slash(const std::string &path) + - 输入一个`string &path`,代表了路径 + - 返回路径`/`最后的文件名的位置 diff --git a/easyPR-doc/util/program_options.md b/easyPR-doc/util/program_options.md new file mode 100644 index 00000000..57eabf53 --- /dev/null +++ b/easyPR-doc/util/program_options.md @@ -0,0 +1,157 @@ +### Class: + - [Class Row](#Row) + - [Class Subroutine](#Subroutine) + - [Class Generator](#Generator) + + +### Class Row + +#### Properties + - `(private)`: + - [`bool require_value`](#require_value) + - [`std::string option_short`](#option_short) + - [`std::string option_long`](#option_long) + - [`std::string default_value`](#default_value) + - [`std::string description`](#description) + - `(public)`: + - [`enum Field { kShort, kLong, kDefault, kDescription }`](#Field) + - [`typedef std::initializer_list Order`](#Order) + +#### Functions + - `(public)`: + - [`Row()`](#Row) + - [`inline std::string oshort() const { return option_short; }`](#oshort_get) + - [`inline std::string olong() const { return option_long; }`](#olong_get) + - [`inline std::string value() const { return default_value; }`](#value_get) + - [`inline std::string desc() const { return description; }`](#desc_get) + - [`inline bool required() const { return require_value; }`](#required_get) + - [`inline void oshort(const std::string& oshort) { option_short = oshort; }`](#oshort_set) + - [`inline void olong(const std::string& olong) { option_long = olong; }`](#olong_set) + - [`inline void value(const std::string& value) { default_value = value; }`](#value_set) + - [`inline void desc(const std::string& desc) { description = desc; }`](#desc_set) + - [`inline void required(bool required) { require_value = required; }`](#required_set) +*** + - +*** + + +### Class Subroutine + +#### Properties + - `(public)`: + - [`typedef std::vector Usages`](#Usages) + - [`typedef std::initializer_list TemplateValue`](#TemplateValue) + - [`typedef std::vector TemplateValues`](#TemplateValues) + - `(private)`: + - [`Usages usages_`](#usages_) + - [`TemplateValues templates_`](#templates_) + - [`const char* first_line_`](#first_line_) + - [`const char* description_`](#description_) + - [`std::string name_`](#name_) + - [`std::string template_str_`](#template_str_) + - [`Row::Order order_`](#order_) + +#### Functions + - `(public)`: + - [`Subroutine()`](#Subroutine1) + - [`Subroutine(const char* name, const char* description)`](#Subroutine2) + - [`inline void add_usage_line(const Row& row) { usages_.push_back(row); }`](#add_usage_line1) + - [`inline void add_usage_line(const TemplateValue& row) {templates_.push_back(row);}`](#add_usage_line2) + - [`inline void set_first_line(const char* line) { first_line_ = line; }`](#set_first_line) + - [`inline void set_description(const char* desc) { description_ = desc; }`](#set_description) + - [`inline void set_template(const char* tstr, const Row::Order& order)`](#set_template) + - [`inline std::string to_string()`](#to_string) + - [`inline std::string get_name() const { return name_; }`](#get_name) + - [`inline const char* get_description() const { return description_; }`](#get_description) + - [`inline const char* get_first_line() const { return first_line_; }`](#get_first_line) + - [`inline Usages::iterator begin() { return usages_.begin(); }`](#begin) + - [`inline Usages::iterator end() { return usages_.end(); }`](#end) + - [`inline size_t size() { return usages_.size(); }`](#size) + - [`inline Row& at(size_t i) { return usages_.at(i); }`](#at) + - [`inline const Usages& get_usage() const { return usages_; }`](#get_usage) + - [`inline static const char* get_default_name() { return "EmptySubroutine"; }`](#get_default_name) + - `(private)`: + - [`friend std::ostream& operator<<(std::ostream& out, Subroutine& subroutine)`](#operator_subroutine) + - [`void print_with_row(std::ostream& out)`](#print_with_row) + - [`void print_with_template(std::ostream& out)`](#print_with_template) +*** + +*** + +#### Subroutine() + + +#### Subroutine(const char* name, const char* description) + - //need to confirm + + +### Class Generator + +#### Properties + - [`typedef std::map SubroutineCollection`](#SubroutineCollection) + - [`(private)const char kDelimiter`](#kDelimiter) + - [`(private)SubroutineCollection subroutines_`](#subroutines) + - [`(private)std::string current_subroutine_`](#current_subroutine_) + - [`(private)Parser* parser_`](#parser_) + +#### Functions + - (`public:`) + - [`Generator()`](#Generator) + - [`~Generator()`](#~Generator) + - [`Generator& make_usage(const char* first_line)`](#make_usage) + - [`Parser* make_parser()`](#make_parser) + - [`Generator& add_subroutine(const char* name)`](#add_subroutine1`) + - [`Generator& add_subroutine(const char* name, const char* description)`](#add_subroutine2) + - [`std::map get_subroutine_list()`](#get_subroutine_list) + - [`inline std::string to_string()`](#to_string) + - [`inline Generator& operator()(const char* option, const char* description)`](#operator1) + - [`inline Generator& operator()(const char* option, const char* default_value,const char* description)`](#operator2) + - [`inline Subroutine& operator()(const char* name)`](#operator3) + - [`inline Generator& make_template(const char* template_str,const Row::Order& order)`](#operator4) + - (`private:`) + - [`(private)inline Subroutine* get_subroutine()`](#get_subroutine) + - [`(private)friend std::ostream& operator<<(std::ostream& out, Generator& generator)`](#operator5) + - [`(private)bool add_usage_line(const char* option,const char* default_value,const char* description)`](#add_usage_line) + +*** + +#### typedef std::map SubroutineCollection + - 用于存储`[string:Subroutine]`的`map`:`SubroutineCollection` + + +#### (private)SubroutineCollection subroutines_ + - `SubroutineCollection`类型,用来存储`Subroutine`集合 + + +#### (private)std::string current_subroutine_ + - 表示当前子程序 + + +#### (private)Parser* parser_ + - 在构造方法中被初始化为`nullptr` + +*** + +#### Generator() + - 向`subroutines_`添加一条["EmptySubroutine",new Subroutine("EmptySubroutine","")] + + +#### Generator& make_usage(const char* first_line) + - 获取当前`current_subroutine_`在`subroutines_`中对应的`Subroutine` + - 将上述的`Subroutine`的属性`first_line`设置成输入的参数`first_line` + - 返回`*this` + +#### Generator& add_subroutine(const char* name) + - 执行`add_subroutine(name, "")` + - 执行`return *this`,返回当前`Generator` + + +#### Generator& add_subroutine(const char* name, const char* description) + - 查找`subroutines_`中有没有子程序`name` + - 如果有,则`return *this` + - 如果没有,则将`[name:new Subroutine(name,description)]`添加到`subroutines_`中 + + +#### inline Subroutine* get_subroutine(){return subroutines_.at(current_subroutine_);} + - 输入`current_subroutine_` + - 返回`subroutines`中`current_subroutine_`对应的`Subroutine`,即当前指令