* change better mser to mser2, which combine yellow and blue plate detect in one process.

v1.6alpha
liuruoze 9 years ago
parent 297c54f337
commit 045ed78542

@ -27,6 +27,8 @@ class CharsIdentify {
bool isCharacter(cv::Mat input, std::string& label, float& maxVal, bool isChinese = false);
void LoadModel(std::string path);
void LoadChineseModel(std::string path);
private:
CharsIdentify();

@ -19,8 +19,8 @@ namespace easypr {
Mat colorMatch(const Mat& src, Mat& match, const Color r,
const bool adaptive_minsv);
Mat mserMatch(const Mat& src, Mat& match, const Color r,
std::vector<RotatedRect>& plateRect, std::vector<Rect>& out_charRect);
//Mat mserMatch(const Mat& src, Mat& match, const Color r,
// std::vector<RotatedRect>& plateRect, std::vector<Rect>& out_charRect);
//! 判断一个车牌的颜色
//! 输入车牌mat与颜色模板
@ -83,8 +83,8 @@ Mat scaleImage(const Mat& image, const Size& maxSize, double& scale_ratio);
RotatedRect scaleBackRRect(const RotatedRect& rr, const float scale_ratio);
//! use verify size to first generate char candidates
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& plateVec, Color color,
bool usePlateMser, std::vector<RotatedRect>& out_plateRRect, int index = 0, bool showDebug = false);
void mserCharMatch(const Mat &src, std::vector<Mat> &match, std::vector<CPlate>& out_plateVec_blue, std::vector<CPlate>& out_plateVec_yellow,
bool usePlateMser, std::vector<RotatedRect>& out_plateRRect_blue, std::vector<RotatedRect>& out_plateRRect_yellow, int index = 0, bool showDebug = false);
bool computeIOU(RotatedRect rrect1, RotatedRect rrect2, const Mat& img, float thresh);

@ -86,8 +86,8 @@ class CPlateLocate {
std::vector<RotatedRect>& outRects, int index = 0);
//! mser search
int mserSearch(const Mat &src, const Color color, Mat &out,
vector<CPlate>& out_plateVec, bool usePlateMser, vector<RotatedRect>& out_plateRRect,
int mserSearch(const Mat &src, vector<Mat>& out,
vector<vector<CPlate>>& out_plateVec, bool usePlateMser, vector<vector<RotatedRect>>& out_plateRRect,
int img_index = 0, bool showDebug = false);
//! 未使用函数与代码

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because it is too large Load Diff

@ -2226,3 +2226,33 @@ Recall:69.6127%, Precise:85.905%, Fscore:76.9054%.
Recall:76.1731%, Precise:84.3137%, Fscore:80.0369%.
0-error:62.4454%, 1-error:71.6157%, Chinese-precise:73.3624%
总时间:839秒, 平均执行时间:3.34263秒
2016-07-01 15:32:50
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.6296%, Precise:74.3677%, Fscore:74.4985%.
0-error:60.4444%, 1-error:70.2222%, Chinese-precise:72%
总时间:738秒, 平均执行时间:2.94024秒
2016-07-01 15:48:32
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:74.7588%, Precise:74.4956%, Fscore:74.627%.
0-error:57.7273%, 1-error:68.1818%, Chinese-precise:70%
总时间:841秒, 平均执行时间:3.3506秒
2016-07-01 16:03:55
总图片数:251, Plates count:290, 未定位车牌:63, 定位率:78.2759%
Recall:70.0679%, Precise:79.4528%, Fscore:74.4658%.
0-error:55.0239%, 1-error:65.5502%, Chinese-precise:67.4641%
总时间:541秒, 平均执行时间:2.15538秒
2016-07-01 16:21:15
总图片数:251, Plates count:290, 未定位车牌:49, 定位率:83.1034%
Recall:73.9864%, Precise:71.9741%, Fscore:72.9664%.
0-error:54.067%, 1-error:63.6364%, Chinese-precise:65.5502%
总时间:707秒, 平均执行时间:2.81673秒
2016-07-01 16:51:30
总图片数:251, Plates count:290, 未定位车牌:48, 定位率:83.4483%
Recall:74.9678%, Precise:73.4406%, Fscore:74.1963%.
0-error:58.6667%, 1-error:66.2222%, Chinese-precise:69.3333%
总时间:461秒, 平均执行时间:1.83665秒
2016-07-01 17:46:40
总图片数:50, Plates count:52, 未定位车牌:11, 定位率:78.8462%
Recall:70.6192%, Precise:70.1825%, Fscore:70.4002%.
0-error:59.4595%, 1-error:70.2703%, Chinese-precise:70.2703%
总时间:132秒, 平均执行时间:2.64秒

@ -23,8 +23,17 @@ namespace easypr {
}
void CharsIdentify::LoadModel(std::string path) {
ann_->clear();
ann_->ml::ANN_MLP::load<ml::ANN_MLP>(path);
if (path.c_str() != kDefaultAnnPath) {
ann_->clear();
ann_->ml::ANN_MLP::load<ml::ANN_MLP>(path);
}
}
void CharsIdentify::LoadChineseModel(std::string path) {
if (path.c_str() != kChineseAnnPath) {
annChinese_->clear();
annChinese_->ml::ANN_MLP::load<ml::ANN_MLP>(path);
}
}
void CharsIdentify::classify(cv::Mat featureRows, std::vector<int>& out_maxIndexs,

File diff suppressed because it is too large Load Diff

@ -13,14 +13,16 @@ namespace easypr {
}
PlateJudge::PlateJudge() {
//svm_ = ml::SVM::load<ml::SVM>(kDefaultSvmPath);
svm_ = ml::SVM::load<ml::SVM>(kLBPSvmPath);
svm_ = ml::SVM::load<ml::SVM>(kDefaultSvmPath);
//svm_ = ml::SVM::load<ml::SVM>(kLBPSvmPath);
extractFeature = getLBPFeatures;
}
void PlateJudge::LoadModel(std::string path) {
svm_->clear();
svm_->ml::SVM::load<ml::SVM>(path);
if (path.c_str() != kDefaultSvmPath) {
svm_->clear();
svm_->ml::SVM::load<ml::SVM>(path);
}
}
//! 对单幅图像进行SVM判断
@ -112,7 +114,7 @@ namespace easypr {
int num = inVec.size();
bool outputResult = false;
bool useCascadeJudge = false;
bool useCascadeJudge = true;
bool useShirkMat = true;
for (int j = 0; j < num; j++) {

File diff suppressed because it is too large Load Diff

@ -96,11 +96,14 @@ namespace easypr {
//pr.setDetectType(PR_DETECT_COLOR | PR_DETECT_SOBEL);
pr.setDetectType(PR_DETECT_CMSER);
CPlateDetect pd;
pd.setDetectType(PR_DETECT_CMSER);
//pd.setPDDebug(true);
pd.setDetectShow(true);
pd.setPDLifemode(true);
//CharsIdentify::instance()->LoadModel(kDefaultAnnPath);
//PlateJudge::instance()->LoadModel(kDefaultSvmPath);
//CPlateDetect pd;
//pd.setDetectType(PR_DETECT_CMSER);
////pd.setPDDebug(true);
//pd.setDetectShow(true);
//pd.setPDLifemode(true);
int size = files.size();

@ -63,15 +63,17 @@ Modifer:liuruoze
#include "opencv2/imgproc/imgproc_c.h"
#include <limits>
#include "mser2.hpp"
namespace cv
{
using std::vector;
class MSER_Impl : public MSER
class MSER_Impl2 : public MSER2
{
public:
struct Params
{
Params(bool _useOpt = false, bool _subPath = false, bool _realMSER = false, bool _usePrune = false,
@ -116,9 +118,9 @@ namespace cv
int edgeBlurSize;
};
explicit MSER_Impl(const Params& _params) : params(_params) {}
explicit MSER_Impl2(const Params& _params) : params(_params) {}
virtual ~MSER_Impl() {}
virtual ~MSER_Impl2() {}
void setDelta(int delta) { params.delta = delta; }
int getDelta() const { return params.delta; }
@ -546,12 +548,8 @@ namespace cv
Rect rect;
};
void detectRegions(InputArray image,
std::vector<std::vector<Point> >& msers,
std::vector<Rect>& bboxes);
void detect(InputArray _src, vector<KeyPoint>& keypoints, InputArray _mask);
void detectRegions(InputArray _src, vector<vector<Point>>& msers_blue, vector<Rect>& bboxes_blue,
vector<vector<Point>>& msers_yellow, vector<Rect>& bboxes_yellow);
void preprocess1(const Mat& img, int* level_size)
{
@ -747,19 +745,17 @@ namespace cv
vector<Pixel> pixbuf;
vector<Pixel*> heapbuf;
vector<CompHistory> histbuf;
Params params;
};
};
void MSER_Impl::detectRegions(InputArray _src, vector<vector<Point> >& msers, vector<Rect>& bboxes)
void MSER_Impl2::detectRegions(InputArray _src, vector<vector<Point>>& msers_blue, vector<Rect>& bboxes_blue,
vector<vector<Point>>& msers_yellow, vector<Rect>& bboxes_yellow)
{
Mat src = _src.getMat();
size_t npix = src.total();
msers.clear();
bboxes.clear();
if (npix == 0)
return;
@ -778,57 +774,30 @@ namespace cv
// dont need when plate is blue
preprocess1(src, level_size);
if (!params.pass2Only)
pass(src, msers, bboxes, size, level_size, 0);
pass(src, msers_yellow, bboxes_yellow, size, level_size, 0);
// brighter to darker (MSER-)
preprocess2(src, level_size);
pass(src, msers, bboxes, size, level_size, 255);
}
else
{
CV_Assert(src.type() == CV_8UC3 || src.type() == CV_8UC4);
//extractMSER_8uC3(src, msers, bboxes, params);
pass(src, msers_blue, bboxes_blue, size, level_size, 255);
}
}
void MSER_Impl::detect(InputArray _image, vector<KeyPoint>& keypoints, InputArray _mask)
{
vector<Rect> bboxes;
vector<vector<Point> > msers;
Mat mask = _mask.getMat();
detectRegions(_image, msers, bboxes);
int i, ncomps = (int)msers.size();
keypoints.clear();
for (i = 0; i < ncomps; i++)
{
Rect r = bboxes[i];
// TODO check transformation from MSER region to KeyPoint
RotatedRect rect = fitEllipse(Mat(msers[i]));
float diam = std::sqrt(rect.size.height*rect.size.width);
if (diam > std::numeric_limits<float>::epsilon() && r.contains(rect.center) &&
(mask.empty() || mask.at<uchar>(cvRound(rect.center.y), cvRound(rect.center.x)) != 0))
keypoints.push_back(KeyPoint(rect.center, diam));
}
}
Ptr<MSER> MSER::create(int _delta, int _min_area, int _max_area,
Ptr<MSER2> MSER2::create(int _delta, int _min_area, int _max_area,
double _max_variation, double _min_diversity,
int _max_evolution, double _area_threshold,
double _min_margin, int _edge_blur_size)
{
printf("better mser \n");
//printf("better mser 2 \n");
bool useOpt = true;
bool subPath = true;
bool realMSER = true;
bool usePrune = true;
return makePtr<MSER_Impl>(
MSER_Impl::Params(useOpt, subPath, realMSER, usePrune, _delta, _min_area, _max_area,
return makePtr<MSER_Impl2>(
MSER_Impl2::Params(useOpt, subPath, realMSER, usePrune, _delta, _min_area, _max_area,
_max_variation, _min_diversity,
_max_evolution, _area_threshold,
_min_margin, _edge_blur_size));

@ -0,0 +1,50 @@
#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__
#include "opencv2/features2d.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
#include <algorithm>
#ifdef HAVE_TEGRA_OPTIMIZATION
#include "opencv2/features2d/features2d_tegra.hpp"
#endif
#endif
#include "opencv2/imgproc/imgproc_c.h"
#include <limits>
namespace cv
{
using std::vector;
class CV_EXPORTS_W MSER2 : public Feature2D
{
public:
//! the full constructor
CV_WRAP static Ptr<MSER2> create(int _delta = 5, int _min_area = 60, int _max_area = 14400,
double _max_variation = 0.25, double _min_diversity = .2,
int _max_evolution = 200, double _area_threshold = 1.01,
double _min_margin = 0.003, int _edge_blur_size = 5);
CV_WRAP virtual void detectRegions(InputArray _src, vector<vector<Point>>& msers_blue, vector<Rect>& bboxes_blue,
vector<vector<Point>>& msers_yellow, vector<Rect>& bboxes_yellow) = 0;
CV_WRAP virtual void setDelta(int delta) = 0;
CV_WRAP virtual int getDelta() const = 0;
CV_WRAP virtual void setMinArea(int minArea) = 0;
CV_WRAP virtual int getMinArea() const = 0;
CV_WRAP virtual void setMaxArea(int maxArea) = 0;
CV_WRAP virtual int getMaxArea() const = 0;
CV_WRAP virtual void setPass2Only(bool f) = 0;
CV_WRAP virtual bool getPass2Only() const = 0;
};
}

@ -145,7 +145,6 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\core\better_mser.cpp" />
<ClCompile Include="..\src\core\chars_identify.cpp" />
<ClCompile Include="..\src\core\chars_recognise.cpp" />
<ClCompile Include="..\src\core\chars_segment.cpp" />
@ -167,6 +166,7 @@
<ClCompile Include="..\src\util\util.cpp" />
<ClCompile Include="..\thirdparty\LBP\helper.cpp" />
<ClCompile Include="..\thirdparty\LBP\lbp.cpp" />
<ClCompile Include="..\thirdparty\mser\mser2.cpp" />
<ClCompile Include="..\thirdparty\textDetect\erfilter.cpp" />
</ItemGroup>
<ItemGroup>
@ -196,6 +196,7 @@
<ClInclude Include="..\include\easypr\util\util.h" />
<ClInclude Include="..\thirdparty\LBP\helper.hpp" />
<ClInclude Include="..\thirdparty\LBP\lbp.hpp" />
<ClInclude Include="..\thirdparty\mser\mser2.hpp" />
<ClInclude Include="..\thirdparty\textDetect\erfilter.hpp" />
</ItemGroup>
<ItemGroup>

@ -108,9 +108,6 @@
<ClCompile Include="..\src\util\kv.cpp">
<Filter>源文件\util</Filter>
</ClCompile>
<ClCompile Include="..\src\core\better_mser.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="..\thirdparty\textDetect\erfilter.cpp">
<Filter>源文件\thirdparty</Filter>
</ClCompile>
@ -123,6 +120,9 @@
<ClCompile Include="..\src\core\params.cpp">
<Filter>源文件\core</Filter>
</ClCompile>
<ClCompile Include="..\thirdparty\mser\mser2.cpp">
<Filter>源文件\thirdparty</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\easypr\preprocess\deface.h">
@ -206,6 +206,9 @@
<ClInclude Include="..\include\easypr\core\params.h">
<Filter>头文件\easypr\core</Filter>
</ClInclude>
<ClInclude Include="..\thirdparty\mser\mser2.hpp">
<Filter>头文件\thirdparty</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE" />

Loading…
Cancel
Save