From eda1a611bc4afcf1c36a6c728f432aec1f688e1b Mon Sep 17 00:00:00 2001 From: admin <weikou2014> Date: 星期一, 27 六月 2022 19:13:36 +0800 Subject: [PATCH] 'GP代码识别' --- ConsoleApplication/ImgUtil.cpp | 137 ++++++++++++++++++++++++++++++++++++--------- 1 files changed, 108 insertions(+), 29 deletions(-) diff --git a/ConsoleApplication/ImgUtil.cpp b/ConsoleApplication/ImgUtil.cpp index bb56699..6299532 100644 --- a/ConsoleApplication/ImgUtil.cpp +++ b/ConsoleApplication/ImgUtil.cpp @@ -1,9 +1,65 @@ #include "ImgUtil.h" -NumberData ImgUtil::NUMS[10]; -uchar* ImgUtil::numsOneLevel; -const int ImgUtil::NUM_WIDTH; -const int ImgUtil::NUM_HEIGHT; +NumberData ImgUtil::NUMS_LEVEL2[10]; +NumberData ImgUtil::NUMS_GP_CODE[10]; +uchar* ImgUtil::numsOneLevel_level2; +uchar* ImgUtil::numsOneLevel_gpcode; + +cv::Mat ImgUtil::formatNumGPCode(cv::Mat num) throw(string) { + if (num.empty()) { + //空值填充0 + cv::Mat zero; + ImgUtil::NUMS_GP_CODE[0].data.copyTo(zero); + return zero; + } + + //去除周围的黑边 + int rows = num.rows; + int cols = num.cols; + int startRow = -1, endRow = -1; + for (int r = 0;r < rows;r++) { + if (!ImgDivider::isRowEmpty(num, r)) { + startRow = r; + break; + } + } + + for (int r = rows - 1;r > -1;r--) { + if (!ImgDivider::isRowEmpty(num, r)) { + endRow = r; + break; + } + } + //去除前后的白边 + int startCol = -1, endCol = -1; + for (int c = 0;c < cols;c++) { + if (!ImgDivider::isColEmpty(num, c, 1)) { + startCol = c; + break; + } + } + + for (int c = cols - 1;c > -1;c--) { + if (!ImgDivider::isColEmpty(num, c, 1)) { + endCol = c; + break; + } + } + + num = cv::Mat(num, cv::Rect(startCol, startRow, endCol - startCol + 1, endRow - startRow + 1)); + + //判断列数是否正常 + if (num.cols == _NUMBER_GP_CODE_WIDTH && num.rows == _NUMBER_GP_CODE_HEIGHT) { + return num; + } + //往右下角添加数据 + cv::Mat m = cv::Mat::zeros(num.rows, _NUMBER_GP_CODE_WIDTH - num.cols, CV_8UC1); + cv::Mat dst; + cv::hconcat(num, m, dst); + return dst; +} + + //分隔时间 list<cv::Mat> ImgUtil::splitTime(cv::Mat src) throw(std::string) { @@ -199,7 +255,7 @@ list<cv::Mat> ImgUtil::splitNum(cv::Mat src) throw(string) { cv::Mat binary; //去除上下的空白图 - threshold(src, binary, 40, 255, cv::THRESH_BINARY); + threshold(src, binary, _IMG_BINARY_THRESHOLD, 255, cv::THRESH_BINARY); int rows = src.rows; int cols = src.cols; @@ -286,11 +342,11 @@ return resultList; } -cv::Mat ImgUtil::formatNum(cv::Mat num) throw(string) { +cv::Mat ImgUtil::formatNumLevel2(cv::Mat num) throw(string) { if (num.empty()) { //空值填充0 cv::Mat zero; - ImgUtil::NUMS[0].data.copyTo(zero); + ImgUtil::NUMS_LEVEL2[0].data.copyTo(zero); return zero; } @@ -330,11 +386,11 @@ num = cv::Mat(num, cv::Rect(startCol, startRow, endCol - startCol + 1, endRow - startRow + 1)); //判断列数是否正常 - if (num.cols == 5 && num.rows == 8) { + if (num.cols == _NUMBER_L2_WIDTH && num.rows == _NUMBER_L2_HEIGHT) { return num; } //往右下角添加数据 - cv::Mat m = cv::Mat::zeros(num.rows, 5 - num.cols, CV_8UC1); + cv::Mat m = cv::Mat::zeros(num.rows, _NUMBER_L2_WIDTH - num.cols, CV_8UC1); cv::Mat dst; cv::hconcat(num, m, dst); return dst; @@ -351,27 +407,50 @@ void ImgUtil::init() { - + //LEVE2数字初始化 for (int i = 0;i < 10;i++) { std::string sdir = "C:\\Users\\Administrator\\Desktop\\ocr\\number\\"; std::string path = sdir.append(std::to_string(i)).append(".jpg"); NumberData data = NumberData(); - data.data = formatNum(cv::imread(path.c_str(), cv::IMREAD_GRAYSCALE)); + data.data = formatNumLevel2(cv::imread(path.c_str(), cv::IMREAD_GRAYSCALE)); data.num = std::to_string(i); - NUMS[i] = data; + NUMS_LEVEL2[i] = data; } - numsOneLevel = (uchar*)malloc(sizeof(uchar) * NUM_HEIGHT * NUM_WIDTH * 10); + numsOneLevel_level2 = (uchar*)malloc(sizeof(uchar) * _NUMBER_L2_HEIGHT * _NUMBER_L2_WIDTH * 10); for (int i = 0;i < 10;i++) { - int baseIndex = i * NUM_HEIGHT * NUM_WIDTH; - for (int r = 0;r < NUM_HEIGHT;r++) { - int baseIndex_1 = r * NUM_WIDTH; - for (int c = 0;c < NUM_WIDTH;c++) { + int baseIndex = i * _NUMBER_L2_HEIGHT * _NUMBER_L2_WIDTH; + for (int r = 0;r < _NUMBER_L2_HEIGHT;r++) { + int baseIndex_1 = r * _NUMBER_L2_WIDTH; + for (int c = 0;c < _NUMBER_L2_WIDTH;c++) { int index = baseIndex + baseIndex_1 + c; - numsOneLevel[index] = NUMS[i].data.ptr<uchar>(r)[c]; + numsOneLevel_level2[index] = NUMS_LEVEL2[i].data.ptr<uchar>(r)[c]; } } } + + + for (int i = 0;i < 10;i++) { + std::string sdir = "C:\\Users\\Administrator\\Desktop\\ocr\\number_2\\"; + std::string path = sdir.append(std::to_string(i)).append(".jpg"); + NumberData data = NumberData(); + data.data = formatNumGPCode(cv::imread(path.c_str(), cv::IMREAD_GRAYSCALE)); + data.num = std::to_string(i); + NUMS_GP_CODE[i] = data; + } + + numsOneLevel_gpcode = (uchar*)malloc(sizeof(uchar) * _NUMBER_GP_CODE_HEIGHT * _NUMBER_GP_CODE_WIDTH * 10); + for (int i = 0;i < 10;i++) { + int baseIndex = i * _NUMBER_GP_CODE_HEIGHT * _NUMBER_GP_CODE_WIDTH; + for (int r = 0;r < _NUMBER_GP_CODE_HEIGHT;r++) { + int baseIndex_1 = r * _NUMBER_GP_CODE_WIDTH; + for (int c = 0;c < _NUMBER_GP_CODE_WIDTH;c++) { + int index = baseIndex + baseIndex_1 + c; + numsOneLevel_gpcode[index] = NUMS_GP_CODE[i].data.ptr<uchar>(r)[c]; + } + } + } + } list<int*> ImgUtil::divideImg(cv::Mat img) { @@ -790,14 +869,14 @@ //将所有的数字格式化为5*8的点阵格式 - int ROW = ImgUtil::NUM_HEIGHT, COL = ImgUtil::NUM_WIDTH; - int rowData = ROW * COL * 10 * 17; + int ROW = _NUMBER_L2_HEIGHT, COL = _NUMBER_L2_WIDTH; + int rowData = ROW * COL * 10 * _NUMBER_L2_TOTAL_NUMBER; list<cv::Mat>::iterator eleM; index = 0; for (eleM = numList.begin();eleM != numList.end();eleM++) { index++; - cv::Mat numMat = formatNum(*eleM); + cv::Mat numMat = formatNumLevel2(*eleM); //转为数组的形式 for (int r = 0;r < ROW;r++) { //将每个数字重复加入10次,用于矩阵相减 @@ -846,25 +925,25 @@ } uchar* ImgUtil::createTemplateNumData(int lines) { - int LINE_NUMBER_COUNT = 17; + int LINE_NUMBER_COUNT = _NUMBER_L2_TOTAL_NUMBER; int NUMBER_COUNT = 10; - unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (ImgUtil::NUM_HEIGHT * lines) * ImgUtil::NUM_WIDTH * NUMBER_COUNT * LINE_NUMBER_COUNT); - int outLineDataCount = ImgUtil::NUM_HEIGHT * ImgUtil::NUM_WIDTH * NUMBER_COUNT * LINE_NUMBER_COUNT; - int inLineDataCount = ImgUtil::NUM_WIDTH * NUMBER_COUNT * LINE_NUMBER_COUNT; + unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * lines) * _NUMBER_L2_WIDTH * NUMBER_COUNT * LINE_NUMBER_COUNT); + int outLineDataCount = _NUMBER_L2_HEIGHT * _NUMBER_L2_WIDTH * NUMBER_COUNT * LINE_NUMBER_COUNT; + int inLineDataCount = _NUMBER_L2_WIDTH * NUMBER_COUNT * LINE_NUMBER_COUNT; for (int l = 0;l < lines;l++) { int outLineCount = outLineDataCount * l; for (int re = 0;re < LINE_NUMBER_COUNT;re++) { for (int n = 0;n < NUMBER_COUNT;n++) { - for (int r = 0;r < ImgUtil::NUM_HEIGHT;r++) { + for (int r = 0;r < _NUMBER_L2_HEIGHT;r++) { int intLineCount = inLineDataCount * r; - for (int c = 0;c < ImgUtil::NUM_WIDTH;c++) { - uchar value = ImgUtil::NUMS[n].data.ptr(r)[c]; + for (int c = 0;c < _NUMBER_L2_WIDTH;c++) { + uchar value = ImgUtil::NUMS_LEVEL2[n].data.ptr(r)[c]; int index = outLineCount; index += intLineCount; - int x = re * NUMBER_COUNT * ImgUtil::NUM_WIDTH + n * ImgUtil::NUM_WIDTH + c; + int x = re * NUMBER_COUNT * _NUMBER_L2_WIDTH + n * _NUMBER_L2_WIDTH + c; index += x; data[index] = value > 40 ? 1 : 0; } -- Gitblit v1.8.0