From 8b06b1cbf112d55307ea8a6efe711db4e7506d89 Mon Sep 17 00:00:00 2001 From: admin <weikou2014> Date: 星期二, 07 三月 2023 10:13:47 +0800 Subject: [PATCH] 'GPU内核方法优化' --- ConsoleApplication/LimitUpCapture.cpp | 433 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 363 insertions(+), 70 deletions(-) diff --git a/ConsoleApplication/LimitUpCapture.cpp b/ConsoleApplication/LimitUpCapture.cpp index 57aba35..16ea52a 100644 --- a/ConsoleApplication/LimitUpCapture.cpp +++ b/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; } //全部开始 -- Gitblit v1.8.0