add LoadModel, maxPlates

v1.6alpha
liuruoze 9 years ago
parent 285fdc03b0
commit 68fc98414c

@ -1561,3 +1561,23 @@
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:330秒, 平均执行时间:1.65秒
2016-06-15 19:58:37
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:181秒, 平均执行时间:0.905秒
2016-06-15 20:13:59
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:181秒, 平均执行时间:0.905秒
2016-06-15 21:05:45
总图片数:50, 未识出图片:26, 定位率:48%
平均字符差距:2.45833, 完全匹配数:6, 完全匹配率:25%
总时间:456秒, 平均执行时间:9.12秒
2016-06-15 21:25:41
总图片数:200, 未识出图片:7, 定位率:96.5%
平均字符差距:0.689119, 完全匹配数:132, 完全匹配率:68.3938%
总时间:186秒, 平均执行时间:0.93秒
2016-06-15 21:51:53
总图片数:50, 未识出图片:18, 定位率:64%
平均字符差距:0, 完全匹配数:0, 完全匹配率:0%
总时间:273秒, 平均执行时间:5.46秒

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

@ -14,6 +14,13 @@ enum Color { BLUE, YELLOW, WHITE, UNKNOWN };
enum LocateType { SOBEL, COLOR, CMSER, OTHER };
enum
{
PR_DETECT_SOBEL = 0x01, /**Sobel detect typeusing twice Sobel */
PR_DETECT_COLOR = 0x02, /**Color detect type */
PR_DETECT_CMSER = 0x04, /**Character detect typeusing mser */
};
//! 根据一幅图像与颜色模板获取对应的二值图
//! 输入RGB图像, 颜色模板(蓝色、黄色)
//! 输出灰度图只有0和255两个值255代表匹配0代表不匹配

