admin
2023-02-09 125db633619a0b4c7bd1d498ea2bf1cefa4f73d3
ConsoleApplication/L2DataCapture.cpp
@@ -7,6 +7,7 @@
#include "GPUtil.h"
#include "LogUtil.h"
#include "L2TradeQueueUtil.h"
#include "Win32Util.h"
//#define malloc(size) malloc(size)
//#define free(ptr) free(ptr)
@@ -38,6 +39,8 @@
void L2DataCapture::_run(int index)
{
   while (true) {
      clock_t origin_start_time = clock();
      if (killRunnings[index])
         break;
      TaskChecker::clientLiveTime.l2[index] = clock();
@@ -53,23 +56,39 @@
      }
      if (running && runnings[index] && gpCodes[index].length() > 0) {
         if (index == 0) {
            cout << "-----------------------开始--------------------  " << endl;
         }
         latest_running_times[index] = clock();
         //识别数据
         string code = gpCodes[index];
         try {
            clock_t start = clock();
            cv::Mat mat = CaptureUtil::capture(index, CAPTURE_TYPE_L2);
            if (mat.cols <= 400 || mat.rows <= 1800) {
            if (mat.cols <= 400 || mat.rows <= 1600) {
               mat.release();
               mat = NULL;
               Sleep(100);
               throw string("截图出错");
            }
            if (index == 0)
            {
               cout << "-----------截图时间消耗:---------  " << index << "  " << clock() - start << endl;
            }
            start = clock();
            list<TradeData*> resultList = captureLevel2TradeData(mat, index);
            long processTime = clock() - start;
            if (index == 0)
            {
               cout << "-----------识别时间消耗:---------- " << index << "  " << clock() - start << endl;
            }
            long processTime = clock() - origin_start_time;
            start = clock();
            data_callback(index, code, start, processTime, resultList, context);
            cout << "时间消耗:" << processTime << endl;
            if (index == 0)
            {
               cout << "------------数据回调时间消耗:-----------" << clock() - start << endl;
            }
         }
         catch (string st) {
            //delete (openCLExcuter[index]);
@@ -88,6 +107,14 @@
         }
      }
      Sleep(2);
      if (index == 0)
      {
         cout << "-----------整个L2周期时间消耗时间消耗:-------------  " << index << "  " << clock() - origin_start_time << endl;
      }
      if (index == 0)
      {
         cout << "-----------------------结束-------------------- \n\n " << endl;
      }
   }
}
@@ -114,17 +141,10 @@
         string code = gpCodes[index];
         try {
            clock_t start = clock();
            cv::Mat mat = CaptureUtil::capture(index, CAPTURE_TYPE_TRADE_QUEUE);
            if (mat.cols <= 400 || mat.rows <= 30) {
               mat.release();
               mat = NULL;
               Sleep(100);
               throw string("截图出错");
            }
            L2TradeQueue result = captureLevel2TradeQueueData(mat, index);
            HWND queueHWND = CaptureUtil::getHWND(index, CAPTURE_TYPE_TRADE_QUEUE);
            L2TradeQueue result = captureLevel2TradeQueueData(queueHWND, index);
            long processTime = clock() - start;
            cout << "时间消耗:" << processTime << endl;
            //cout << "时间消耗:" << processTime << endl;
            trade_queue_data_callback(index, code, result, context);
         }
         catch (...) {
@@ -133,6 +153,138 @@
      }
      Sleep(50);
   }
}
std::list<string> L2DataCapture::captureLevel2TradeQueueBuyData(OpenCLExcuter* openCLExcuter, cv::Mat& grayImg, int identify)
{
   if (grayImg.cols == 0 || grayImg.rows == 0) {
      return list<string>();
   }
   cv::Mat img;
   try {
      list<ImgArea> splitAreas = L2TradeQueueUtil::splitBuyQueue(grayImg, identify);
      int* splitResult = (int*)malloc(sizeof(int) * 4 * splitAreas.size());
      int index = 0;
      for (list<ImgArea>::iterator ele = splitAreas.begin(); ele != splitAreas.end(); ++ele) {
         ImgArea area = *ele;
         splitResult[index * 4 + 0] = area.startx;
         splitResult[index * 4 + 1] = area.starty;
         splitResult[index * 4 + 2] = area.endx;
         splitResult[index * 4 + 3] = area.endy;
         index++;
      }
      //二值化,方便处理
      threshold(grayImg, img, _IMG_BINARY_THRESHOLD, 255, cv::THRESH_BINARY);
      clock_t time_2 = clock();
      unsigned char* zeroData = (unsigned char*)malloc(sizeof(unsigned char) * _NUMBER_GP_CODE_WIDTH * _NUMBER_GP_CODE_HEIGHT);
      for (int r = 0; r < _NUMBER_GP_CODE_HEIGHT; r++) {
         for (int c = 0; c < _NUMBER_GP_CODE_WIDTH; c++)
         {
            zeroData[r * _NUMBER_GP_CODE_WIDTH + c] = ImgUtil::NUMS_GP_CODE[0].data.ptr<uchar>(r)[c];
         }
      }
      int num_length_per_ele = 5;
      //splitAreasQueue最多12个数字
      int ele_count_per_line = splitAreas.size();
      int line_number_count = ele_count_per_line * num_length_per_ele;
      unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
      unsigned char types[] = { NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM,NUM_TYPE_NUM };
      UcharDataInfo typesData = UcharDataInfo();
      typesData.length = ele_count_per_line;
      typesData.data = types;
      openCLExcuter->splitPlateNum(img, IntDataInfo({ splitResult,(int)(ele_count_per_line * 1) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, ele_count_per_line, num_length_per_ele);
      free(splitResult);
      free(zeroData);
      //识别
      uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
      try {
         openCLExcuter->createNumberTemplates(1, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count, ImgUtil::numsOneLevel_gpcode, templateNums);
      }
      catch (...) {
         free(totalNumberData);
         free(templateNums);
         throw string("创建数据模板出错");
      }
      uchar** numberResult = nullptr;
      //数字识别
      try {
         numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, 1 * _NUMBER_GP_CODE_HEIGHT, _NUMBER_GP_CODE_WIDTH * 10 * line_number_count, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count);
         //释放内存
         free(totalNumberData);
         free(templateNums);
      }
      catch (...) {
         //释放内存
         free(totalNumberData);
         free(templateNums);
         throw string("数字识别出错");
      }
      img.release();
      //循环读取数字
      uchar* lineData = numberResult[0];
      list<string> buyQueueList;
      for (int i = 0; i < ele_count_per_line; i++) {
         string num = "";
         for (int j = 0; j < num_length_per_ele; j++) {
            num.append(to_string(lineData[num_length_per_ele * i + j]));
         }
         buyQueueList.push_back(num);
      }
      //释放内存
      free(lineData);
      index++;
      free(numberResult);
      return buyQueueList;
   }
   catch (...) {
      img.release();
      img = NULL;
      throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
   }
}
cv::Mat L2DataCapture::grayImg(OpenCLExcuter* openCLExcuter, cv::Mat& oimg)
{
   cv::Mat img = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
   if (oimg.channels() == 1) {
      //黑白图片
      img.data = oimg.data;
   }
   else {
      try {
         if (oimg.channels() == 3)
         {
            openCLExcuter->rgb2Gray(oimg, img.data);
         }
         else {
            openCLExcuter->rgba2Gray(oimg, img.data);
         }
         oimg.release();
      }
      catch (...) {
         oimg.release();
         oimg = NULL;
         img.release();
         img = NULL;
         throw string("灰度出错");
      }
   }
   return img;
}
void L2DataCapture::setGPCode(int index, string code) {
@@ -170,7 +322,7 @@
   {
      openCLExcuter[i] = new OpenCLExcuter();
      openCLExcuter[i]->init();
      openCLExcuterQueue[i]= new OpenCLExcuter();
      openCLExcuterQueue[i] = new OpenCLExcuter();
      openCLExcuterQueue[i]->init();
      tradeQueueCapture[i] = new TradeQueueCapture();
@@ -255,7 +407,7 @@
   list<TradeData*> resultList = captureLevel2TradeData(openCLExcuter[identify], oimg, identify);
   std::cout << "-------L2行情识别结束任务: threadid-" << std::this_thread::get_id() << "  序号:" << identify << " CODE:" << gpCodes[identify] << " 耗时:" << clock() - starttime << "  数据量:" << resultList.size() << endl;
   //std::cout << "-------L2行情识别结束任务: threadid-" << std::this_thread::get_id() << "  序号:" << identify << " CODE:" << gpCodes[identify] << " 耗时:" << clock() - starttime << "  数据量:" << resultList.size() << endl;
   return resultList;
}
@@ -263,6 +415,7 @@
list<TradeData*> L2DataCapture::captureLevel2TradeData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify)
{
   bool ENABLE_LOG = FALSE;
   if (oimg.cols <= 0 || oimg.rows <= 0) {
      throw string("图像数据错误");
@@ -300,7 +453,7 @@
      }
      //img.data = imgData;
      clock_t time_2_ = clock();
      if (identify == 0)
      if (identify == 0&& ENABLE_LOG)
      {
         std::cout << "灰度完成: threadid-" << std::this_thread::get_id() << " 耗时:" << (time_2_ - time_1) << "   截图尺寸:" << img.cols << "x" << img.rows << endl;
@@ -389,13 +542,13 @@
   clock_t time_3 = clock();
   //LogUtil::debug("分隔完成");
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "分隔完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_3 - time_2 << "总耗时:" << time_3 - time_1 << endl;
   //结果初始化
   list<TradeData*> resultList;
   for (int i = 0; i < rowDataList.size(); i++) {
      TradeData *td = new TradeData;
      TradeData* td = new TradeData;
      resultList.push_back(td);
   }
@@ -458,7 +611,7 @@
   free(notNumberResult);
   clock_t time_5 = clock();
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "非数字数据识别完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_5 - time_3 << "总耗时:" << time_5 - time_1 << endl;
@@ -470,7 +623,7 @@
   unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowDataList.size()) * _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER);
   clock_t time_31 = clock();
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数据准备-图像数据准备: threadid-" << std::this_thread::get_id() << " 耗时:" << time_31 - time_3 << "总耗时:" << time_31 - time_1 << endl;
   int* pos = (int*)malloc(sizeof(int) * 4 * 4 * rowDataList.size());
@@ -517,7 +670,7 @@
   clock_t time_32 = clock();
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数据准备-位置数据准备: threadid-" << std::this_thread::get_id() << " 耗时:" << time_32 - time_31 << "总耗时:" << time_32 - time_1 << endl;
   unsigned char* zeroData = (unsigned char*)malloc(sizeof(unsigned char) * _NUMBER_L2_WIDTH * _NUMBER_L2_HEIGHT);
@@ -529,7 +682,7 @@
   }
   clock_t time_33 = clock();
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数据准备-0数据准备: threadid-" << std::this_thread::get_id() << " 耗时:" << time_33 - time_32 << "总耗时:" << time_33 - time_1 << endl;
   try {
      openCLExcuter->splitL2Num(img.data, img.cols, img.rows, pos, 4 * rowDataList.size(), zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, totalNumberData);
@@ -555,7 +708,7 @@
   */
   clock_t time_34 = clock();
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数据准备-数字分隔完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_34 - time_33 << "总耗时:" << time_34 - time_1 << endl;
   //准备模板数字
@@ -572,11 +725,11 @@
   //ImgUtil::createTemplateNumData(data.size());
   clock_t time_4 = clock();
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数据准备-模板数字准备完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_4 - time_34 << "总耗时:" << time_4 - time_1 << endl;
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数据准备完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_4 - time_3 << "总耗时:" << time_4 - time_1 << endl;
@@ -647,60 +800,79 @@
   clock_t time_6 = clock();
   //LogUtil::debug("识别完成");
   if (identify == 0)
   if (identify == 0 && ENABLE_LOG)
      std::cout << "数字识别完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_6 - time_5 << "总耗时:" << time_6 - time_1 << endl;
   //释放内存
   img.release();
   rowDataList.clear();
   list<int*>().swap(rowDataList);
   return resultList;
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(HWND hwnd, int index)
{
   cv::Mat mat =   CaptureUtil::capture(hwnd);
   return captureLevel2TradeQueueData(mat,index);
   HWND buyQueueHWND = L2TradeQueueUtil::getTradeQueueBuyHWND(hwnd);
   //获取位置
   RECT prect;
   Win32Util::getWindowRect(hwnd, &prect);
   RECT buyRect;
   Win32Util::getWindowRect(buyQueueHWND, &buyRect);
   cv::Mat mat = CaptureUtil::capture(hwnd);
   if (mat.cols <= 400 || mat.rows <= 30) {
      mat.release();
      mat = NULL;
      Sleep(100);
      throw string("截图出错");
   }
   cv::Rect rect = cv::Rect(buyRect.left - prect.left, buyRect.top - prect.top, buyRect.right - buyRect.left + 1, buyRect.bottom - buyRect.top + 1);
   return captureLevel2TradeQueueData(mat, rect, index);
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(cv::Mat& oimg, int identify)
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(cv::Mat& oimg, cv::Rect buyQueueArea, int identify)
{
   return captureLevel2TradeQueueData(openCLExcuterQueue[identify],oimg,identify);
   return captureLevel2TradeQueueData(openCLExcuterQueue[identify], oimg, buyQueueArea, identify);
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify)
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, cv::Rect buyQueueArea, int identify)
{
   cv::Mat img = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
   if (oimg.channels() == 1) {
      //黑白图片
      img.data = oimg.data;
   }
   else {
      try {
         if (oimg.channels() == 3)
         {
            openCLExcuter->rgb2Gray(oimg, img.data);
         }
         else {
            openCLExcuter->rgba2Gray(oimg, img.data);
         }
         oimg.release();
      }
      catch (...) {
         oimg.release();
         oimg = NULL;
         img.release();
         img = NULL;
         throw string("灰度出错");
   cv::Mat img = grayImg(openCLExcuter, oimg);
   cv::Mat tmpImg = cv::Mat(img, buyQueueArea);
   cv::Mat   buyQueueImg = cv::Mat::zeros(buyQueueArea.height, buyQueueArea.width, CV_8UC1);
   uchar* datas = (uchar*)malloc(sizeof(uchar)* buyQueueArea.height* buyQueueArea.width);
   for (int r = 0; r < buyQueueImg.rows; r++) {
      for (int c = 0; c < buyQueueImg.cols; c++) {
         datas[r * buyQueueImg.cols + c] = tmpImg.ptr<uchar>(r)[c];
      }
   }
   buyQueueImg.data = datas;
   //过滤黄底白字
   L2TradeQueueUtil::filterTradeQueueBuyMat(buyQueueImg);
   if (FALSE)
   {
      string path = string("C:\\Users\\Administrator\\Desktop\\ocr\\trade_queue\\origin\\").append(to_string(identify)).append("_").append(to_string(rand()).append(".png"));
      cv::imwrite(path, buyQueueImg);
   }
   L2TradeQueue tradeQueue = captureLevel2TradeQueueViewData(openCLExcuter, img, identify);
   try {
      list<ImgArea> splitAreas = L2TradeQueueUtil::splitElements(img);
      int* splitResult = (int*)malloc(sizeof(int) * 4 * 6);
      std::list<string> buyQueueList = captureLevel2TradeQueueBuyData(openCLExcuter, buyQueueImg, identify);
      tradeQueue.buyQueue = buyQueueList;
   }
   catch (...) {
   }
   free(datas);
   return tradeQueue;
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueViewData(OpenCLExcuter* openCLExcuter, cv::Mat& img, int identify)
{
   L2TradeQueue tradeQueue;
   try {
      list<ImgArea> splitAreas = L2TradeQueueUtil::splitViewElements(img);
      int* splitResult = (int*)malloc(sizeof(int) * 4 * splitAreas.size());
      int index = 0;
      for (list<ImgArea>::iterator ele = splitAreas.begin(); ele != splitAreas.end(); ++ele) {
         ImgArea area = *ele;
@@ -730,12 +902,13 @@
         }
      }
      int num_length_per_ele = 7;
      //splitAreasQueue最多8个数字
      int ele_count_per_line = 6;
      int line_number_count = ele_count_per_line * num_length_per_ele;
      unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
      unsigned char types[] = { NUM_TYPE_TIME,NUM_TYPE_TIME,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU };
      unsigned char types[] = { NUM_TYPE_TIME,NUM_TYPE_TIME,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU,NUM_TYPE_NUM,NUM_TYPE_NUM };
      UcharDataInfo typesData = UcharDataInfo();
      typesData.length = 6;
      typesData.length = ele_count_per_line;
      typesData.data = types;
      openCLExcuter->splitPlateNum(img, IntDataInfo({ splitResult,(int)(ele_count_per_line * 1) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, ele_count_per_line, num_length_per_ele);
@@ -781,7 +954,7 @@
      sellOneTime.append(to_string(lineData[5])).append(to_string(lineData[6]));
      string buyOneTime = "";
      buyOneTime.append(to_string(lineData[num_length_per_ele*1+1])).append(to_string(lineData[num_length_per_ele * 1 + 2]));
      buyOneTime.append(to_string(lineData[num_length_per_ele * 1 + 1])).append(to_string(lineData[num_length_per_ele * 1 + 2]));
      buyOneTime.append(":");
      buyOneTime.append(to_string(lineData[num_length_per_ele * 1 + 3])).append(to_string(lineData[num_length_per_ele * 1 + 4]));
      buyOneTime.append(":");
@@ -822,9 +995,9 @@
      free(lineData);
      index++;
      free(numberResult);
      L2TradeQueue tradeQueue = L2TradeQueue();
      tradeQueue = L2TradeQueue();
      tradeQueue.buyOnePrice = buyOnePrice;
      tradeQueue.buyOneVolumn = buyOneNum;
      tradeQueue.buyTime = buyOneTime;
@@ -838,7 +1011,6 @@
      img = NULL;
      throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
   }
}
//捕获level2的盘口数据