diff --git a/accuracy.txt b/accuracy.txt index e4358fb..cb63832 100644 --- a/accuracy.txt +++ b/accuracy.txt @@ -1185,3 +1185,67 @@ 总图片数:204张, 未识出图片:6张, 定位率:97.0588% 平均字符差距:0.520202个, 完全匹配数:145张, 完全匹配率:73.2323% 总时间:176秒, 平均执行时间:0.862745秒 +2015-07-31 17:53:07 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.520202个, 完全匹配数:145张, 完全匹配率:73.2323% +总时间:182秒, 平均执行时间:0.892157秒 +2015-07-31 18:02:12 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.520202个, 完全匹配数:145张, 完全匹配率:73.2323% +总时间:183秒, 平均执行时间:0.897059秒 +2015-07-31 18:06:37 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.520202个, 完全匹配数:145张, 完全匹配率:73.2323% +总时间:182秒, 平均执行时间:0.892157秒 +2015-07-31 18:11:16 +总图片数:1张, 未识出图片:0张, 定位率:100% +平均字符差距:0个, 完全匹配数:1张, 完全匹配率:100% +总时间:1秒, 平均执行时间:1秒 +2015-07-31 18:11:31 +总图片数:1张, 未识出图片:0张, 定位率:100% +平均字符差距:0个, 完全匹配数:1张, 完全匹配率:100% +总时间:0秒, 平均执行时间:0秒 +2015-07-31 18:18:20 +总图片数:1张, 未识出图片:0张, 定位率:100% +平均字符差距:0个, 完全匹配数:1张, 完全匹配率:100% +总时间:0秒, 平均执行时间:0秒 +2015-07-31 18:21:34 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.510101个, 完全匹配数:147张, 完全匹配率:74.2424% +总时间:182秒, 平均执行时间:0.892157秒 +2015-07-31 18:32:25 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:1.05556个, 完全匹配数:108张, 完全匹配率:54.5455% +总时间:214秒, 平均执行时间:1.04902秒 +2015-07-31 18:36:36 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.510101个, 完全匹配数:147张, 完全匹配率:74.2424% +总时间:183秒, 平均执行时间:0.897059秒 +2015-07-31 18:41:32 +总图片数:1张, 未识出图片:0张, 定位率:100% +平均字符差距:0个, 完全匹配数:1张, 完全匹配率:100% +总时间:0秒, 平均执行时间:0秒 +2015-07-31 18:44:39 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.959596个, 完全匹配数:115张, 完全匹配率:58.0808% +总时间:184秒, 平均执行时间:0.901961秒 +2015-07-31 18:50:08 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.914141个, 完全匹配数:115张, 完全匹配率:58.0808% +总时间:185秒, 平均执行时间:0.906863秒 +2015-07-31 18:53:53 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.520202个, 完全匹配数:145张, 完全匹配率:73.2323% +总时间:186秒, 平均执行时间:0.911765秒 +2015-07-31 19:01:29 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:1.01515个, 完全匹配数:111张, 完全匹配率:56.0606% +总时间:187秒, 平均执行时间:0.916667秒 +2015-07-31 19:09:06 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.535354个, 完全匹配数:146张, 完全匹配率:73.7374% +总时间:202秒, 平均执行时间:0.990196秒 +2015-07-31 19:13:50 +总图片数:204张, 未识出图片:6张, 定位率:97.0588% +平均字符差距:0.520202个, 完全匹配数:145张, 完全匹配率:73.2323% +总时间:215秒, 平均执行时间:1.05392秒 diff --git a/include/easypr/chars_recognise.h b/include/easypr/chars_recognise.h index 1769008..2ac6aad 100644 --- a/include/easypr/chars_recognise.h +++ b/include/easypr/chars_recognise.h @@ -27,7 +27,7 @@ class CCharsRecognise { ~CCharsRecognise(); //! 字符分割与识别 - int charsRecognise(Mat, String&); + int charsRecognise(Mat, String&, int index = 0); string charsRecognise(Mat plate); diff --git a/include/easypr/chars_segment.h b/include/easypr/chars_segment.h index f4b51c9..cfcd9f0 100644 --- a/include/easypr/chars_segment.h +++ b/include/easypr/chars_segment.h @@ -24,7 +24,7 @@ class CCharsSegment { CCharsSegment(); //! 字符分割 - int charsSegment(Mat, vector&); + int charsSegment(Mat, vector&, int index = 0); //! 字符尺寸验证 bool verifyCharSizes(Mat r); diff --git a/include/easypr/plate_recognize.h b/include/easypr/plate_recognize.h index 84978cb..5ffc20d 100644 --- a/include/easypr/plate_recognize.h +++ b/include/easypr/plate_recognize.h @@ -25,7 +25,7 @@ class CPlateRecognize : public CPlateDetect, public CCharsRecognise { CPlateRecognize(); //! 车牌检测与字符识别 - int plateRecognize(cv::Mat src, std::vector& licenseVec); + int plateRecognize(cv::Mat src, std::vector& licenseVec, int index = 0); //! 生活模式与工业模式切换 inline void setLifemode(bool param) { CPlateDetect::setPDLifemode(param); } diff --git a/src/core/chars_recognise.cpp b/src/core/chars_recognise.cpp index a327778..e9f349c 100644 --- a/src/core/chars_recognise.cpp +++ b/src/core/chars_recognise.cpp @@ -23,13 +23,14 @@ void CCharsRecognise::LoadANN(string s) { string CCharsRecognise::charsRecognise(Mat plate) { return m_charsIdentify->charsIdentify(plate); } -int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense) { + +int CCharsRecognise::charsRecognise(Mat plate, string& plateLicense, int index) { //车牌字符方块集合 vector matVec; string plateIdentify = ""; - int result = m_charsSegment->charsSegment(plate, matVec); + int result = m_charsSegment->charsSegment(plate, matVec, index); if (result == 0) { int num = matVec.size(); for (int j = 0; j < num; j++) { diff --git a/src/core/chars_segment.cpp b/src/core/chars_segment.cpp index 8267f85..3b79c6a 100644 --- a/src/core/chars_segment.cpp +++ b/src/core/chars_segment.cpp @@ -73,7 +73,7 @@ Mat CCharsSegment::preprocessChar(Mat in) { //! 字符分割与排序 -int CCharsSegment::charsSegment(Mat input, vector& resultVec) { +int CCharsSegment::charsSegment(Mat input, vector& resultVec, int index) { if (!input.data) return 0x01; @@ -135,7 +135,7 @@ int CCharsSegment::charsSegment(Mat input, vector& resultVec) { if (m_debug) { stringstream ss(stringstream::in | stringstream::out); - ss << "resources/image/tmp/debug_char_threshold" << ".jpg"; + ss << "resources/image/tmp/debug_char_threshold_" << index << ".jpg"; utils::imwrite(ss.str(), img_threshold); } @@ -147,7 +147,7 @@ int CCharsSegment::charsSegment(Mat input, vector& resultVec) { if (m_debug) { stringstream ss(stringstream::in | stringstream::out); - ss << "resources/image/tmp/debug_char_clearLiuDing" << ".jpg"; + ss << "resources/image/tmp/debug_char_clearLiuDing_" << index << ".jpg"; utils::imwrite(ss.str(), img_threshold); } @@ -184,22 +184,22 @@ int CCharsSegment::charsSegment(Mat input, vector& resultVec) { size_t specIndex = 0; - //获得特殊字符对应的Rectt,如苏A的"A" + // 获得特殊字符对应的Rectt,如苏A的"A" specIndex = GetSpecificRect(sortedRect); if (m_debug) { if (specIndex < sortedRect.size()) { Mat specMat(img_threshold, sortedRect[specIndex]); stringstream ss(stringstream::in | stringstream::out); - ss << "resources/image/tmp/debug_specMat" + ss << "resources/image/tmp/debug_specMat_" << index << ".jpg"; utils::imwrite(ss.str(), specMat); } } - //根据特定Rect向左反推出中文字符 - //这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect,因此仅能 - //退过特定算法来指定 + // 根据特定Rect向左反推出中文字符 + // 这样做的主要原因是根据findContours方法很难捕捉到中文字符的准确Rect,因此仅能 + // 退过特定算法来指定 Rect chineseRect; if (specIndex < sortedRect.size()) chineseRect = GetChineseRect(sortedRect[specIndex]); @@ -209,7 +209,7 @@ int CCharsSegment::charsSegment(Mat input, vector& resultVec) { if (m_debug) { Mat chineseMat(img_threshold, chineseRect); stringstream ss(stringstream::in | stringstream::out); - ss << "resources/image/tmp/debug_chineseMat" + ss << "resources/image/tmp/debug_chineseMat_" << index << ".jpg"; utils::imwrite(ss.str(), chineseMat); } @@ -223,17 +223,49 @@ int CCharsSegment::charsSegment(Mat input, vector& resultVec) { if (newSortedRect.size() == 0) return 0x05; + // 开始截取每个字符 for (size_t i = 0; i < newSortedRect.size(); i++) { Rect mr = newSortedRect[i]; + Mat auxRoi(img_threshold, mr); + // 使用灰度图来截取图块,然后依次对每个图块进行大津阈值来二值化 + //Mat auxRoi(input_grey, mr); + //Mat newRoi; + + //if (BLUE == plateType) { + + // /* img_threshold = auxRoi.clone(); + // int w = input_grey.cols; + // int h = input_grey.rows; + // Mat tmp = input_grey(Rect_(w * 0.1, h * 0.1, w * 0.8, h * 0.8)); + // int threadHoldV = ThresholdOtsu(tmp);*/ + + // threshold(auxRoi, newRoi, 5, 255, CV_THRESH_BINARY + CV_THRESH_OTSU); + //} + //else if (YELLOW == plateType) { + // threshold(auxRoi, newRoi, 5, 255, CV_THRESH_BINARY_INV + CV_THRESH_OTSU); + + //} + //else if (WHITE == plateType) { + // threshold(auxRoi, newRoi, 5, 255, CV_THRESH_OTSU + CV_THRESH_BINARY_INV); + //} + //else { + // threshold(auxRoi, newRoi, 5, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); + //} + + // 归一化大小 auxRoi = preprocessChar(auxRoi); - if (m_debug) { + + // 假设我们要重新训练ANN模型,在这里需要把训练样板输出 + if (i == 0) { stringstream ss(stringstream::in | stringstream::out); - ss << "resources/image/tmp/debug_char_auxRoi_" << (i) + ss << "resources/image/tmp/debug_char_auxRoi_" << index << "_" << (i) << ".jpg"; utils::imwrite(ss.str(), auxRoi); } + + // 每个字符图块输入到下面的步骤进行处理 resultVec.push_back(auxRoi); } diff --git a/src/core/plate_recognize.cpp b/src/core/plate_recognize.cpp index 9980f01..23b746b 100644 --- a/src/core/plate_recognize.cpp +++ b/src/core/plate_recognize.cpp @@ -12,16 +12,16 @@ CPlateRecognize::CPlateRecognize() { } // !车牌识别模块 -int CPlateRecognize::plateRecognize(Mat src, std::vector &licenseVec) { +int CPlateRecognize::plateRecognize(Mat src, std::vector &licenseVec, int index) { // 车牌方块集合 vector plateVec; // 进行深度定位,使用颜色信息与二次Sobel - int resultPD = plateDetect(src, plateVec, getPDDebug(), 0); + int resultPD = plateDetect(src, plateVec, getPDDebug(), index); if (resultPD == 0) { int num = plateVec.size(); - int index = 0; + int i = 0; //依次识别每个车牌内的符号 for (int j = 0; j < num; j++) { @@ -33,7 +33,7 @@ int CPlateRecognize::plateRecognize(Mat src, std::vector &licenseVec) { //获取车牌号 string plateIdentify = ""; - int resultCR = charsRecognise(plate, plateIdentify); + int resultCR = charsRecognise(plate, plateIdentify, index); if (resultCR == 0) { string license = plateType + ":" + plateIdentify; licenseVec.push_back(license); @@ -52,11 +52,11 @@ int CPlateRecognize::plateRecognize(Mat src, std::vector &licenseVec) { int height = 36; int width = 136; - if (height * index + height < result.rows) { - Mat imageRoi = result(Rect(0, 0 + height * index, width, height)); + if (height * i + height < result.rows) { + Mat imageRoi = result(Rect(0, 0 + height * i, width, height)); addWeighted(imageRoi, 0, plate, 1, 0, imageRoi); } - index++; + i++; RotatedRect minRect = item.getPlatePos(); Point2f rect_points[4]; diff --git a/src/train/ann_train.cpp b/src/train/ann_train.cpp index 75cc0b7..39a81ab 100644 --- a/src/train/ann_train.cpp +++ b/src/train/ann_train.cpp @@ -208,6 +208,7 @@ void saveModel(int _predictsize, int _neurons) { cout << "End the saveModelChar" << endl; string model_name = "resources/train/ann.xml"; + // if(1) //{ // stringstream ss(stringstream::in | stringstream::out); diff --git a/test/accuracy.hpp b/test/accuracy.hpp index cc47ec1..775ff4a 100644 --- a/test/accuracy.hpp +++ b/test/accuracy.hpp @@ -72,7 +72,7 @@ int accuracyTest(const char* test_path) { cout << "原牌:" << plateLicense << endl; vector plateVec; - int result = pr.plateRecognize(src, plateVec); + int result = pr.plateRecognize(src, plateVec, i); if (result == 0) { int num = plateVec.size(); diff --git a/test/main.cpp b/test/main.cpp index 940c6b4..20347de 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -5,6 +5,9 @@ #include "chars.hpp" #include "plate.hpp" + +extern int annMain(); + namespace easypr { namespace demo { @@ -421,7 +424,7 @@ int main(int argc, const char* argv[]) { std::cout << "Run \"easypr_test svm\" for more usage." << std::endl; break; case 4: - // TODO + annMain(); break; case 5: easypr::preprocess::generate_gdts();