@ -12,13 +12,6 @@ class CPlateDetect {
~CPlateDetect();
enum
{
PR_DETECT_SOBEL = 0x01, /**Sobel detect typeusing twice Sobel */
PR_DETECT_COLOR = 0x02, /**Color detect type */
PR_DETECT_CMSER = 0x04, /**Character detect typeusing mser */
};
/** @brief Plate detect in an image.
The function detects plate in an image. It can use sobel, color, and character method or the combinations of them.
@ -29,9 +22,24 @@ class CPlateDetect {
@param showDetectArea
@param index
*/
int plateDetect(Mat src, std::vector<CPlate> &resultVec, int type = 0,
int plateDetect(Mat src, std::vector<CPlate> &resultVec, int type,
bool showDetectArea = true, int index = 0);
/** @brief Plate detect in an image.
The function detects plate in an image. It can use sobel, color, and character method or the combinations of them.
Use default m_type, it can use setDetectType() to set it;
@param src Source image.
@param resultVec Destination vector of CPlate.
@param showDetectArea
@param index
*/
int plateDetect(Mat src, std::vector<CPlate> &resultVec,
bool showDetectArea = true, int index = 0);
//! 展示中间的结果
int showResult(const Mat &result);
@ -52,6 +60,9 @@ class CPlateDetect {
inline bool getPDDebug() { return m_plateLocate->getDebug(); }
inline void setDetectType(int param) { m_type = param; }
//! 设置与读取变量
inline void setGaussianBlurSize(int param) {
@ -113,6 +124,11 @@ class CPlateDetect {
//! 车牌定位
CPlateLocate* m_plateLocate;
int m_type;
static std::string m_pathSvm;
};
}

@ -13,8 +13,10 @@ class PlateJudge {
//! 对多幅车牌进行SVM判断
void LoadModel(std::string path);
int plateJudge(const std::vector<CPlate> &, std::vector<CPlate> &);
int plateJudgeUsingNMS(const std::vector<CPlate> &, std::vector<CPlate> &);
int plateJudgeUsingNMS(const std::vector<CPlate> &, std::vector<CPlate> &, int maxPlates = 5);
//! 车牌判断

@ -38,6 +38,9 @@ namespace easypr {
//! 是否开启调试模式
inline void setDebug(bool param) { CPlateDetect::setPDDebug(param); }
inline void setDetectType(int param) { CPlateDetect::setDetectType(param); }
};
} /* \namespace easypr */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 323 KiB

File diff suppressed because it is too large Load Diff

@ -19,6 +19,11 @@ namespace easypr {
kv_->load("etc/province_mapping");
}
void CharsIdentify::LoadModel(std::string path) {
ann_->clear();
ann_->ml::ANN_MLP::load<ml::ANN_MLP>(path);
}
int CharsIdentify::classify(cv::Mat f, float& maxVal, bool isChinses){
int result = -1;

@ -803,11 +803,11 @@ Mat preprocessChar(Mat in, int char_size) {
Rect GetChineseRect(const Rect rectSpe) {
int height = rectSpe.height;
float newwidth = rectSpe.width * 1.2f;
float newwidth = rectSpe.width * 1.10f;
int x = rectSpe.x;
int y = rectSpe.y;
int newx = x - int(newwidth * 1.2);
int newx = x - int(newwidth * 1.10f);
newx = newx > 0 ? newx : 0;
Rect a(newx, y, int(newwidth), height);
@ -1007,14 +1007,14 @@ Mat mserMatch(const Mat &src, Mat &match, const Color r,
if (verifyCharSizes(rect)) {
float aspect = float(rect.width) / float(rect.height);
Mat region = image(rect);
Mat binary_region;
threshold(region, binary_region, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
//Mat region = image(rect);
//Mat binary_region;
//threshold(region, binary_region, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
Mat charInput = preprocessChar(binary_region, 20);
std::string label = "";
float maxVal = -2.f;
bool isCharacter = CharsIdentify::instance()->isCharacter(charInput, label, maxVal);
//Mat charInput = preprocessChar(binary_region, 20);
//std::string label = "";
//float maxVal = -2.f;
//bool isCharacter = CharsIdentify::instance()->isCharacter(charInput, label, maxVal);
if (1) {
//match(rect) = min(max(0, int(maxVal * 255)),255);

@ -6,9 +6,8 @@ namespace easypr {
CPlateDetect::CPlateDetect() {
m_plateLocate = new CPlateLocate();
// 默认EasyPR在一幅图中定位最多3个车
m_maxPlates = 3;
m_type = 0;
}
CPlateDetect::~CPlateDetect() { SAFE_RELEASE(m_plateLocate); }
@ -54,7 +53,7 @@ namespace easypr {
}
}
if (!type || type & PR_DETECT_CMSER)
if ( !type || type & PR_DETECT_CMSER)
{
m_plateLocate->plateMserLocate(src, mser_Plates, index);
@ -69,13 +68,18 @@ namespace easypr {
}
}
// 使用非极大值抑制来判断车牌
PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec);
PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec, m_maxPlates);
return 0;
}
int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec,
bool showDetectArea, int index) {
int result = plateDetect(src, resultVec, m_type, showDetectArea, index);
return result;
}
int CPlateDetect::showResult(const Mat &result) {
namedWindow("EasyPR", CV_WINDOW_AUTOSIZE);

@ -14,6 +14,11 @@ namespace easypr {
PlateJudge::PlateJudge() { svm_ = ml::SVM::load<ml::SVM>(kDefaultSvmPath); }
void PlateJudge::LoadModel(std::string path) {
svm_->clear();
svm_->ml::SVM::load<ml::SVM>(path);
}
//! 对单幅图像进行SVM判断
int PlateJudge::plateJudge(const Mat &inMat, int &result) {
@ -98,7 +103,7 @@ namespace easypr {
}
//! 使用非极大值抑制的车牌判断
int PlateJudge::plateJudgeUsingNMS(const std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec) {
int PlateJudge::plateJudgeUsingNMS(const std::vector<CPlate> &inVec, std::vector<CPlate> &resultVec, int maxPlates) {
std::vector<CPlate> plateVec;
int num = inVec.size();
@ -139,10 +144,22 @@ namespace easypr {
}
}
std::vector<CPlate> reDupPlateVec;
// 使用非极大值抑制来去除那些重叠的车牌
// overlap阈值设置为0.5
double overlap = 0.5;
NMS(plateVec, resultVec, overlap);
NMS(plateVec, reDupPlateVec, overlap);
std::vector<CPlate>::iterator it = reDupPlateVec.begin();
int count = 0;
for (; it != reDupPlateVec.end(); ++it) {
resultVec.push_back(*it);
count++;
if (count >= maxPlates)
break;
}
return 0;
}

@ -87,7 +87,7 @@ int CPlateLocate::mserSearch(const Mat &src, const Color r, Mat &out,
// width值对最终结果影响很大可以考虑进行多次colorSerch每次不同的值
// 另一种解决方案就是在结果输出到SVM之前进行线与角的再纠正
const int color_morph_width = 20;
const int color_morph_width = 30;
const int color_morph_height = 5;
std::vector<RotatedRect> plateRects;
@ -550,6 +550,10 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
Scalar(0, 255, 255), 1, 8);
}
// changed
// rotation = 90 - abs(roi_angle);
// rotation < m_angel;
// m_angle=60
if (roi_angle - m_angle < 0 && roi_angle + m_angle > 0) {
Rect_<float> safeBoundRect;
@ -595,7 +599,6 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
plate_mat.create(HEIGHT, WIDTH, TYPE);
// haitungaga添加删除非区域这个函数影响了25%的完整定位率
DeleteNotArea(deskew_mat);
// 这里对deskew_mat进行了一个筛选
@ -615,6 +618,12 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
CPlate plate;
plate.setPlatePos(roi_rect);
plate.setPlateMat(plate_mat);
if (0) {
imshow("plate_mat", plate_mat);
waitKey(0);
}
outPlates.push_back(plate);
}
}

@ -248,19 +248,20 @@ namespace easypr {
// 对图像进行统一缩放,确保图像不要过大
// 对速度提升帮助不大
int scale_size = 1600;
int scale_size = 1200;
double scale_ratio = 1;
Mat image = scaleImage(channelImage, Size(scale_size, scale_size), scale_ratio);
Mat result = image;
cvtColor(result, result, COLOR_GRAY2BGR);
int imageArea = image.rows * image.cols;
if (3 == flags[i]) {
mser = MSER::create(3, 30, int(0.25 * imageArea));
mser = MSER::create(3, 30, int(0.05 * imageArea));
}
else {
mser = MSER::create(1, 30, int(0.25 * imageArea));
mser = MSER::create(1, 30, int(0.05 * imageArea));
}
mser->detectRegions(image, all_contours[i], all_boxes[i]);
@ -399,7 +400,7 @@ namespace easypr {
//src = ret;
// 进行深度定位使用颜色信息与二次Sobel
int resultPD = plateDetect(src, plateVec, CPlateDetect::PR_DETECT_SOBEL | CPlateDetect::PR_DETECT_COLOR);
int resultPD = plateDetect(src, plateVec);
if (resultPD == 0) {
size_t num = plateVec.size();

@ -91,6 +91,9 @@ namespace easypr {
pr.setMaxPlates(4);
//pr.setDetectType(PR_DETECT_COLOR | PR_DETECT_SOBEL);
pr.setDetectType(PR_DETECT_CMSER);
int size = files.size();
if (0 == size) {

@ -110,12 +110,13 @@ int test_plate_recognize() {
CPlateRecognize pr;
pr.setLifemode(true);
pr.setDebug(true);
pr.setDetectType(easypr::PR_DETECT_CMSER);
//vector<string> plateVec;
vector<CPlate> plateVec;
int result = pr.plateRecognize(src, plateVec);
//int result = pr.plateRecognizeAsText(src, plateVec);
//int result = pr.plateRecognize(src, plateVec);
int result = pr.plateRecognizeAsText(src, plateVec);
if (result == 0) {
size_t num = plateVec.size();
for (size_t j = 0; j < num; j++) {

Loading…
Cancel
Save