* change accuracy test to mser test and show debug.

v1.6alpha
liuruoze 9 years ago
parent b8af57c3d8
commit 510f019cae

@ -1872,3 +1872,18 @@ Recall:0%, Precise:0%, Fscore:0%.
Recall:0%, Precise:0%, Fscore:0%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:385秒, 平均执行时间:7.7秒
2016-06-26 16:27:11
总图片数:200, Plates count:238, 未识出图片:25, 定位率:89.4958%
Recall:83.2581%, Precise:86.2716%, Fscore:84.7381%.
0-error:66.6667%, 1-error:76.5258%, Chinese-precise:78.8732%
总时间:201秒, 平均执行时间:1.005秒
2016-06-26 16:28:16
总图片数:50, Plates count:44, 未识出图片:25, 定位率:43.1818%
Recall:37.5998%, Precise:59.6161%, Fscore:46.115%.
0-error:15.7895%, 1-error:21.0526%, Chinese-precise:21.0526%
总时间:49秒, 平均执行时间:0.98秒
2016-06-26 16:43:33
总图片数:50, Plates count:44, 未识出图片:35, 定位率:20.4545%
Recall:18.4055%, Precise:57.8458%, Fscore:27.9255%.
0-error:22.2222%, 1-error:22.2222%, Chinese-precise:22.2222%
总时间:276秒, 平均执行时间:5.52秒

