admin
2023-03-07 8b06b1cbf112d55307ea8a6efe711db4e7506d89
ConsoleApplication/LimitUpCapture.cpp
@@ -4,6 +4,7 @@
#include "Win32Util.h"
#include "TaskChecker.h"
#include "GPUtil.h"
#include "OpenCLUtil.h"
bool LimitUpCapture::tradeTimeCapture;
OpenCLExcuter* LimitUpCapture::openCLExcuter;
bool LimitUpCapture::inited;
@@ -13,9 +14,13 @@
bool LimitUpCapture::kill;
CallbackFun_Limit_Up LimitUpCapture::data_callback;
CallbackFun_First_Limit_Up LimitUpCapture::first_data_callback;
MatOcrFun  LimitUpCapture::ocr_fun;
std::list<cv::Point> LimitUpCapture::pointList;
cv::Point LimitUpCapture::limitUpPoint;
cv::Point LimitUpCapture::firstCodePoint;
void* LimitUpCapture::context;
@@ -45,15 +50,17 @@
      if (running && inited) {
         clock_t start = clock();
         try {
            list<LimitUpData> codes = captureLimitUpCodes();
            //cout << "耗时:" << clock() - start << "  数量:" << codes.size() << endl;
            data_callback(codes, context);
            codes.clear();
            LimitUpFinalData finalData = captureLimitUpCodes();
            cout << "涨停识别耗时:" << clock() - start  << endl;
            data_callback(finalData.limitUpDatas, context);
            first_data_callback(finalData.firstLimitUpDatas, context);
            finalData.limitUpDatas.clear();
            finalData.firstLimitUpDatas.clear();
         }
         catch (...) {
         
         }
         Sleep(3000);
         Sleep(50);
      }
      else {
         Sleep(1000);
@@ -63,8 +70,9 @@
bool LimitUpCapture::pause;
void LimitUpCapture::init(CallbackFun_Limit_Up callback, MatOcrFun matMcrFun, void* contex) {
void LimitUpCapture::init(CallbackFun_Limit_Up callback, CallbackFun_First_Limit_Up first_callback, MatOcrFun matMcrFun, void* contex) {
   data_callback = callback;
   first_data_callback = first_callback;
   ocr_fun = matMcrFun;
   context = contex;
   running = false;
@@ -75,6 +83,7 @@
   rt.detach();
   inited = true;
   try {
      if(matMcrFun!=NULL)
      refreshHWND();
   }
   catch (...) {
@@ -92,7 +101,7 @@
void LimitUpCapture::refreshHWND() {
   HWND hwnd = getWindow();
   if (hwnd <= 0)
      throw string("同花顺副屏2未打开");
      throw string("同花顺副屏1未打开");
   //输入快捷键51定位到我的版块
   Win32Util::showWindow(hwnd);
   Win32Util::focus(hwnd);
@@ -115,24 +124,30 @@
   do {
      maxCount++;
      child = FindWindowExA(content, child, "AfxWnd100s", NULL);
      if (!Win32Util::isWindowShow(child)) {
         continue;
      }
      GetWindowRect(child, &tempRect);
   } while ((!IsWindowVisible(child) || tempRect.right - tempRect.left > tempRect.bottom - tempRect.top) && maxCount < 10);//没显示或者宽大于高
   HWND temp= FindWindowExA(child, NULL, NULL, NULL);
   for (int i = 0;i < 10;i++) {
      GetWindowRect(temp, &tempRect);
      if (!IsWindowVisible(temp) || tempRect.bottom - tempRect.top < 100) {
         temp= FindWindowExA(child, temp, NULL, NULL);
      if (tempRect.right- tempRect.left>1000) {
         continue;
      }
      else {
         break;
      if (tempRect.right - tempRect.left > tempRect.bottom - tempRect.top) {
         continue;
      }
   }
   temp= FindWindowExA(temp, NULL, "block_list_page", NULL);
      HWND temp =   FindWindowExA(child, NULL, "#32770", NULL);
      if (temp > 0) {
         temp =   FindWindowExA(temp, NULL, "block_list_page", NULL);
         if (temp > 0) {
            menuWin = temp;
            break;
         }
      }
   menuWin = temp;
   } while (maxCount < 20);
   if (menuWin <= 0)
      throw string("未获取到内容窗口的菜单句柄");
@@ -140,15 +155,27 @@
   //查找菜单的位置
   cv::Mat grayImg = ImgUtil::grayImage(CaptureUtil::capture(menuWin));
   pointList.clear();
   // 获取涨停的坐标位置
   list<OCRResult> ocrResultList = ocr_fun("今日", grayImg);
   if (ocrResultList.size() > 0) {
      for (list<OCRResult>::iterator ele = ocrResultList.begin(); ele != ocrResultList.end(); ele++) {
         OCRResult result = *ele;
         pointList.push_back(cv::Point((result.rect.left+result.rect.right)/2, (result.rect.top + result.rect.bottom) / 2));
         limitUpPoint = (cv::Point((result.rect.left+result.rect.right)/2, (result.rect.top + result.rect.bottom) / 2));
         ImgUtil::markMat(grayImg, cv::Rect(result.rect.left, result.rect.top, result.rect.right - result.rect.left +1, result.rect.bottom - result.rect.top + 1), 255, 1);
         break;
      }
   }
   //获取首板的坐标位置
   ocrResultList = ocr_fun("首板", grayImg);
   if (ocrResultList.size() > 0) {
      for (list<OCRResult>::iterator ele = ocrResultList.begin(); ele != ocrResultList.end(); ele++) {
         OCRResult result = *ele;
         firstCodePoint=(cv::Point((result.rect.left + result.rect.right) / 2, (result.rect.top + result.rect.bottom) / 2));
         ImgUtil::markMat(grayImg, cv::Rect(result.rect.left, result.rect.top, result.rect.right - result.rect.left + 1, result.rect.bottom - result.rect.top + 1), 255, 1);
         break;
      }
   }
   //保存临时图片 
   //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\menu.jpg", grayImg);
}
@@ -158,28 +185,18 @@
}
list<LimitUpData> LimitUpCapture::captureLimitUpCodes(cv::Mat oimg) {
   cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);//ImgUtil::grayImage(oimg);
   cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
   uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols);
   try {
      if (oimg.channels() == 3)
      {
         openCLExcuter->rgb2Gray(oimg, imgData);
      }
      else {
         openCLExcuter->rgba2Gray(oimg, imgData);
      }
      grayImg = OpenCLUtil::grayImg(openCLExcuter, oimg);
   }
   catch (...) {
      //保存原始图片
      //string path = "D:\\imgs\\img.png";
      //cv::imwrite(path, oimg);
      oimg.release();
      free(imgData);
      imgData = NULL;
      throw string("灰度出错");
   }
   grayImg.data = imgData;
@@ -189,7 +206,6 @@
      rowData = THSActionUtil::splitPlateRowArea(grayImg);
   }
   catch (string st) {
      free(imgData);
      throw st;
   }
@@ -382,46 +398,306 @@
   free(splitResult);
   free(zeroData);
   free(templateNums);
   free(imgData);
   grayImg.release();
   return dataList;
}
list<LimitUpData> LimitUpCapture::captureLimitUpCodes() {
list<FirstLimitUpCodeData> LimitUpCapture::captureLimitUpFirstCodes(cv::Mat oimg)
{
   cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
   try {
      grayImg = OpenCLUtil::grayImg(openCLExcuter, oimg);
   }
   catch (...) {
      //保存原始图片
      //string path = "D:\\imgs\\img.png";
      //cv::imwrite(path, oimg);
      oimg.release();
      throw string("灰度出错");
   }
   list<int*> rowData;
   try {
      rowData = THSActionUtil::splitPlateRowArea(grayImg);
   }
   catch (string st) {
      throw st;
   }
   //每行的元素个数
   int ele_count_per_line = 6;
   int num_length_per_ele = 6;
   int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size());
   int* rowIndex = (int*)malloc(sizeof(int) * 4 * rowData.size());
   int count = 0;
   for (std::list<int*>::iterator ele = rowData.begin(); ele != rowData.end(); ele++) {
      string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
      path.append(to_string(count)).append(".jpg");
      //cv::imwrite(path, cv::Mat(grayImg, cv::Rect((*ele)[0], (*ele)[1], (*ele)[2] - (*ele)[0] + 1, (*ele)[3] - (*ele)[1] + 1)));
      rowIndex[4 * count + 0] = (*ele)[0];
      rowIndex[4 * count + 1] = (*ele)[1];
      rowIndex[4 * count + 2] = (*ele)[2];
      rowIndex[4 * count + 3] = (*ele)[3];
      free(*ele);
      count++;
   }
   int line_number_count = ele_count_per_line * num_length_per_ele;
   openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 1, ele_count_per_line, splitResult);
   //测试
   set<int> excudeIndexs;
   for (int i = 0; i < rowData.size(); i++) {
      for (int j = 0; j < ele_count_per_line; j++) {
         int sx = splitResult[(ele_count_per_line * i + j) * 4 + 0];
         int sy = splitResult[(ele_count_per_line * i + j) * 4 + 1];
         int ex = splitResult[(ele_count_per_line * i + j) * 4 + 2];
         int ey = splitResult[(ele_count_per_line * i + j) * 4 + 3];
         string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
         path.append(to_string(i)).append("_").append(to_string(j)).append(".jpg");
         //cv::imwrite(path, cv::Mat(grayImg, cv::Rect(sx, sy, ex - sx + 1, ey - sy + 1)));
      }
      int sx = splitResult[(ele_count_per_line * i + 1) * 4 + 0];
      int ex = splitResult[(ele_count_per_line * i + 1) * 4 + 2];
      if (ex - sx < 20) {
         //噪点数据
         excudeIndexs.insert(i);
      }
   }
   int start = 4 * 4 * 1 + 4 * 1;
   string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
   path.append(to_string(start)).append(".jpg");
   //cv::imwrite(path, cv::Mat(grayImg,cv::Rect(splitResult[start], splitResult[start+1], splitResult[start+2]- splitResult[start]+1, splitResult[start+3]- splitResult[start+1]+1)));
   //cv::imwrite(path, cv::Mat(grayImg, cv::Rect(447, 102, 454-447+1,111-102+1 )));
   //分割数字
   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];
      }
   }
   unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * rowData.size()) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
   unsigned char types[] = { NUM_TYPE_MONEY,NUM_TYPE_MONEY,NUM_TYPE_CODE,NUM_TYPE_TIME, NUM_TYPE_PRICE,NUM_TYPE_PERCENT };
   UcharDataInfo typesData = UcharDataInfo();
   typesData.length = 6;
   typesData.data = types;
   openCLExcuter->splitPlateNum(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, ele_count_per_line, num_length_per_ele);
   //识别数字
   uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * rowData.size()) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
   openCLExcuter->createNumberTemplates(rowData.size(), _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count, ImgUtil::numsOneLevel_gpcode, templateNums);
   uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowData.size() * _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);
   list<FirstLimitUpCodeData> dataList;
   for (int i = 0; i < rowData.size(); i++) {
      if (excudeIndexs.count(i) > 0) {
         continue;
      }
      FirstLimitUpCodeData limitUpData = FirstLimitUpCodeData();
      string money = "";
      for (int j = 0; j < num_length_per_ele; j++)
      {
         if (j == 4) {
            money.append(".");
         }
         money.append(to_string(numberResult[i][num_length_per_ele * 0 + j]));
      }
      string volume = "";
      for (int j = 0; j < num_length_per_ele; j++)
      {
         if (j == 4) {
            volume.append(".");
         }
         volume.append(to_string(numberResult[i][num_length_per_ele * 1 + j]));
      }
      string code = "";
      for (int j = 0; j < num_length_per_ele; j++)
      {
         code.append(to_string(numberResult[i][num_length_per_ele * 2 + j]));
      }
      string time = "";
      for (int j = 0; j < num_length_per_ele; j++)
      {
         if (j == 2 || j == 4) {
            time.append(":");
         }
         time.append(to_string(numberResult[i][num_length_per_ele * 3 + j]));
      }
      string price = "";
      for (int j = 0; j < num_length_per_ele; j++)
      {
         if (j == 4) {
            price.append(".");
         }
         price.append(to_string(numberResult[i][num_length_per_ele * 4 + j]));
      }
      string percent = "";
      for (int j = 0; j < num_length_per_ele; j++)
      {
         if (j == 4) {
            percent.append(".");
         }
         percent.append(to_string(numberResult[i][num_length_per_ele * 5 + j]));
      }
      /*
      if (percent == "0000.00") {
         int sx = splitResult[(ele_count_per_line * i + 4) * 4 + 0];
         int sy = splitResult[(ele_count_per_line * i + 4) * 4 + 1];
         int ex = splitResult[(ele_count_per_line * i + 4) * 4 + 2];
         int ey = splitResult[(ele_count_per_line * i + 4) * 4 + 3];
         string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
         path.append(to_string(i)).append("_").append(".jpg");
         cv::imwrite(path, cv::Mat(grayImg, cv::Rect(sx, sy, ex - sx + 1, ey - sy + 1)));
      }
      */
      limitUpData.index = i;
      limitUpData.code = code;
      limitUpData.time = time;
      limitUpData.price = price;
      limitUpData.limitUpPercent = percent;
      limitUpData.zyltMoney = money;
      limitUpData.volume = volume;
      if (limitUpData.code != "000000" && limitUpData.limitUpPercent != "0000.00") {
         dataList.push_back(limitUpData);
      }
      else {
         cout <<"出错"<< endl;
      }
      free(numberResult[i]);
   }
   free(numberResult);
   if (dataList.size() > 0)
   {
      int* unitData = (int*)malloc(sizeof(int) * 4 * dataList.size() * 2 );
      //识别金额单位
      int index = 0;
      for (list<FirstLimitUpCodeData>::iterator ele = dataList.begin(); ele != dataList.end(); ele++) {
         unitData[index * 4 * 2 + 0] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 0];
         unitData[index * 4 * 2 + 1] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 1];
         unitData[index * 4 * 2 + 2] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 2];
         unitData[index * 4 * 2 + 3] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 3];
         unitData[index * 4 * 2 + 4] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 0];
         unitData[index * 4 * 2 + 5] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 1];
         unitData[index * 4 * 2 + 6] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 2];
         unitData[index * 4 * 2 + 7] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 3];
         index++;
      }
      int* unitResult = (int*)malloc(sizeof(int) * dataList.size() * 2);
      openCLExcuter->recognitionPlateMoneyUnit(grayImg.data, grayImg.cols, grayImg.rows, unitData, 2, dataList.size(), unitResult);
      index = 0;
      for (list<FirstLimitUpCodeData>::iterator ele = dataList.begin(); ele != dataList.end(); ele++) {
         switch (unitResult[index*2])
         {
         case 0:
            (*ele).zyltMoneyUnit = MONEY_UNIT_Y;
            break;
         case 1:
            (*ele).zyltMoneyUnit = MONEY_UNIT_W;
            break;
         default:
            break;
         }
         switch (unitResult[index * 2 + 1])
         {
         case 0:
            (*ele).volumeUnit = MONEY_UNIT_Y;
            break;
         case 1:
            (*ele).volumeUnit = MONEY_UNIT_W;
            break;
         case 2:
            (*ele).volumeUnit = MONEY_UNIT_NO;
            (*ele).volume = to_string((int)(stof((*ele).volume) * 100));
            break;
         default:
            break;
         }
         index++;
      }
      free(unitData);
      free(unitResult);
   }
   free(rowIndex);
   free(splitResult);
   free(zeroData);
   free(templateNums);
   grayImg.release();
   return dataList;
}
LimitUpFinalData LimitUpCapture::captureLimitUpCodes() {
   cout << "开始运行" << endl;
   HWND hwnd = getWindow();
   cout << "同花顺句柄:"<< hwnd << endl;
   RECT wrect;
   GetWindowRect(win, &wrect);
   list<LimitUpData> flist;
   set<string> codesSet;
   string codestr = "";
   RECT menuRect;
   GetWindowRect(menuWin, &menuRect);
   list<cv::Point>::iterator ele;
   for (ele = pointList.begin();ele != pointList.end();ele++) {
   LimitUpFinalData finalDatas;
   list<LimitUpData> limitUpList;
   list<FirstLimitUpCodeData> firstLimitUpList;
   for (int n = 0; n < 2;n++) {
      set<string> codesSet;
      if (kill) {
         break;
      }
      //暂停 暂时注释掉
      //while (pause) {
      //   cout <<"涨停识别暂停"<< endl;
      //   Sleep(100);
      //}
      int x = (*ele).x;//+ menuRect.left;
      int y = (*ele).y;//+ menuRect.top;
      int x = 0;
      int y = 0;
      if (n == 0) {
         x =   limitUpPoint.x;
         y = limitUpPoint.y;
      }
      else {
         x = firstCodePoint.x;
         y = firstCodePoint.y;
      }
      printf("x:%d y:%d\n", x, y);
       PostMessage(menuWin, WM_LBUTTONDOWN, 0, MAKELONG(x, y));
      Sleep(10);
      PostMessage(menuWin, WM_LBUTTONUP, 0, MAKELONG(x, y));
      Sleep(50);
      
      for (int i = 0;i < 2;i++)
      for (int i = 0;i < 3;i++)
      {
         if (kill) {
            break;
@@ -431,29 +707,46 @@
         PostMessage(win, WM_MOUSEWHEEL, 0, MAKEWORD(x, y));
         Sleep(200);
         cv::Mat oimg = CaptureUtil::capture(win);
         try {
            list<LimitUpData> codes = captureLimitUpCodes(oimg);
            for (list<LimitUpData>::iterator e = codes.begin();e != codes.end();e++) {
               string code = (*e).code;
               if (codesSet.count(code) == 0) {
                  codesSet.insert(code);
                  flist.push_back(*e);
         if (n == 0)
         {
            try {
               list<LimitUpData> codes = captureLimitUpCodes(oimg);
               for (list<LimitUpData>::iterator e = codes.begin(); e != codes.end(); e++) {
                  string code = (*e).code;
                  if (codesSet.count(code) == 0) {
                     codesSet.insert(code);
                     limitUpList.push_back(*e);
                  }
               }
               codes.clear();
            }
            codes.clear();
            catch (string e) {
               cout << e << endl;
            }
         }
         catch (string e) {
            cout << e << endl;
         }
         else {
            try {
               list<FirstLimitUpCodeData> codes = captureLimitUpFirstCodes(oimg);
               for (list<FirstLimitUpCodeData>::iterator e = codes.begin(); e != codes.end(); e++) {
                  string code = (*e).code;
                  if (codesSet.count(code) == 0) {
                     codesSet.insert(code);
                     firstLimitUpList.push_back(*e);
                  }
               }
               codes.clear();
            }
            catch (string e) {
               cout << e << endl;
            }
         
         }
         Sleep(50);
      }
   }
   return flist;
   finalDatas.limitUpDatas = limitUpList;
   finalDatas.firstLimitUpDatas = firstLimitUpList;
   return finalDatas;
}
//全部开始