admin
2023-01-02 954ead41d9391bca28a3cc4f9592f73f25b3bbc8
ConsoleApplication/L2DataCapture.cpp
@@ -6,6 +6,7 @@
#include "TaskChecker.h"
#include "GPUtil.h"
#include "LogUtil.h"
#include "L2TradeQueueUtil.h"
//#define malloc(size) malloc(size)
//#define free(ptr) free(ptr)
@@ -14,6 +15,8 @@
bool L2DataCapture::tradeTimeCapture;
OpenCLExcuter* L2DataCapture::openCLExcuter[THS_FRAME_COUNT];
OpenCLExcuter* L2DataCapture::openCLExcuterQueue[THS_FRAME_COUNT];
TradeQueueCapture* L2DataCapture::tradeQueueCapture[THS_FRAME_COUNT];
@@ -45,6 +48,10 @@
         }
      }
      if (GPUtil::isBeforeTradeTime()) {
         Sleep(1000);
      }
      if (running && runnings[index] && gpCodes[index].length() > 0) {
         latest_running_times[index] = clock();
         //识别数据
@@ -61,13 +68,13 @@
            list<TradeData> resultList = captureLevel2TradeData(mat, index);
            long processTime = clock() - start;
            data_callback(index, code, start , processTime, resultList, context);
            data_callback(index, code, start, processTime, resultList, context);
            cout << "时间消耗:" << processTime << endl;
         }
         catch (string st) {
            //delete (openCLExcuter[index]);
            //openCLExcuter[index] = new OpenCLExcuter();
            //openCLExcuter[index]->init();
            //delete (openCLExcuter[index]);
            //openCLExcuter[index] = new OpenCLExcuter();
            //openCLExcuter[index]->init();
            LogUtil::getInstance()->getL2Logger().error(string("识别出错:").append(st));
         }
         catch (int error_code) {
@@ -88,12 +95,37 @@
void L2DataCapture::_run_trade_queue(int index)
{
   while (true) {
      if (killRunnings[index])
         break;
      TaskChecker::clientLiveTime.l2[index] = clock();
      if (tradeTimeCapture) {
         if (!GPUtil::isTradeTime()) {
            Sleep(2);
            continue;
         }
      }
      if (GPUtil::isBeforeTradeTime()) {
         Sleep(1000);
      }
      if (running && runnings[index] && gpCodes[index].length() > 0) {
         //识别数据
         string code = gpCodes[index];
         try {
            list<int> numList;//= tradeQueueCapture[index]->recognition(CaptureUtil::getHWND(index, CAPTURE_TYPE_TRADE_QUEUE));
            trade_queue_data_callback(index, code, numList, context);
            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);
            long processTime = clock() - start;
            cout << "时间消耗:" << processTime << endl;
            trade_queue_data_callback(index, code, result, context);
         }
         catch (...) {
@@ -134,22 +166,25 @@
   context = contex;
   for (int i = 0;i < THS_FRAME_COUNT;i++)
   for (int i = 0; i < THS_FRAME_COUNT; i++)
   {
      openCLExcuter[i] = new OpenCLExcuter();
      openCLExcuter[i]->init();
      openCLExcuterQueue[i]= new OpenCLExcuter();
      openCLExcuterQueue[i]->init();
      tradeQueueCapture[i] = new TradeQueueCapture();
   }
   running = false;
   int length = sizeof(runnings) / sizeof(runnings[0]);
   for (int i = 0;i < length;i++) {
   for (int i = 0; i < length; i++) {
      runnings[i] = false;
      thread rt(&(L2DataCapture::_run), i);
      rt.detach();
      killRunnings[i] = FALSE;
      //thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i);
      //rt_trade_queue.detach();
      thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i);
      rt_trade_queue.detach();
   }
   //获取同花顺窗口句柄
@@ -195,14 +230,14 @@
void L2DataCapture::startAll() {
   int length = sizeof(runnings) / sizeof(runnings[0]);
   for (int i = 0;i < length;i++) {
   for (int i = 0; i < length; i++) {
      runnings[i] = true;
   }
}
void L2DataCapture::stopAll() {
   int length = sizeof(runnings) / sizeof(runnings[0]);
   for (int i = 0;i < length;i++) {
   for (int i = 0; i < length; i++) {
      runnings[i] = false;
   }
}
@@ -218,12 +253,13 @@
   clock_t  starttime = clock();
   list<TradeData> resultList=  captureLevel2TradeData(openCLExcuter[identify], oimg, identify);
   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;
}
list<TradeData> L2DataCapture::captureLevel2TradeData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify)
{
@@ -295,7 +331,7 @@
   int* rowDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4);
   list<int*>::iterator e;
   int index = 0;
   for (e = rowDataList.begin();e != rowDataList.end();e++) {
   for (e = rowDataList.begin(); e != rowDataList.end(); e++) {
      int* indexs = *e;
      rowDataOneLevel[index * 4 + 0] = indexs[1];
      rowDataOneLevel[index * 4 + 1] = indexs[0];
@@ -317,7 +353,7 @@
      free(rowSplitDataOneLevel);
      throw string("图片分隔出错");
   }
   /*
   for (int i = 0;i < rowDataList.size();i++) {
@@ -358,7 +394,7 @@
   //结果初始化
   list<TradeData> resultList;
   for (int i = 0;i < rowDataList.size();i++) {
   for (int i = 0; i < rowDataList.size(); i++) {
      TradeData td = TradeData();
      resultList.push_back(td);
   }
@@ -371,15 +407,15 @@
   int i = 0;
   for (list<TradeData>::iterator ele = resultList.begin();ele != resultList.end();++ele) {
   for (list<TradeData>::iterator ele = resultList.begin(); ele != resultList.end(); ++ele) {
      switch (notNumberResult[i * 3])
      {
      case 0:
         (*ele).cancelTimeUnit = TIME_SECOND;break;
         (*ele).cancelTimeUnit = TIME_SECOND; break;
      case 1:
         (*ele).cancelTimeUnit = TIME_MINITE;break;
         (*ele).cancelTimeUnit = TIME_MINITE; break;
      case 2:
         (*ele).cancelTimeUnit = TIME_HOUR;break;
         (*ele).cancelTimeUnit = TIME_HOUR; break;
      default:
         break;
@@ -388,11 +424,11 @@
      switch (notNumberResult[i * 3 + 1])
      {
      case 0:
         (*ele).limitPrice = LIMIT_PRICE_NORMAL;break;
         (*ele).limitPrice = LIMIT_PRICE_NORMAL; break;
      case 1:
         (*ele).limitPrice = LIMIT_PRICE_UP;break;
         (*ele).limitPrice = LIMIT_PRICE_UP; break;
      case 2:
         (*ele).limitPrice = LIMIT_PRICE_DOWN;break;
         (*ele).limitPrice = LIMIT_PRICE_DOWN; break;
      default:
         break;
@@ -441,7 +477,7 @@
   index = 0;
   for (e = rowDataList.begin();e != rowDataList.end();e++) {
   for (e = rowDataList.begin(); e != rowDataList.end(); e++) {
      int startS = index * 4 * 7;
@@ -483,8 +519,8 @@
      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);
   for (int r = 0;r < _NUMBER_L2_HEIGHT;r++) {
      for (int c = 0;c < _NUMBER_L2_WIDTH;c++)
   for (int r = 0; r < _NUMBER_L2_HEIGHT; r++) {
      for (int c = 0; c < _NUMBER_L2_WIDTH; c++)
      {
         zeroData[r * _NUMBER_L2_WIDTH + c] = ImgUtil::NUMS_LEVEL2[0].data.ptr<uchar>(r)[c];
      }
@@ -553,10 +589,10 @@
   }
   */
   uchar** numberResult=nullptr;
   uchar** numberResult = nullptr;
   //数字识别
   try {
       numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER);
      numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER);
      //释放内存
      free(totalNumberData);
      free(templateNums);
@@ -571,7 +607,7 @@
   //循环读取数字
   list<TradeData>::iterator tradeEle;
   index = 0;
   for (tradeEle = resultList.begin();tradeEle != resultList.end();tradeEle++) {
   for (tradeEle = resultList.begin(); tradeEle != resultList.end(); tradeEle++) {
      uchar* lineData = numberResult[index];
      string time = "";
      time.append(to_string(lineData[0])).append(to_string(lineData[1]));
@@ -620,6 +656,189 @@
   return resultList;
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(HWND hwnd, int index)
{
   cv::Mat mat =   CaptureUtil::capture(hwnd);
   return captureLevel2TradeQueueData(mat,index);
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(cv::Mat& oimg, int identify)
{
   return captureLevel2TradeQueueData(openCLExcuterQueue[identify],oimg,identify);
}
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, 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("灰度出错");
      }
   }
   try {
      list<ImgArea> splitAreas = L2TradeQueueUtil::splitElements(img);
      int* splitResult = (int*)malloc(sizeof(int) * 4 * 6);
      int index = 0;
      for (list<ImgArea>::iterator ele = splitAreas.begin(); ele != splitAreas.end(); ++ele) {
         ImgArea area = *ele;
         if (area.startx < 0) {
            splitResult[index * 4 + 0] = 0;
            splitResult[index * 4 + 1] = 0;
            splitResult[index * 4 + 2] = 0;
            splitResult[index * 4 + 3] = 0;
         }
         else {
            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++;
      }
      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 = 6;
      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 };
      UcharDataInfo typesData = UcharDataInfo();
      typesData.length = 6;
      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];
      string sellOneTime = "";
      sellOneTime.append(to_string(lineData[0])).append(to_string(lineData[1]));
      sellOneTime.append(":");
      sellOneTime.append(to_string(lineData[2])).append(to_string(lineData[3]));
      sellOneTime.append(":");
      sellOneTime.append(to_string(lineData[4])).append(to_string(lineData[5]));
      string buyOneTime = "";
      buyOneTime.append(to_string(lineData[6])).append(to_string(lineData[7]));
      buyOneTime.append(":");
      buyOneTime.append(to_string(lineData[8])).append(to_string(lineData[9]));
      buyOneTime.append(":");
      buyOneTime.append(to_string(lineData[10])).append(to_string(lineData[11]));
      string sellOnePrice = "";
      for (int i = 0; i < 6; i++)
      {
         sellOnePrice.append(to_string(lineData[12 + i]));
         if (i == 3) {
            sellOnePrice.append(".");
         }
      }
      string sellOneNum = "";
      for (int i = 0; i < 6; i++)
      {
         sellOneNum.append(to_string(lineData[18 + i]));
      }
      string buyOnePrice = "";
      for (int i = 0; i < 6; i++)
      {
         buyOnePrice.append(to_string(lineData[24 + i]));
         if (i == 3) {
            buyOnePrice.append(".");
         }
      }
      string buyOneNum = "";
      for (int i = 0; i < 6; i++)
      {
         buyOneNum.append(to_string(lineData[30 + i]));
      }
      //释放内存
      free(lineData);
      index++;
      free(numberResult);
      L2TradeQueue tradeQueue = L2TradeQueue();
      tradeQueue.buyOnePrice = buyOnePrice;
      tradeQueue.buyOneVolumn = buyOneNum;
      tradeQueue.buyTime = buyOneTime;
      tradeQueue.sellOnePrice = sellOnePrice;
      tradeQueue.sellOneVolumn = sellOneNum;
      tradeQueue.sellTime = sellOneTime;
      return tradeQueue;
   }
   catch (...) {
      img.release();
      img = NULL;
      throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
   }
}
//捕获level2的盘口数据
list<TradeData> L2DataCapture::captureLevel2TradeData(HWND hwnd, int index) throw(int) {
   clock_t  starttime = clock();
@@ -641,7 +860,7 @@
      return resultList;
   }
   catch (int code) {
   }
   list<TradeData> tempList;
   return tempList;