@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include "opencv2/opencv.hpp"
#include "easypr/config.h"
namespace easypr {

@ -3,6 +3,19 @@
namespace easypr {
enum Color { BLUE, YELLOW, WHITE, UNKNOWN };
enum LocateType { SOBEL, COLOR, CMSER, OTHER };
enum CharSearchDirection { LEFT, RIGHT };
enum
{
PR_DETECT_SOBEL = 0x01, /**Sobel detect type£¬using twice Sobel */
PR_DETECT_COLOR = 0x02, /**Color detect type */
PR_DETECT_CMSER = 0x04, /**Character detect type£¬using mser */
};
static const char* kDefaultSvmPath = "resources/model/svm.xml";
static const char* kDefaultAnnPath = "resources/model/ann.xml";

@ -17,6 +17,7 @@
#include "easypr/core/character.hpp"
#include "easypr/util/util.h"
#include "easypr/core/plate.hpp"
#include "easypr/config.h"
namespace easypr {

@ -2,6 +2,7 @@
#define EASYPR_CORE_COREFUNC_H_
#include <opencv2/opencv.hpp>
#include "easypr/core/plate.hpp"
using namespace cv;
@ -10,19 +11,6 @@ Namespace where all the C++ EasyPR functionality resides
*/
namespace easypr {
enum Color { BLUE, YELLOW, WHITE, UNKNOWN };
enum LocateType { SOBEL, COLOR, CMSER, OTHER };
enum CharSearchDirection { LEFT, RIGHT };
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代表不匹配
@ -87,7 +75,7 @@ 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<Rect>& out_charRect, Color color, int index = 0, bool showDebug = false);
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& plateVec, Color color, int index = 0, bool showDebug = false);
/** @brief convert form mser point to image.

@ -10,8 +10,9 @@
#ifndef EASYPR_CORE_PLATE_H_
#define EASYPR_CORE_PLATE_H_
#include <opencv2/opencv.hpp>
#include "easypr/core/character.hpp"
#include "easypr/core/core_func.h"
#include "easypr/config.h"
using namespace cv;

@ -16,10 +16,14 @@
#include "easypr/core/plate.hpp"
#include "easypr/core/core_func.h"
#include "easypr/config.h"
/*! \namespace easypr
Namespace where all the C++ EasyPR functionality resides
*/
using namespace std;
namespace easypr {
class CPlateLocate {
@ -82,7 +86,7 @@ class CPlateLocate {
//! mser search
int mserSearch(const Mat& src, const Color r, Mat& out,
std::vector<RotatedRect>& outRects, int index = 0, bool showDebug = false);
vector<CPlate>& plateVec, int index = 0, bool showDebug = false);
//! 未使用函数与代码
//! 开始------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -6,7 +6,9 @@
</image>
<image>
<imageName>´¨A095Q5</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="444" y="222" width="107" height="30" rotation="2" locateType="2">À¶ÅÆ:Óå11A095</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨A105LR</imageName>
@ -14,7 +16,9 @@
</image>
<image>
<imageName>´¨A113YP</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="346" y="207" width="125" height="33" rotation="0" locateType="2">À¶ÅÆ:½òA113YF</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨A561WP</imageName>
@ -26,7 +30,9 @@
</image>
<image>
<imageName>´¨A762ZS</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="457" y="175" width="115" height="31" rotation="1" locateType="2">À¶ÅÆ:´¨A762ZS</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AE8H60</imageName>
@ -42,11 +48,15 @@
</image>
<image>
<imageName>´¨AKM065</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="450" y="191" width="112" height="33" rotation="0" locateType="2">À¶ÅÆ:Íî4AKM06</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AKQ291</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="417" y="152" width="89" height="27" rotation="-4" locateType="2">À¶ÅÆ:ÃÉ929111</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AM1186</imageName>
@ -66,11 +76,15 @@
</image>
<image>
<imageName>´¨AUU093</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="406" y="200" width="111" height="32" rotation="1" locateType="2">À¶ÅÆ:¹óAUU093</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AY116F</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="427" y="189" width="107" height="32" rotation="1" locateType="2">À¶ÅÆ:²Ø11AY11</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>´¨AZ408T</imageName>
@ -86,7 +100,9 @@
</image>
<image>
<imageName>»¦ALB022</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="392" y="390" width="115" height="31" rotation="-3" locateType="2">À¶ÅÆ:»¦ALB022</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>»¦B683J8</imageName>
@ -194,7 +210,9 @@
</image>
<image>
<imageName>Ô¥U00000</imageName>
<taggedRectangles/>
<taggedRectangles>
<taggedRectangle x="888" y="650" width="102" height="28" rotation="0" locateType="2">À¶ÅÆ:»¦1D0DCL</taggedRectangle>
</taggedRectangles>
</image>
<image>
<imageName>¸ÓK11978</imageName>

@ -1,4 +1,5 @@
#include "easypr/core/chars_segment.h"
#include "easypr/config.h"
using namespace std;

@ -5,6 +5,7 @@
#include "easypr/core/core_func.h"
#include "easypr/core/plate.hpp"
#include "easypr/core/chars_identify.h"
#include "easypr/config.h"
using namespace cv;
@ -1329,7 +1330,7 @@ bool judegMDOratio(const Mat& image, const Rect& rect, std::vector<Point>& conto
//! use verify size to first generate char candidates
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<Rect>& out_charRect, Color color, int img_index, bool showDebug) {
Mat mserCharMatch(const Mat &src, Mat &match, std::vector<CPlate>& out_plateVec, Color color, int img_index, bool showDebug) {
Mat image = src;
std::vector<std::vector<Point>> all_contours;
@ -1428,7 +1429,6 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<Rect>& out_charRect, C
Rect maxrect;
double ostu_level_sum = 0;
int leftx = image.cols;
Point leftPoint(leftx, 0);
int rightx = 0;
@ -1459,7 +1459,6 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<Rect>& out_charRect, C
}
}
double ostu_level_avg = ostu_level_sum / (double)charGroup.size();
std::cout << "ostu_level_avg:" << ostu_level_avg << std::endl;
float ratio_maxrect = (float)maxrect.width / (float)maxrect.height;
@ -1574,10 +1573,6 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<Rect>& out_charRect, C
mserCharacter.push_back(seed);
}
//cv::circle(result, leftPoint, 3, Scalar(0, 0, 255), 2);
//std::cout << "widthRatio:" << float(rightPoint.x - leftPoint.x) / (float)dist[0] << std::endl;
//cv::circle(result, Point(rightPoint.x - 4 * (float)dist[0], rightPoint.y), 3, Scalar(0, 0, 255), 2);
searchWeakSeed(searchCandidate, searchLeftWeakSeed, line, leftPoint, maxrect, plateResult, CharSearchDirection::LEFT);
std::cout << "searchLeftWeakSeed:" << searchLeftWeakSeed.size() << std::endl;
for (auto seed : searchLeftWeakSeed) {
@ -1618,7 +1613,7 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<Rect>& out_charRect, C
//plate.setOstuLevel(ostu_level);
Mat charInput = preprocessChar(binary_region, 20);
if (1) {
if (0) {
imshow("charInput", charInput);
waitKey(0);
destroyWindow("charInput");
@ -1653,13 +1648,15 @@ Mat mserCharMatch(const Mat &src, Mat &match, std::vector<Rect>& out_charRect, C
if (verifyRotatedPlateSizes(platePos)) {
rotatedRectangle(result, platePos, Scalar(0, 0, 255), 1);
plate.setPlatePos(platePos);
out_plateVec.push_back(plate);
}
//cv::rectangle(result, plateResult, Scalar(0, 0, 255), 1);
match(plateResult) = 255;
}
if (1) {
if (0) {
imshow("result", result);
waitKey(0);
destroyWindow("result");

@ -20,16 +20,11 @@ namespace easypr {
std::vector<CPlate> mser_Plates;
std::vector<CPlate> all_result_Plates;
//如果颜色查找找到n个以上包含n个的车牌就不再进行Sobel查找了。
if ( !type || type & PR_DETECT_SOBEL)
{
if ( !type || type & PR_DETECT_SOBEL) {
m_plateLocate->plateSobelLocate(src, sobel_Plates, index);
std::vector<CPlate>& sobel_result_Plates = sobel_Plates;
for (size_t i = 0; i < sobel_result_Plates.size(); i++)
{
for (size_t i = 0; i < sobel_result_Plates.size(); i++) {
CPlate plate = sobel_result_Plates[i];
plate.setPlateLocateType(SOBEL);
@ -37,14 +32,11 @@ namespace easypr {
}
}
if ( !type || type & PR_DETECT_COLOR)
{
if ( !type || type & PR_DETECT_COLOR) {
m_plateLocate->plateColorLocate(src, color_Plates, index);
std::vector<CPlate>& color_result_Plates = color_Plates;
for (size_t i = 0; i < color_result_Plates.size(); i++)
{
for (size_t i = 0; i < color_result_Plates.size(); i++) {
CPlate plate = color_result_Plates[i];
plate.setPlateLocateType(COLOR);
@ -52,14 +44,11 @@ namespace easypr {
}
}
if ( !type || type & PR_DETECT_CMSER)
{
if ( !type || type & PR_DETECT_CMSER) {
m_plateLocate->plateMserLocate(src, mser_Plates, index);
std::vector<CPlate>& mser_result_Plates = mser_Plates;
for (size_t i = 0; i < mser_result_Plates.size(); i++)
{
for (size_t i = 0; i < mser_result_Plates.size(); i++) {
CPlate plate = mser_result_Plates[i];
plate.setPlateLocateType(CMSER);
@ -70,31 +59,23 @@ namespace easypr {
// 使用非极大值抑制来判断车牌
PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec, m_maxPlates);
if (1)
{
if (0) {
Mat result = src.clone();
for (size_t i = 0; i < all_result_Plates.size(); i++)
{
CPlate plate = all_result_Plates[i];
for (size_t i = 0; i < all_result_Plates.size(); i++) {
CPlate plate = all_result_Plates.at(i);
Rect_<float> outputRect;
calcSafeRect(plate.getPlatePos(), src, outputRect);
cv::rectangle(result, outputRect, Scalar(0, 0, 255));
if (0)
{
cv::rectangle(result, outputRect, Scalar(0, 0, 255));
}
if (0)
{
if (0){
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plate_" << index << "_" << i << ".jpg";
imwrite(ss.str(), src(outputRect));
}
}
if (0)
{
if (0) {
imshow("result", result);
waitKey(0);
destroyWindow("result");

@ -14,7 +14,7 @@ namespace easypr {
PlateJudge::PlateJudge() {
svm_ = ml::SVM::load<ml::SVM>(kDefaultSvmPath);
extractFeature = getHistogramFeatures;
extractFeature = getLBPFeatures;
}
void PlateJudge::LoadModel(std::string path) {
@ -122,50 +122,74 @@ namespace easypr {
}
int result = plateSetScore(plate);
if (result == 0) {
plateVec.push_back(plate);
if (outputResult) {
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plate/has" << "/" << plate.getPlatePos().center << "_"
<< plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_"
<< plate.getPlateScore() << ".jpg";
imwrite(ss.str(), inMat);
}
}
else {
int w = inMat.cols;
int h = inMat.rows;
int w = inMat.cols;
int h = inMat.rows;
//ÔÙÈ¡Öм䲿·ÖÅжÏÒ»´Î
Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8));
Mat tmpDes = inMat.clone();
resize(tmpmat, tmpDes, Size(inMat.size()));
Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8));
Mat tmpDes = inMat.clone();
resize(tmpmat, tmpDes, Size(inMat.size()));
plate.setPlateMat(tmpDes);
plate.setPlateMat(tmpDes);
int resultCascade = plateSetScore(plate);
int resultCascade = plateSetScore(plate);
if (resultCascade == 0) {
plateVec.push_back(plate);
if (outputResult) {
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plate/has" << "/" << plate.getPlatePos().center << "_"
<< plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_"
<< plate.getPlateScore() << ".jpg";
imwrite(ss.str(), tmpDes);
}
}
else {
if (outputResult) {
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/plate/no" << "/" << plate.getPlatePos().center << "_"
<< plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_"
<< plate.getPlateScore() << ".jpg";
imwrite(ss.str(), tmpDes);
if (resultCascade == 0) {
if (0) {
imshow("inMat", inMat);
waitKey(0);
destroyWindow("inMat");
}
plateVec.push_back(plate);
}
}
}
//if (result == 0) {
// plateVec.push_back(plate);
// if (outputResult) {
// std::stringstream ss(std::stringstream::in | std::stringstream::out);
// ss << "resources/image/tmp/plate/has" << "/" << plate.getPlatePos().center << "_"
// << plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_"
// << plate.getPlateScore() << ".jpg";
// imwrite(ss.str(), inMat);
// }
//}
//else {
// int w = inMat.cols;
// int h = inMat.rows;
// //ÔÙÈ¡Öм䲿·ÖÅжÏÒ»´Î
// Mat tmpmat = inMat(Rect_<double>(w * 0.05, h * 0.1, w * 0.9, h * 0.8));
// Mat tmpDes = inMat.clone();
// resize(tmpmat, tmpDes, Size(inMat.size()));
// plate.setPlateMat(tmpDes);
// int resultCascade = plateSetScore(plate);
// if (resultCascade == 0) {
// plateVec.push_back(plate);
// if (outputResult) {
// std::stringstream ss(std::stringstream::in | std::stringstream::out);
// ss << "resources/image/tmp/plate/has" << "/" << plate.getPlatePos().center << "_"
// << plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_"
// << plate.getPlateScore() << ".jpg";
// imwrite(ss.str(), tmpDes);
// }
// }
// else {
// if (outputResult) {
// std::stringstream ss(std::stringstream::in | std::stringstream::out);
// ss << "resources/image/tmp/plate/no" << "/" << plate.getPlatePos().center << "_"
// << plate.getPlatePos().size << "_" << plate.getPlatePos().angle << "_"
// << plate.getPlateScore() << ".jpg";
// imwrite(ss.str(), tmpDes);
// }
// }
//}
}
std::vector<CPlate> reDupPlateVec;

File diff suppressed because it is too large Load Diff

@ -86,7 +86,7 @@ namespace easypr {
CPlateRecognize pr;
// 设置Debug模式
pr.setDebug(false);
pr.setDebug(true);
pr.setLifemode(true);
// 设置要处理的一张图片中最多有多少车牌

Loading…
Cancel
Save