#include "TradeListCapture.h" #include #include "Win32Util.h" #include "TaskChecker.h" OpenCLExcuter* TradeListCapture::openCLExcuter; bool TradeListCapture::inited; bool TradeListCapture::kill_d; bool TradeListCapture::kill_s; HWND TradeListCapture::trade_delegate_win; HWND TradeListCapture::trade_success_win; RecognitionManager* TradeListCapture::recognitionManager; //ÊÇ·ñÕýÔÚÖ´ÐÐ bool TradeListCapture::running_s; bool TradeListCapture::running_d; CallbackFun_Trade_Success TradeListCapture::data_callback_success; CallbackFun_Trade_Delegate TradeListCapture::data_callback_delegate; void* TradeListCapture::context; void TradeListCapture::_run_s() { while (true) { if (kill_s) break; TaskChecker::clientLiveTime.tradeSuccess = clock(); if (running_s && inited) { clock_t start = clock(); try { list datas = captureTradeSuccessInfo(); cout << "ºÄʱ:" << clock() - start << " ÊýÁ¿£º" << datas.size() << endl; data_callback_success(datas, context); datas.clear(); } catch (...) { } Sleep(10); } else { Sleep(2000); } } } void TradeListCapture::_run_d() { while (true) { if (kill_d) break; //1sÒ»´Î if (running_d && inited) { clock_t start = clock(); try { list datas = captureTradeDelegateInfo(); string money = getAvaiableMoney(); cout << "ºÄʱ:" << clock() - start << " ÊýÁ¿£º" << datas.size() << endl; data_callback_delegate(datas, money, context); datas.clear(); } catch (...) { } Sleep(5); } else { Sleep(2000); } } } cv::Mat TradeListCapture::grayImgs(cv::Mat oimg) { cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);//ImgUtil::grayImage(oimg); uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols); if (oimg.channels() == 3) { openCLExcuter->rgb2ThresholdInvert(oimg.data, oimg.cols, oimg.rows, imgData); } else { openCLExcuter->rgba2ThresholdInvert(oimg.data, oimg.cols, oimg.rows, imgData); } grayImg.data = imgData; return grayImg; } void TradeListCapture::init(CallbackFun_Trade_Success callback_s, CallbackFun_Trade_Delegate callback_d, void* contex) { data_callback_success = callback_s; data_callback_delegate = callback_d; context = contex; running_s = false; running_d = false; recognitionManager = new RecognitionManager(); openCLExcuter = new OpenCLExcuter(); openCLExcuter->init(); thread rt(&(TradeListCapture::_run_s)); rt.detach(); thread rt1(&(TradeListCapture::_run_d)); rt1.detach(); inited = true; try { refreshTradeSuccessHWND(); } catch (...) { } try { refreshTradeDelegateHWND(); } catch (...) { } } void TradeListCapture::reCreateTradeSuccessRunning() { kill_s = TRUE; Sleep(3000); kill_s = FALSE; thread rt(&(TradeListCapture::_run_s)); rt.detach(); } void TradeListCapture::reCreateTradeDelegateRunning() { kill_d = TRUE; Sleep(3000); kill_d = FALSE; thread rt(&(TradeListCapture::_run_d)); rt.detach(); } void TradeListCapture::refreshTradeDelegateHWND() { HWND hwnd = THSActionUtil::getTradeDelegateWindow(); if (hwnd <= 0) throw string("ͬ»¨Ë³×¨ÒµÏµ¥Ò³ÃæÎ´´ò¿ª"); HWND content = GetDlgItem(hwnd, 0x00002EE6); if (content <= 0) throw string("δ»ñÈ¡µ½ÄÚÈÝ´°¿Ú¾ä±ú"); trade_delegate_win = content; } void TradeListCapture::refreshTradeSuccessHWND() { HWND hwnd = THSActionUtil::getTradeSuccessWindow(); if (hwnd <= 0) throw string("ͬ»¨Ë³ÍøÉÏ¹ÉÆ±½»Ò×ϵͳδ´ò¿ª"); hwnd = FindWindowEx(hwnd, NULL, TEXT("AfxMDIFrame140s"), NULL); HWND temp = FindWindowEx(hwnd, NULL, TEXT("#32770"), NULL); HWND first = 0; for (int i = 0;i < 20;i++) { if (IsWindowVisible(temp)) { RECT rect; GetWindowRect(temp, &rect); if (rect.right - rect.left > 100 && rect.bottom - rect.top > 100) { first = temp; break; } } temp = FindWindowEx(hwnd, temp, TEXT("#32770"), NULL); } if (first <= 0) { throw string("ͬ»¨Ë³ÍøÉÏ¹ÉÆ±½»Ò×ϵͳ-µ±Èճɽ»´°¿ÚδÕÒµ½"); } temp = FindWindowEx(first, NULL, NULL, TEXT("HexinScrollWnd")); if (temp <= 0) { throw string("ͬ»¨Ë³ÍøÉÏ¹ÉÆ±½»Ò×ϵͳ-µ±Èճɽ»´°¿Ú-ÄÚÈÝ´°¿ÚδÕÒµ½"); } trade_success_win = temp; } //˳Ðò ´úÂë-³É½»Ê±¼ä-³É½»ÊýÁ¿-³É½»¾ù¼Û-³É½»½ð¶î-ºÏͬ±àºÅ-²Ù×÷ list TradeListCapture::captureTradeSuccessInfo(cv::Mat oimg) { cv::Mat grayImg = grayImgs(oimg); list dataList; //·Ö¸ôÔªËØ int empty_start = -1; int empty_end = -1; int data_start = -1; int data_end = -1; list rowData; for (int r = 0;r < grayImg.rows;r++) { if (ImgDivider::isRowEmpty(grayImg, r, 0, 50)) { if (empty_start < 0) { empty_start = r; empty_end = r; } else { empty_end = r; } if (data_start > -1 && data_end > -1 && data_end - data_start > 5) { printf("%d-%d\n", data_start, data_end); int* d = (int*)malloc(sizeof(int) * 2); d[0] = data_start; d[1] = data_end; rowData.push_back(d); data_start = -1; data_end = -1; } } else { empty_start = -1; empty_end = -1; if (data_start < 0) { data_start = r; data_end = r; } else { data_end = r; } } } if (rowData.size() < 2) { free(grayImg.data); grayImg.release(); for (list::iterator ele = rowData.begin();ele != rowData.end();ele++) { free(*ele); } return dataList; } //ȥͷȥβ list::iterator start = rowData.begin(); list::iterator end = rowData.end(); free(*start); rowData.erase(start); std::advance(end, -1); free(*end); rowData.erase(end); int* rowIndex = (int*)malloc(sizeof(int) * rowData.size() * 4); int index = 0; for (list::iterator ele = rowData.begin();ele != rowData.end();ele++) { rowIndex[index * 4 + 0] = 0; rowIndex[index * 4 + 1] = (*ele)[0]; rowIndex[index * 4 + 2] = grayImg.cols - 1; rowIndex[index * 4 + 3] = (*ele)[1]; free(*ele); index++; } int ele_count_per_line = 7; int length_per_num = 10; int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size()); openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 6, splitResult); if (false) { //±£´æ·Ö¸ô½á¹û for (int i = 0;i < rowData.size();i++) { int start = i * ele_count_per_line * 4; for (int j = 0;j < ele_count_per_line;j++) { int startx = splitResult[start]; int starty = splitResult[start + 1]; int endx = splitResult[start + 2]; int endy = splitResult[start + 3]; start += 4; string path = "C:\\Users\\Administrator\\Desktop\\ocr\\trade\\"; path.append(to_string(i)).append("_").append(to_string(j)).append(".jpg"); cv::imwrite(path, cv::Mat(grayImg, cv::Rect(startx, starty, endx - startx + 1, endy - starty + 1))); } } } //·Ö¸îÊý×Ö 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++) { zeroData[r * _NUMBER_L2_WIDTH + c] = ImgUtil::NUMS_LEVEL2[0].data.ptr(r)[c]; } } int line_number_count = ele_count_per_line * length_per_num; unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count); UcharDataInfo typesData = UcharDataInfo(); unsigned char types[] = { NUM_TYPE_CODE,NUM_TYPE_TIME,NUM_TYPE_CODE,NUM_TYPE_PRICE,NUM_TYPE_PRICE,NUM_TYPE_CODE }; typesData.length = ele_count_per_line; typesData.data = types; openCLExcuter->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num); //ʶ±ðÊý×Ö uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count); openCLExcuter->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums); uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count); for (int i = 0;i < rowData.size();i++) { TradeSuccessData industryData = TradeSuccessData(); //´úÂë string code = ""; for (int j = length_per_num - 6;j < length_per_num;j++) { code.append(to_string(numberResult[i][length_per_num * 0 + j])); } //ʱ¼ä string time = ""; for (int j = length_per_num - 6;j < length_per_num;j++) { if (j - (length_per_num - 6) == 2 || j - (length_per_num - 6) == 4) time.append(":"); time.append(to_string(numberResult[i][length_per_num * 1 + j])); } //ÊýÁ¿ string num = ""; for (int j = 0;j < length_per_num;j++) { num.append(to_string(numberResult[i][length_per_num * 2 + j])); } num = to_string(stoi(num)); //¼Û¸ñ string price = ""; for (int j = 0;j < length_per_num;j++) { if (j == length_per_num - 3) { price.append("."); } price.append(to_string(numberResult[i][length_per_num * 3 + j])); } char* priceCode; priceCode = new char[20]; sprintf_s(priceCode, price.length(), "%.2lf", stod(price)); std::string _str(priceCode); delete[] priceCode; price = _str; //½ð¶î string money = ""; for (int j = 0;j < length_per_num;j++) { if (j == length_per_num - 3) { money.append("."); } money.append(to_string(numberResult[i][length_per_num * 4 + j])); } char* chCode; chCode = new char[20]; sprintf_s(chCode, money.length(), "%.2lf", stod(money)); std::string str(chCode); delete[] chCode; money = str; //ºÏͬ±àºÅ string trade_num = ""; for (int j = 0;j < length_per_num;j++) { trade_num.append(to_string(numberResult[i][length_per_num * 5 + j])); } //ÂòÈëÂô³ö int start = i * 4 * ele_count_per_line + 6 * 4; int startx = splitResult[start]; int starty = splitResult[start + 1]; int endx = splitResult[start + 2]; int endy = splitResult[start + 3]; int count = 0; for (int r = starty;r <= endy;r++) { for (int c = startx;c <= endx;c++) { uchar v = grayImg.ptr(r)[c]; if (v >= _IMG_BINARY_THRESHOLD) { count++; } } } if (count > 50) { //Âô³ö industryData.type = TRADE_TYPE_SELL; } else { //ÂòÈë industryData.type = TRADE_TYPE_BUY; } industryData.index = i; industryData.price = price; industryData.code = code; industryData.time = time; industryData.num = num; industryData.money = money; industryData.trade_num = trade_num; dataList.push_back(industryData); free(numberResult[i]); } free(totalNumberData); free(numberResult); free(rowIndex); free(splitResult); free(zeroData); free(templateNums); free(grayImg.data); grayImg.release(); return dataList; } list TradeListCapture::captureTradeSuccessInfo() { cv::Mat oimg = CaptureUtil::capture(trade_success_win); if (oimg.cols < 10 || oimg.rows < 10) { throw string("½ØÍ¼³ö´í"); } list codes = captureTradeSuccessInfo(oimg); return codes; } //˳Ðò£ºÎ¯ÍÐʱ¼ä-´úÂë-ίÍÐÊýÁ¿-ίÍм۸ñ-³É½»¾ù¼Û-³ÉЧÊýÁ¿-²Ù×÷ list TradeListCapture::captureTradeDelegateInfo(cv::Mat oimg) { cv::Mat grayImg = grayImgs(oimg); list dataList; //·Ö¸ôÔªËØ int empty_start = -1; int empty_end = -1; int data_start = -1; int data_end = -1; list rowData; for (int r = 0;r < grayImg.rows;r++) { if (ImgDivider::isRowEmpty(grayImg, r, 0, 50)) { if (empty_start < 0) { empty_start = r; empty_end = r; } else { empty_end = r; } if (data_start > -1 && data_end > -1 && data_end - data_start > 5) { printf("%d-%d\n", data_start, data_end); int* d = (int*)malloc(sizeof(int) * 2); d[0] = data_start; d[1] = data_end; rowData.push_back(d); data_start = -1; data_end = -1; } } else { empty_start = -1; empty_end = -1; if (data_start < 0) { data_start = r; data_end = r; } else { data_end = r; } } } if (rowData.size() < 2) { free(grayImg.data); grayImg.release(); for (list::iterator ele = rowData.begin();ele != rowData.end();ele++) { free(*ele); } return dataList; } //ȥͷȥβ list::iterator start = rowData.begin(); list::iterator end = rowData.end(); free(*start); rowData.erase(start); std::advance(end, -1); free(*end); rowData.erase(end); int* rowIndex = (int*)malloc(sizeof(int) * rowData.size() * 4); int index = 0; for (list::iterator ele = rowData.begin();ele != rowData.end();ele++) { rowIndex[index * 4 + 0] = 0; rowIndex[index * 4 + 1] = (*ele)[0]; rowIndex[index * 4 + 2] = grayImg.cols - 1; rowIndex[index * 4 + 3] = (*ele)[1]; free(*ele); index++; } int ele_count_per_line = 7; int length_per_num = 8; int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size()); openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 6, splitResult); if (false) { //±£´æ·Ö¸ô½á¹û for (int i = 0;i < rowData.size();i++) { int start = i * ele_count_per_line * 4; for (int j = 0;j < ele_count_per_line;j++) { int startx = splitResult[start]; int starty = splitResult[start + 1]; int endx = splitResult[start + 2]; int endy = splitResult[start + 3]; start += 4; string path = "C:\\Users\\Administrator\\Desktop\\ocr\\trade\\"; path.append(to_string(i)).append("_").append(to_string(j)).append(".jpg"); cv::imwrite(path, cv::Mat(grayImg, cv::Rect(startx, starty, endx - startx + 1, endy - starty + 1))); } } } //·Ö¸îÊý×Ö 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++) { zeroData[r * _NUMBER_L2_WIDTH + c] = ImgUtil::NUMS_LEVEL2[0].data.ptr(r)[c]; } } int line_number_count = ele_count_per_line * length_per_num; unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count); UcharDataInfo typesData = UcharDataInfo(); unsigned char types[] = { NUM_TYPE_TIME,NUM_TYPE_CODE,NUM_TYPE_CODE,NUM_TYPE_PRICE,NUM_TYPE_PRICE,NUM_TYPE_CODE, NUM_TYPE_CODE }; typesData.length = ele_count_per_line; typesData.data = types; openCLExcuter->splitL2NumNew(grayImg, IntDataInfo({ splitResult,(int)(ele_count_per_line * rowData.size()) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, length_per_num); //ʶ±ðÊý×Ö uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowData.size()) * _NUMBER_L2_WIDTH * 10 * line_number_count); openCLExcuter->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums); uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowData.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count); for (int i = 0;i < rowData.size();i++) { TradeDelegateData delegateData = TradeDelegateData(); //ʱ¼ä string time = ""; for (int j = length_per_num - 6;j < length_per_num;j++) { if (j - (length_per_num - 6) == 2 || j - (length_per_num - 6) == 4) time.append(":"); time.append(to_string(numberResult[i][length_per_num * 0 + j])); } //´úÂë string code = ""; for (int j = length_per_num - 6;j < length_per_num;j++) { code.append(to_string(numberResult[i][length_per_num * 1 + j])); } //ίÍÐÊýÁ¿ string num = ""; for (int j = 0;j < length_per_num;j++) { num.append(to_string(numberResult[i][length_per_num * 2 + j])); } num = to_string(stoi(num)); //ίÍм۸ñ string delegate_price = ""; for (int j = 0;j < length_per_num;j++) { if (length_per_num - j == 3) delegate_price.append("."); delegate_price.append(to_string(numberResult[i][length_per_num * 3 + j])); } delegate_price = to_string(stod(delegate_price)); char* chCode; chCode = new char[20]; sprintf_s(chCode, delegate_price.length(), "%.3lf", stod(delegate_price)); std::string delegate_price_str(chCode); delegate_price = delegate_price_str; //³É½»¾ù¼Û string percent_price = ""; for (int j = 0;j < length_per_num;j++) { if (length_per_num - j == 3) percent_price.append("."); percent_price.append(to_string(numberResult[i][length_per_num * 4 + j])); } chCode = new char[20]; sprintf_s(chCode, percent_price.length(), "%.3lf", stod(percent_price)); std::string percent_price_str(chCode); percent_price = percent_price_str; //³É½»ÊýÁ¿ string success_num = ""; for (int j = 0;j < length_per_num;j++) { success_num.append(to_string(numberResult[i][length_per_num * 5 + j])); } success_num = to_string(stoi(success_num)); //ÂòÈëÂô³ö int start = i * 4 * ele_count_per_line + 6 * 4; int startx = splitResult[start]; int starty = splitResult[start + 1]; int endx = splitResult[start + 2]; int endy = splitResult[start + 3]; int count = 0; for (int r = starty;r <= endy;r++) { for (int c = startx;c <= endx;c++) { uchar v = grayImg.ptr(r)[c]; if (v >= _IMG_BINARY_THRESHOLD) { count++; } } } if (count > 50) { //Âô³ö delegateData.type = TRADE_TYPE_SELL; } else { //ÂòÈë delegateData.type = TRADE_TYPE_BUY; } delegateData.index = i; delegateData.code = code; delegateData.time = time; delegateData.num = num; delegateData.price = delegate_price; delegateData.trade_price = percent_price; delegateData.trade_num = success_num; dataList.push_back(delegateData); free(numberResult[i]); } free(totalNumberData); free(numberResult); free(rowIndex); free(splitResult); free(zeroData); free(templateNums); free(grayImg.data); grayImg.release(); return dataList; } list TradeListCapture::captureTradeDelegateInfo() { cv::Mat oimg = CaptureUtil::capture(trade_delegate_win); if (oimg.cols < 10 || oimg.rows < 10) { throw string("½ØÍ¼³ö´í"); } list codes = captureTradeDelegateInfo(oimg); return codes; } string TradeListCapture::getAvaiableMoney() { HWND hwnd = THSActionUtil::getTradeDelegateWindow(); if (hwnd <= 0) { throw string("ίÍд°¿Úδ´ò¿ª"); } HWND temp = FindWindowEx(hwnd, NULL, TEXT("#32770"), NULL); HWND avaiableMoneyHWND = 0; for (int i = 0;i < 20;i++) { if (IsWindowVisible(temp)) { HWND tempW = FindWindowEx(temp, NULL, TEXT("Static"), TEXT("¿ÉÓÃ")); if (tempW > 0) { avaiableMoneyHWND = GetDlgItem(temp, 0x000007D5); break; } } temp = FindWindowEx(hwnd, temp, TEXT("#32770"), NULL); } if (avaiableMoneyHWND <= 0) { throw string("δ²éÕÒµ½¿ÉÓÃÓà¶î¿Ø¼þ"); } string text = Win32Util::getWindowName(avaiableMoneyHWND); return text; } bool TradeListCapture::isInited() { return inited; } bool TradeListCapture::isRunningTradeSuccess() { return running_s; } bool TradeListCapture::isRunningTradeDelegate() { return running_d; } void TradeListCapture::startTradeSuccess() { running_s = true; } void TradeListCapture::stopTradeSuccess() { running_s = false; } void TradeListCapture::startTradeDelegate() { running_d = true; } void TradeListCapture::stopTradeDelegate() { running_d = false; }