* add test to general images and deskew to mser characters.

v1.6alpha
liuruoze 9 years ago
parent 586f9fdb69
commit dafe058d2e

@ -1887,3 +1887,33 @@ Recall:37.5998%, Precise:59.6161%, Fscore:46.115%.
Recall:18.4055%, Precise:57.8458%, Fscore:27.9255%.
0-error:22.2222%, 1-error:22.2222%, Chinese-precise:22.2222%
总时间:276秒, 平均执行时间:5.52秒
2016-06-27 11:43:54
总图片数:50, Plates count:44, 未识出图片:25, 定位率:43.1818%
Recall:38.8157%, Precise:68.3157%, Fscore:49.5041%.
0-error:31.5789%, 1-error:36.8421%, Chinese-precise:36.8421%
总时间:323秒, 平均执行时间:6.46秒
2016-06-27 11:51:11
总图片数:50, Plates count:44, 未识出图片:11, 定位率:75%
Recall:67.2173%, Precise:59.1512%, Fscore:62.9268%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:200秒, 平均执行时间:4秒
2016-06-27 12:26:45
总图片数:50, Plates count:44, 未识出图片:11, 定位率:75%
Recall:66.2867%, Precise:63.4047%, Fscore:64.8137%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:214秒, 平均执行时间:4.28秒
2016-06-27 12:41:27
总图片数:200, Plates count:238, 未识出图片:53, 定位率:77.7311%
Recall:68.9754%, Precise:76.1017%, Fscore:72.3635%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:841秒, 平均执行时间:4.205秒
2016-06-27 16:24:55
总图片数:50, Plates count:44, 未识出图片:11, 定位率:75%
Recall:66.2867%, Precise:63.4047%, Fscore:64.8137%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:262秒, 平均执行时间:5.24秒
2016-06-27 17:42:24
总图片数:50, Plates count:44, 未识出图片:11, 定位率:75%
Recall:66.2867%, Precise:63.4047%, Fscore:64.8137%.
0-error:0%, 1-error:0%, Chinese-precise:100%
总时间:260秒, 平均执行时间:5.2秒

@ -28,11 +28,11 @@ static const float kSvmPercentage = 0.7f;
static const int kCharacterInput = 120;
static const int kChineseInput = 440;
static const int kAnnInput = kChineseInput;
static const int kAnnInput = kCharacterInput;
static const int kCharacterSize = 10;
static const int kChineseSize = 20;
static const int kPredictSize = kChineseSize;
static const int kPredictSize = kCharacterSize;
static const int kNeurons = 40;

