| | |
| | | #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) { |
| | |
| | | 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; |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | |
| | | 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) { |
| | |
| | | |
| | | |
| | | //将所有的数字格式化为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次,用于矩阵相减 |
| | |
| | | } |
| | | |
| | | 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; |
| | | } |