#include "TradeSuccessCapture.h" #include #include "Win32Util.h" OpenCLExcuter* BuySuccessCapture::openCLExcuter; bool BuySuccessCapture::inited; HWND BuySuccessCapture::win; RecognitionManager* BuySuccessCapture::recognitionManager; //ÊÇ·ñÕýÔÚÖ´ÐÐ bool BuySuccessCapture::running; CallbackFun_Trade_Success BuySuccessCapture::data_callback; void* BuySuccessCapture::context; void BuySuccessCapture::_run() { while (true) { //1sÒ»´Î if (running && inited) { clock_t start = clock(); list datas = captureTradeSuccessInfo(); cout << "ºÄʱ:" << clock() - start << " ÊýÁ¿£º" << datas.size() << endl; data_callback(datas, context); datas.clear(); Sleep(2000); } } } cv::Mat BuySuccessCapture::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 BuySuccessCapture::init(CallbackFun_Trade_Success callback, void* contex) { data_callback = callback; context = contex; running = false; recognitionManager = new RecognitionManager(); openCLExcuter = new OpenCLExcuter(); openCLExcuter->init(); thread rt(&(BuySuccessCapture::_run)); rt.detach(); inited = true; try { refreshHWND(); } catch (...) { } } void BuySuccessCapture::refreshHWND() { HWND hwnd = THSActionUtil::getTradeWindow(); if (hwnd <= 0) throw string("ͬ»¨Ë³×¨ÒµÏµ¥Ò³ÃæÎ´´ò¿ª"); HWND content = GetDlgItem(hwnd, 0x00002EE6); if (content <= 0) throw string("δ»ñÈ¡µ½ÄÚÈÝ´°¿Ú¾ä±ú"); win = content; } list BuySuccessCapture::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; } } } //ȥͷȥβ 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_CODE,NUM_TYPE_TIME,NUM_TYPE_CODE,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 date = ""; for (int j = length_per_num - 8;j < length_per_num;j++) { date.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 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 * 2 + j])); } //ÊýÁ¿ string num = ""; for (int j = 0;j < length_per_num;j++) { num.append(to_string(numberResult[i][length_per_num * 3 + j])); } num = to_string(stoi(num)); //½ð¶î string money = ""; for (int j = 0;j < length_per_num;j++) { if (j == length_per_num - 2) { 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); 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.date = date; 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(numberResult); free(rowIndex); free(splitResult); free(zeroData); free(templateNums); free(grayImg.data); grayImg.release(); return dataList; } list BuySuccessCapture::captureTradeSuccessInfo() { cv::Mat oimg = CaptureUtil::capture(win); if (oimg.cols < 10 || oimg.rows < 10) { throw string("½ØÍ¼³ö´í"); } list codes = captureTradeSuccessInfo(oimg); return codes; } bool BuySuccessCapture::isInited() { return inited; } bool BuySuccessCapture::isRunning() { return running; } //È«²¿¿ªÊ¼ void BuySuccessCapture::start() { running = true; } //È«²¿½áÊø void BuySuccessCapture::stop() { running = false; }