@ -61,7 +61,7 @@ Rect GetChineseRect(const Rect rectSpe);
bool verifyCharSizes(Rect r);
bool verifyPlateSize(Rect mr);
bool verifyRotatedPlateSizes(RotatedRect mr);
bool verifyRotatedPlateSizes(RotatedRect mr, bool showDebug = false);
void rotatedRectangle(InputOutputArray img, RotatedRect rect,

@ -23,7 +23,7 @@ class CPlateDetect {
@param index
*/
int plateDetect(Mat src, std::vector<CPlate> &resultVec, int type,
bool showDetectArea = true, int index = 0);
bool showDetectArea, int img_index = 0);
/** @brief Plate detect in an image.
@ -33,38 +33,32 @@ class CPlateDetect {
@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 plateDetect(Mat src, std::vector<CPlate> &resultVec, int img_index = 0);
//! 展示中间的结果
int showResult(const Mat &result);
int showResult(const Mat &result, int img_index = 0);
//! 装载SVM模型
void LoadSVM(std::string s);
//! 生活模式与工业模式切换
inline void setPDLifemode(bool param) { m_plateLocate->setLifemode(param); }
//! 是否开启调试模式
inline void setPDDebug(bool param) { m_plateLocate->setDebug(param); }
inline void setPDDebug(bool param) {
m_plateLocate->setDebug(param);
setDetectShow(param);
}
//! 获取调试模式状态
inline bool getPDDebug() { return m_plateLocate->getDebug(); }
inline void setDetectType(int param) { m_type = param; }
//! 设置与读取变量
inline void setGaussianBlurSize(int param) {
m_plateLocate->setGaussianBlurSize(param);
}
@ -115,6 +109,9 @@ class CPlateDetect {
inline int getMaxPlates() const { return m_maxPlates; }
inline void setDetectShow(bool param) { m_showDetect = param; }
inline bool getDetectShow() const { return m_showDetect; }
private:
//! 设置一幅图中最多有多少车牌
@ -129,6 +126,9 @@ class CPlateDetect {
static std::string m_pathSvm;
// show the detect result image
bool m_showDetect;
};
}

@ -25,7 +25,7 @@ namespace easypr {
CPlateRecognize();
//! 车牌检测与字符识别
int plateRecognize(Mat src, std::vector<CPlate> &licenseVec, int index = 0);
int plateRecognize(Mat src, std::vector<CPlate> &licenseVec, int img_index = 0);
int plateRecognize(Mat src, std::vector<std::string> &licenseVec);
int plateRecognizeAsText(Mat src, std::vector<CPlate> &licenseVec);
@ -34,13 +34,17 @@ namespace easypr {
//! 生活模式与工业模式切换
inline void setLifemode(bool param) { CPlateDetect::setPDLifemode(param); }
inline void setDetectType(int param) { CPlateDetect::setDetectType(param); }
//! 是否开启调试模式
inline void setDebug(bool param) { CPlateDetect::setPDDebug(param); }
inline void setResultShow(bool param) { m_showResult = param; }
inline bool getResultShow() const { return m_showResult; }
inline void setDetectShow(bool param) { CPlateDetect::setDetectShow(param); }
inline void setDebug(bool param) { setResultShow(param); }
inline void setDetectType(int param) { CPlateDetect::setDetectType(param); }
private:
// show the detect and recognition result image
bool m_showResult;
};
} /* \namespace easypr */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 56 KiB

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

File diff suppressed because it is too large Load Diff

@ -8,12 +8,14 @@ namespace easypr {
m_maxPlates = 3;
m_type = 0;
m_showDetect = false;
}
CPlateDetect::~CPlateDetect() { SAFE_RELEASE(m_plateLocate); }
int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec, int type,
bool showDetectArea, int index) {
bool showDetectArea, int img_index) {
std::vector<CPlate> color_Plates;
std::vector<CPlate> sobel_Plates;
@ -21,7 +23,7 @@ namespace easypr {
std::vector<CPlate> all_result_Plates;
if ( !type || type & PR_DETECT_SOBEL) {
m_plateLocate->plateSobelLocate(src, sobel_Plates, index);
m_plateLocate->plateSobelLocate(src, sobel_Plates, img_index);
std::vector<CPlate>& sobel_result_Plates = sobel_Plates;
for (size_t i = 0; i < sobel_result_Plates.size(); i++) {
@ -33,7 +35,7 @@ namespace easypr {
}
if ( !type || type & PR_DETECT_COLOR) {
m_plateLocate->plateColorLocate(src, color_Plates, index);
m_plateLocate->plateColorLocate(src, color_Plates, img_index);
std::vector<CPlate>& color_result_Plates = color_Plates;
for (size_t i = 0; i < color_result_Plates.size(); i++) {
@ -45,7 +47,7 @@ namespace easypr {
}
if ( !type || type & PR_DETECT_CMSER) {
m_plateLocate->plateMserLocate(src, mser_Plates, index);
m_plateLocate->plateMserLocate(src, mser_Plates, img_index);
std::vector<CPlate>& mser_result_Plates = mser_Plates;
for (size_t i = 0; i < mser_result_Plates.size(); i++) {
@ -59,7 +61,44 @@ namespace easypr {
// 使用非极大值抑制来判断车牌
PlateJudge::instance()->plateJudgeUsingNMS(all_result_Plates, resultVec, m_maxPlates);
if (0) {
if (showDetectArea || getDetectShow()) {
int index = 0;
Mat result;
src.copyTo(result);
for (size_t j = 0; j < resultVec.size(); j++) {
CPlate item = resultVec[j];
Mat plate = item.getPlateMat();
int height = 36;
int width = 136;
if (height * index + height < result.rows) {
Mat imageRoi = result(Rect(0, 0 + height * index, width, height));
addWeighted(imageRoi, 0, plate, 1, 0, imageRoi);
}
index++;
RotatedRect minRect = item.getPlatePos();
Point2f rect_points[4];
minRect.points(rect_points);
Scalar lineColor = Scalar(255, 255, 255);
if (item.getPlateLocateType() == SOBEL) lineColor = Scalar(255, 0, 0);
if (item.getPlateLocateType() == COLOR) lineColor = Scalar(0, 255, 0);
if (item.getPlateLocateType() == CMSER) lineColor = Scalar(0, 0, 255);
for (int j = 0; j < 4; j++)
line(result, rect_points[j], rect_points[(j + 1) % 4], lineColor, 2, 8);
}
//ÏÔʾ¶¨Î»¿òµÄͼƬ
showResult(result, img_index);
}
/*if (0) {
Mat result = src.clone();
for (size_t i = 0; i < all_result_Plates.size(); i++) {
CPlate plate = all_result_Plates.at(i);
@ -80,18 +119,17 @@ namespace easypr {
waitKey(0);
destroyWindow("result");
}
}
}*/
return 0;
}
int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec,
bool showDetectArea, int index) {
int result = plateDetect(src, resultVec, m_type, showDetectArea, index);
int CPlateDetect::plateDetect(Mat src, std::vector<CPlate> &resultVec, int img_index) {
int result = plateDetect(src, resultVec, m_type, false, img_index);
return result;
}
int CPlateDetect::showResult(const Mat &result) {
int CPlateDetect::showResult(const Mat &result, int img_index) {
namedWindow("EasyPR", CV_WINDOW_AUTOSIZE);
const int RESULTWIDTH = 640; // 640 930
@ -141,10 +179,17 @@ namespace easypr {
result_resize.cols, result_resize.rows));
addWeighted(imageRoi, 0, result_resize, 1, 0, imageRoi);
imshow("EasyPR", img_window);
waitKey();
if (1) {
imshow("EasyPR", img_window);
waitKey(1000);
destroyWindow("EasyPR");
}
destroyWindow("EasyPR");
if (1) {
std::stringstream ss(std::stringstream::in | std::stringstream::out);
ss << "resources/image/tmp/Result/plate_" << img_index << ".jpg";
imwrite(ss.str(), img_window);
}
return 0;
}

@ -79,13 +79,100 @@ bool CPlateLocate::verifySizes(RotatedRect mr) {
return true;
}
// !基于HSV空间的颜色搜索方法
//! mser search method
int CPlateLocate::mserSearch(const Mat &src, const Color color, Mat &out,
vector<CPlate>& plateVec, int index, bool showDebug) {
vector<CPlate>& out_plateVec, int img_index, bool showDebug) {
Mat match_grey;
vector<CPlate> plateVec;
//mserMatch(src, match_grey, r, plateRects, charRects);
mserCharMatch(src, match_grey, plateVec, color, index, showDebug);
mserCharMatch(src, match_grey, plateVec, color, img_index, showDebug);
//calculet avg dist
/*float sumdist = 0, avgdist = 0;
for (auto plate : plateVec) {
Vec2i disV = plate.getPlateDistVec();
sumdist += (float)disV[0];
}
avgdist = sumdist / (float)plateVec.size();
const int mser_morph_width = (int)avgdist;
const int mser_morph_height = int(avgdist / 5);
Mat src_threshold;
threshold(match_grey, src_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
Mat element = getStructuringElement(MORPH_RECT, Size(mser_morph_width, mser_morph_height));
morphologyEx(src_threshold, src_threshold, MORPH_CLOSE, element);*/
Mat src_threshold = match_grey.clone();
vector<RotatedRect> mergeRects;
vector<vector<Point>> contours;
findContours(src_threshold,
contours, // a vector of contours
CV_RETR_EXTERNAL,
CV_CHAIN_APPROX_NONE); // all pixels of each contours
vector<vector<Point>>::iterator itc = contours.begin();
while (itc != contours.end()) {
RotatedRect mr = minAreaRect(Mat(*itc));
// 需要进行大小尺寸判断
if (!verifyRotatedPlateSizes(mr))
itc = contours.erase(itc);
else {
++itc;
//contourRects.push_back(mr);
float width = mr.size.width;
float height = mr.size.height;
RotatedRect candRect(mr.center,
Size2f(float(width * 1.15), float(height * 1.25)), mr.angle);
//mergeRects.push_back(candRect);
}
}
for (auto plate : plateVec) {
RotatedRect rrect = plate.getPlatePos();
Rect_<float> rectSrc;
calcSafeRect(rrect, src, rectSrc);
double maxr = 0;
RotatedRect similyRect;
for (auto mergeRect : mergeRects) {
Rect_<float> rectComp;
calcSafeRect(mergeRect, src, rectComp);
Rect rectInter = rectSrc & rectComp;
Rect rectUnion = rectSrc | rectComp;
double r = double(rectInter.area()) / double(rectUnion.area());
if (r > maxr){
maxr = r;
similyRect = mergeRect;
}
}
if (maxr > 0.5){
plate.setPlatePos(similyRect);
}
}
for (auto plate : plateVec){
RotatedRect rrect = plate.getPlatePos();
rotatedRectangle(match_grey, rrect, Scalar(255));
}
if (0) {
imshow("match", match_grey);
waitKey(0);
destroyWindow("match");
}
out_plateVec = plateVec;
out = match_grey;
return 0;
}
@ -724,12 +811,11 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
plate_mat.create(HEIGHT, WIDTH, TYPE);
// haitungaga添加删除非区域这个函数影响了25%的完整定位率
DeleteNotArea(deskew_mat);
// DeleteNotArea(deskew_mat);
// 这里对deskew_mat进行了一个筛选
// 使用了经验数值2.3和6
if (deskew_mat.cols * 1.0 / deskew_mat.rows > 2.3 &&
deskew_mat.cols * 1.0 / deskew_mat.rows < 6) {
@ -744,9 +830,10 @@ int CPlateLocate::deskew(const Mat &src, const Mat &src_b,
plate.setPlatePos(roi_rect);
plate.setPlateMat(plate_mat);
if (0) {
if (1) {
imshow("plate_mat", plate_mat);
waitKey(0);
destroyWindow("plate_mat");
}
outPlates.push_back(plate);
@ -970,7 +1057,7 @@ int CPlateLocate::plateColorLocate(Mat src, vector<CPlate> &candPlates,
//! MSER plate locate
int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int index) {
int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int img_index) {
std::vector<Mat> channelImages;
std::vector<Color> flags;
@ -993,17 +1080,26 @@ int CPlateLocate::plateMserLocate(Mat src, vector<CPlate> &candPlates, int index
int scale_size = 1024;
double scale_ratio = 1;
vector<RotatedRect> rects_mser;
vector<CPlate> plates;
Mat src_b;
for (size_t i = 0; i < channelImages.size(); ++i) {
Mat channelImage = channelImages[i];
vector<RotatedRect> rects_mser;
vector<CPlate> plates;
Mat src_b;
Mat channelImage = channelImages.at(i);
Color color = flags.at(i);
Mat image = scaleImage(channelImage, Size(scale_size, scale_size), scale_ratio);
//vector<RotatedRect> rects;
mserSearch(image, flags[i], src_b, plates, index);
// vector<RotatedRect> rects;
mserSearch(image, color, src_b, plates, img_index);
// deskew for rotation and slope image
/*for (auto plate : plates) {
RotatedRect rrect = plate.getPlatePos();
rects_mser.push_back(rrect);
}
deskew(image, src_b, rects_mser, candPlates);*/
// no deskew
for (size_t j = 0; j < plates.size(); ++j) {
CPlate plate = plates.at(j);
RotatedRect rrect = plate.getPlatePos();

@ -4,10 +4,11 @@
namespace easypr {
CPlateRecognize::CPlateRecognize() { }
CPlateRecognize::CPlateRecognize() {
m_showResult = false;
}
void groups_draw(Mat &src, std::vector<Rect> &groups)
{
void groups_draw(Mat &src, std::vector<Rect> &groups) {
for (int i = (int)groups.size() - 1; i >= 0; i--)
{
if (src.type() == CV_8UC3)
@ -296,7 +297,7 @@ int CPlateRecognize::plateRecognizeAsText(Mat src, std::vector<CPlate> &licenseV
// !车牌识别模块
int CPlateRecognize::plateRecognize(Mat src, std::vector<CPlate> &licenseVec, int index) {
int CPlateRecognize::plateRecognize(Mat src, std::vector<CPlate> &licenseVec, int img_index) {
// 车牌集合
std::vector<CPlate> plateVec;
@ -311,7 +312,7 @@ int CPlateRecognize::plateRecognize(Mat src, std::vector<CPlate> &licenseVec, in
// 进行深度定位使用颜色信息与二次Sobel
int resultPD = plateDetect(src, plateVec, false, index);
int resultPD = plateDetect(src, plateVec, img_index);
if (resultPD == 0) {
size_t num = plateVec.size();
@ -340,7 +341,7 @@ int CPlateRecognize::plateRecognize(Mat src, std::vector<CPlate> &licenseVec, in
//如果是Debug模式则还需要将定位的图片显示在原图左上角
if (getPDDebug()) {
if (getResultShow()) {
Mat result;
src.copyTo(result);
@ -363,22 +364,16 @@ int CPlateRecognize::plateRecognize(Mat src, std::vector<CPlate> &licenseVec, in
Scalar lineColor = Scalar(255, 255, 255);
if (item.getPlateLocateType() == SOBEL) lineColor = Scalar(255, 0, 0);
if (item.getPlateLocateType() == COLOR) lineColor = Scalar(0, 255, 0);
if (item.getPlateLocateType() == CMSER) lineColor = Scalar(0, 0, 255);
for (int j = 0; j < 4; j++)
line(result, rect_points[j], rect_points[(j + 1) % 4], lineColor, 2,
8);
line(result, rect_points[j], rect_points[(j + 1) % 4], lineColor, 2, 8);
}
//显示定位框的图片
showResult(result);
}
}
return resultPD;
}
@ -422,7 +417,7 @@ int CPlateRecognize::plateRecognize(Mat src,
//如果是Debug模式则还需要将定位的图片显示在原图左上角
if (getPDDebug()) {
if (getResultShow()) {
Mat result;
src.copyTo(result);

@ -1,237 +0,0 @@
#include "easypr/core/chars_identify.h"
#include "easypr/core/character.hpp"
#include "easypr/config.h"
#include "easypr/core/core_func.h"
namespace easypr {
CharsIdentify* CharsIdentify::instance_ = nullptr;
CharsIdentify* CharsIdentify::instance() {
if (!instance_) {
instance_ = new CharsIdentify;
}
return instance_;
}
CharsIdentify::CharsIdentify() {
ann_ = ml::ANN_MLP::load<ml::ANN_MLP>(kDefaultAnnPath);
kv_ = std::shared_ptr<Kv>(new Kv);
kv_->load("etc/province_mapping");
}
void CharsIdentify::LoadModel(std::string path) {
ann_->clear();
ann_->ml::ANN_MLP::load<ml::ANN_MLP>(path);
}
void CharsIdentify::classify(cv::Mat featureRows, std::vector<int>& out_maxIndexs,
std::vector<float>& out_maxVals, std::vector<bool> isChineseVec){
int rowNum = featureRows.rows;
cv::Mat output(rowNum, kCharsTotalNumber, CV_32FC1);
ann_->predict(featureRows, output);
for (int output_index = 0; output_index < rowNum; output_index++) {
int result = -1;
float maxVal = -2.f;
bool isChinses = isChineseVec[output_index];
if (!isChinses) {
result = 0;
for (int j = 0; j < kCharactersNumber; j++) {
float val = output.at<float>(j);
// std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
}
else {
result = kCharactersNumber;
for (int j = kCharactersNumber; j < kCharsTotalNumber; j++) {
float val = output.at<float>(j);
//std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
}
out_maxIndexs[output_index] = result;
out_maxVals[output_index] = maxVal;
}
}
void CharsIdentify::classify(std::vector<CCharacter>& charVec){
size_t charVec_size = charVec.size();
Mat featureRows;
for (size_t index = 0; index < charVec_size; index++) {
Mat charInput = charVec[index].getCharacterMat();
Mat feature = charFeatures(charInput, kPredictSize);
featureRows.push_back(feature);
}
int rowNum = featureRows.rows;
cv::Mat output(rowNum, kCharsTotalNumber, CV_32FC1);
ann_->predict(featureRows, output);
for (int output_index = 0; output_index < rowNum; output_index++) {
CCharacter& character = charVec[output_index];
int result = -1;
float maxVal = -2.f;
string label = "";
bool isChinses = character.getIsChinese();
if (!isChinses) {
result = 0;
for (int j = 0; j < kCharactersNumber; j++) {
float val = output.at<float>(j);
// std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
}
else {
result = kCharactersNumber;
for (int j = kCharactersNumber; j < kCharsTotalNumber; j++) {
float val = output.at<float>(j);
//std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
}
character.setCharacterScore(maxVal);
character.setCharacterStr(result);
}
}
int CharsIdentify::classify(cv::Mat f, float& maxVal, bool isChinses){
int result = -1;
cv::Mat output(1, kCharsTotalNumber, CV_32FC1);
ann_->predict(f, output);
maxVal = -2.f;
if (!isChinses) {
result = 0;
for (int j = 0; j < kCharactersNumber; j++) {
float val = output.at<float>(j);
// std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
}
else {
result = kCharactersNumber;
for (int j = kCharactersNumber; j < kCharsTotalNumber; j++) {
float val = output.at<float>(j);
//std::cout << "j:" << j << "val:" << val << std::endl;
if (val > maxVal) {
maxVal = val;
result = j;
}
}
}
//std::cout << "maxVal:" << maxVal << std::endl;
return result;
}
bool CharsIdentify::isCharacter(cv::Mat input, std::string& label, float& maxVal, bool isChinese) {
cv::Mat feature = charFeatures(input, kPredictSize);
auto index = static_cast<int>(classify(feature, maxVal, isChinese));
if (isChinese)
std::cout << "maxVal:" << maxVal << std::endl;
if (maxVal >= 0.9) {
if (index < kCharactersNumber) {
label = std::make_pair(kChars[index], kChars[index]).second;
}
else {
const char* key = kChars[index];
std::string s = key;
std::string province = kv_->get(s);
label = std::make_pair(s, province).second;
}
return true;
}
else
return false;
}
/*bool CharsIdentify::charsJudge(std::vector<CCharacter>& charVec) {
cv::Mat feature = charFeatures(input, kPredictSize);
auto index = static_cast<int>(classify(feature, maxVal, isChinese));
if (isChinese)
std::cout << "maxVal:" << maxVal << std::endl;
if (maxVal >= 0.9) {
if (index < kCharactersNumber) {
label = std::make_pair(kChars[index], kChars[index]).second;
}
else {
const char* key = kChars[index];
std::string s = key;
std::string province = kv_->get(s);
label = std::make_pair(s, province).second;
}
return true;
}
else
return false;
}*/
std::pair<std::string, std::string> CharsIdentify::identify(cv::Mat input, bool isChinese) {
cv::Mat feature = charFeatures(input, kPredictSize);
float maxVal = -2;
auto index = static_cast<int>(classify(feature, maxVal, isChinese));
if (index < kCharactersNumber) {
return std::make_pair(kChars[index], kChars[index]);
}
else {
const char* key = kChars[index];
std::string s = key;
std::string province = kv_->get(s);
return std::make_pair(s, province);
}
}
int CharsIdentify::identify(std::vector<cv::Mat> inputs, std::vector<std::pair<std::string, std::string>>& outputs,
std::vector<bool> isChineseVec) {
Mat featureRows;
size_t input_size = inputs.size();
for (size_t i = 0; i < input_size; i++) {
Mat input = inputs[i];
cv::Mat feature = charFeatures(input, kPredictSize);
featureRows.push_back(feature);
}
std::vector<int> maxIndexs;
std::vector<float> maxVals;
classify(featureRows, maxIndexs, maxVals, isChineseVec);
for (size_t row_index = 0; row_index < input_size; row_index++) {
int index = maxIndexs[row_index];
if (index < kCharactersNumber) {
outputs[row_index] = std::make_pair(kChars[index], kChars[index]);
}
else {
const char* key = kChars[index];
std::string s = key;
std::string province = kv_->get(s);
outputs[row_index] = std::make_pair(s, province);
}
}
return 0;
}
}

@ -86,18 +86,18 @@ namespace easypr {
CPlateRecognize pr;
// 设置Debug模式
pr.setDebug(true);
pr.setResultShow(true);
pr.setLifemode(true);
// 设置要处理的一张图片中最多有多少车牌
pr.setMaxPlates(4);
//pr.setDetectType(PR_DETECT_COLOR | PR_DETECT_SOBEL);
pr.setDetectType(PR_DETECT_CMSER);
//CPlateDetect pd;
//pd.setDetectType(PR_DETECT_CMSER);
//pd.setPDDebug(false);
//pd.setPDLifemode(true);
CPlateDetect pd;
pd.setDetectType(PR_DETECT_CMSER);
//pd.setPDDebug(true);
pd.setDetectShow(true);
pd.setPDLifemode(true);
int size = files.size();
@ -172,9 +172,9 @@ namespace easypr {
XMLNode rectangleNodes = xNode.addChild("taggedRectangles");
vector<CPlate> plateVec;
int result = pr.plateRecognize(src, plateVec, i);
//int result = pr.plateRecognize(src, plateVec, i);
//pd.plateDetect(src, plateVec);
int result = pd.plateDetect(src, plateVec, i);
// get the ground truth and compare it with the detect list;
map<string, vector<CPlate>>::iterator it;

Loading…
Cancel
Save