From eda1a611bc4afcf1c36a6c728f432aec1f688e1b Mon Sep 17 00:00:00 2001 From: admin <weikou2014> Date: 星期一, 27 六月 2022 19:13:36 +0800 Subject: [PATCH] 'GP代码识别' --- ConsoleApplication/THSActionUtil.cpp | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 221 insertions(+), 17 deletions(-) diff --git a/ConsoleApplication/THSActionUtil.cpp b/ConsoleApplication/THSActionUtil.cpp index 27429a5..3506f84 100644 --- a/ConsoleApplication/THSActionUtil.cpp +++ b/ConsoleApplication/THSActionUtil.cpp @@ -1,18 +1,193 @@ #include "THSActionUtil.h" #include "ImgDivider.h" +#include "Win32Util.h" + + +//获取副屏 +HWND getSecondWindow() { + list<HWND> wlist = Win32Util::searchWindow("同花顺("); + list<HWND>::iterator ele; + for (ele = wlist.begin();ele != wlist.end();ele++) { + HWND hwnd = *ele; + string str = Win32Util::getWindowName(hwnd); + if (str.find("同花顺") != string::npos && str.find("副屏") != string::npos) + { + return hwnd; + } + } + return 0; +} + void THSActionUtil::openSecondScreen() { + list<HWND> wlist = Win32Util::searchWindow("同花顺("); + + bool open = false; + HWND mainPage = 0; + + list<HWND>::iterator ele; + for (ele = wlist.begin();ele != wlist.end();ele++) { + HWND hwnd = *ele; + string str = Win32Util::getWindowName(hwnd); + if (str.find("同花顺") != string::npos && str.find("副屏") != string::npos) + { + cout << str << endl; + SetForegroundWindow(hwnd); + SetFocus(hwnd); + open = true; + break; + } + + if (str.find("同花顺") != string::npos && str.find("热门股") != string::npos) { + cout << hwnd << endl; + //获取尺寸 + RECT rc; + GetWindowRect(hwnd, &rc); + if (rc.right - rc.left > 200 && rc.bottom - rc.top > 200) { + mainPage = hwnd; + } + } + + } + + if (!open) { + Win32Util::focus(mainPage); + //查找主窗口的工具栏 + HWND tool = FindWindowExA(mainPage, NULL, "AfxControlBar100s", NULL); + + //获取第一个子窗口 + tool = FindWindowExA(tool, NULL, NULL, NULL); + cout << "操作栏:" << tool << endl; + //打开副屏,多窗按钮ID为:0x00007AF9 + HWND btn = GetDlgItem(tool, 0x00007AF9); + RECT rc; + GetWindowRect(btn, &rc); + //获取需要点击的位置 + int x = rc.left + (rc.right - rc.left) / 3; + int y = rc.top + (rc.bottom - rc.top) / 3; + //点击多窗 + Win32Util::click(x, y); + //点击副屏1 + Win32Util::click(x + 10, y + 21 * 7 + 5, 500); + } } //添加股票 -void THSActionUtil::addGP(std::string quickCode, std::string code) { +void THSActionUtil::setGP(std::string quickCode, list<std::string> codeList) { + //打开副屏 + HWND sw = getSecondWindow(); + if (sw <= 0) + { + openSecondScreen(); + Sleep(2000); + sw = getSecondWindow(); + } + if (sw <= 0) { + throw("未打开副屏"); + } + + //打开板块 + Win32Util::keyboardNum(quickCode); + Win32Util::keyboard(VK_RETURN, 200); + Sleep(1000); + //设置板块中的股票 + + //获取板块内容句柄 + + HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL); + cv::Mat img = CaptureUtil::capture(content); + if (img.cols <= 0 || img.rows <= 0) { + throw("板块截屏内容为空"); + } + + std::list<GPCodeArea> areaList = recognitionGPArea(img); + + std::list<string> addList; + std::list<GPCodeArea> delList; + std::list<GPCodeArea> resultList = recognitionNum(img, areaList); + + for (std::list<GPCodeArea>::reverse_iterator ele= resultList.rbegin();ele != resultList.rend();++ele) { + + bool contains = false; + std::list<string>::iterator e; + for (e = codeList.begin();e != codeList.end();e++) { + if (*e == (*ele).code) { + contains = true; + break; + } + } + + if (!contains) { + delList.push_back(*ele); + } + else + { + codeList.remove((*ele).code); + } + + } + //-----先删除需要删除的 + //获取内容板块坐标 + RECT rect; + GetWindowRect(content, &rect); + + + for (std::list<GPCodeArea>::iterator ele = delList.begin();ele != delList.end();++ele) { + int x = rect.left; + int y = rect.top; + x += (*ele).startx+5; + y += (*ele).starty+5; + //选中删除 + Win32Util::click(x,y,50); + Win32Util::keyboard(VK_DELETE, 50); + } + + //----增加 + //截图,识别出增加按钮位置,点击增加,输入内容 } -//删除股票 -void THSActionUtil::deleteGP(std::string quickCode, std::string code) { + +void add(string code) { + //打开副屏 + HWND sw = getSecondWindow(); + if (sw <= 0) + { + openSecondScreen(); + Sleep(2000); + sw = getSecondWindow(); + } + if (sw <= 0) { + throw("未打开副屏"); + } + + HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL); + cv::Mat img = CaptureUtil::capture(content); + if (img.cols <= 0 || img.rows <= 0) { + throw("板块截屏内容为空"); + } + std::list<GPCodeArea> areaList = recognitionGPArea(img); + for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();++ele) { + GPCodeArea codeArea = *ele; + if (codeArea.type == IMG_TYPE_ADD) { + RECT rc; + GetWindowRect(HWND(0x00161728), &rc); + int y = rc.top + codeArea.starty + (codeArea.endy - codeArea.starty) / 2; + int x = rc.left + codeArea.startx + (codeArea.endx - codeArea.startx) / 2; + Win32Util::click(x, y, 50); + //输入股票代码 + Win32Util::keyboardNum(code,1000); + Win32Util::keyboard(VK_RETURN, 1500); + //关闭按钮 + Sleep(100); + HWND close = FindWindowA(0, "添加股票"); + SendMessage(close, WM_CLOSE, 0, 0); + break; + } + } } + //识别股票代码 -std::list<GPCodeArea> THSActionUtil::recognitionGPCode(cv::Mat img) { +std::list<GPCodeArea> THSActionUtil::recognitionGPArea(cv::Mat img) { //获取title分隔线 int rows = img.rows; int cols = img.cols; @@ -70,7 +245,7 @@ std::list<int*> dataItemList; for (int i = contentStartRow + 30;i < rows;i++) { - bool empty = ImgDivider::isRowEmpty(img, i, startC, startC+50, 1, 64)&& ImgDivider::isRowEmpty(img, i, startC +(endC-startC)/2-40, startC + (endC - startC) / 2 + 40, 1, 64); + bool empty = ImgDivider::isRowEmpty(img, i, startC, startC + 50, 1, 64) && ImgDivider::isRowEmpty(img, i, startC + (endC - startC) / 2 - 40, startC + (endC - startC) / 2 + 40, 1, 64); if (empty) { if (emptyStartRow < 0) { emptyStartRow = i; @@ -80,7 +255,7 @@ emptyEndRow = i; } - if (emptyEndRow - emptyStartRow > 50&& dataItemList.size()>0) { + if (emptyEndRow - emptyStartRow > 50 && dataItemList.size() > 0) { //没有数据了 break; } @@ -133,7 +308,7 @@ LogUtil::debug("%d %d %d %d\n", startRow, startCol, endRow, endCol); //保存行数据 - if (true) { + if (false) { std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\split\\"; path.append(std::to_string(index)).append(".jpg"); imwrite(path, cv::Mat(img, cv::Rect(startCol, startRow, endCol - startCol + 1, endRow - startRow + 1))); @@ -160,14 +335,14 @@ //3个及以上的空白数据才分列 if (emptyEnd - emptyStart >= 5 && dataEnd - dataStart > 0) { int* dd = (int*)malloc(sizeof(int) * 4); - *dd = dataStart ; + *dd = dataStart; *(dd + 1) = startRow; - *(dd + 2) = dataEnd ; + *(dd + 2) = dataEnd; *(dd + 3) = endRow; rowDataList.push_back(dd); dataEnd = -1; dataStart = -1; - if (rowDataList.size() >= 2){ + if (rowDataList.size() >= 2) { break; } } @@ -188,9 +363,9 @@ //后面的数据没有足够的空白分隔 if (dataEnd - dataStart > 0) { int* dd = (int*)malloc(sizeof(int) * 4); - *dd = dataStart ; + *dd = dataStart; *(dd + 1) = startRow; - *(dd + 2) = dataEnd ; + *(dd + 2) = dataEnd; *(dd + 3) = endRow; rowDataList.push_back(dd); } @@ -198,15 +373,15 @@ int rowDataSize = rowDataList.size(); if (rowDataSize == 2) { - std::list<int*>::iterator ele= rowDataList.begin(); + std::list<int*>::iterator ele = rowDataList.begin(); std::advance(ele, 1); GPCodeArea area = GPCodeArea(); area.type = IMG_TYPE_GP; area.startx = **ele; - area.starty = *(*ele+1); - area.endx = *(*ele+2); - area.endy = *(*ele+3); + area.starty = *(*ele + 1); + area.endx = *(*ele + 2); + area.endy = *(*ele + 3); resultList.push_back(area); } else { @@ -245,9 +420,38 @@ cc++; } } - + } return resultList; +} + +std::list<GPCodeArea> THSActionUtil::recognitionNum(cv::Mat img, std::list<GPCodeArea> areaList) { + + if (!recognitionManager) { + recognitionManager = new RecognitionManager(); + } + //识别数字 + std::list<GPCodeArea> codeList; + + std::list<GPCodeArea>::iterator ele; + + for (ele = areaList.begin();ele != areaList.end();ele++) { + GPCodeArea codeArea = *ele; + if (codeArea.type == IMG_TYPE_GP) { + cv::Mat nums = cv::Mat(img, cv::Rect(codeArea.startx, codeArea.starty, codeArea.endx - codeArea.startx + 1, codeArea.endy - codeArea.starty + 1)); + std::list<cv::Mat> list2 = ImgUtil::splitNum(nums); + std::list<uchar> resultList = recognitionManager->recognitionGPCode(list2); + std::list<uchar>::iterator ele1; + string code = ""; + for (ele1 = resultList.begin();ele1 != resultList.end();++ele1) { + code.append(to_string(*ele1)); + } + codeArea.code = code; + codeList.push_back(codeArea); + } + } + + return codeList; } \ No newline at end of file -- Gitblit v1.8.0