admin
2022-06-27 eda1a611bc4afcf1c36a6c728f432aec1f688e1b
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;
               }