#include "LimitUpCapture.h" #include "THSActionUtil.h" #include #include "Win32Util.h" #include "TaskChecker.h" #include "GPUtil.h" bool LimitUpCapture::tradeTimeCapture; OpenCLExcuter* LimitUpCapture::openCLExcuter; bool LimitUpCapture::inited; //ÊÇ·ñÕýÔÚÖ´ÐÐ bool LimitUpCapture::running; bool LimitUpCapture::kill; CallbackFun_Limit_Up LimitUpCapture::data_callback; std::list LimitUpCapture::pointList; void* LimitUpCapture::context; HWND LimitUpCapture::win; HWND LimitUpCapture::menuWin; HWND getWindow() { HWND win = THSActionUtil::getThirdWindow(); if (win <= 0) { win = THSActionUtil::getSecondWindow(); } return win; } void LimitUpCapture::_run() { while (true) { if (kill) break; if (tradeTimeCapture) { if (!GPUtil::isTradeTime()) { Sleep(100); continue; } } TaskChecker::clientLiveTime.limitUp = clock(); if (running && inited) { clock_t start = clock(); try { list codes = captureLimitUpCodes(); cout << "ºÄʱ:" << clock() - start << " ÊýÁ¿£º" << codes.size() << endl; data_callback(codes, context); codes.clear(); } catch (...) { } Sleep(3000); } else { Sleep(1000); } } } bool LimitUpCapture::pause; void LimitUpCapture::init(CallbackFun_Limit_Up callback, void* contex) { data_callback = callback; context = contex; running = false; kill = false; openCLExcuter = new OpenCLExcuter(); openCLExcuter->init(); thread rt(&(LimitUpCapture::_run)); rt.detach(); inited = true; try { refreshHWND(); } catch (...) { } } void LimitUpCapture::reCreateRunning() { kill = TRUE; Sleep(4000); kill = FALSE; thread rt(&(LimitUpCapture::_run)); rt.detach(); } void LimitUpCapture::refreshHWND() { HWND hwnd = getWindow(); if (hwnd <= 0) throw string("ͬ»¨Ë³¸±ÆÁ2δ´ò¿ª"); //ÊäÈë¿ì½Ý¼ü51¶¨Î»µ½Îҵİæ¿é Win32Util::showWindow(hwnd); Win32Util::focus(hwnd); Win32Util::keyboardNum("51", 200); Win32Util::keyboard(VK_RETURN, 1000); Sleep(500); HWND content = FindWindowExA(hwnd, NULL, "AfxFrameOrView100s", NULL); if (content <= 0) throw string("δ»ñÈ¡µ½ÄÚÈÝ´°¿Ú¾ä±ú"); win = content; HWND child = 0; RECT tempRect; int maxCount = 1; do { maxCount++; child = FindWindowExA(content, child, "AfxWnd100s", NULL); 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); } else { break; } } temp= FindWindowExA(temp, NULL, "block_list_page", NULL); menuWin = temp; if (menuWin <= 0) throw string("δ»ñÈ¡µ½ÄÚÈÝ´°¿ÚµÄ²Ëµ¥¾ä±ú"); //²éÕҲ˵¥µÄλÖà cv::Mat grayImg = ImgUtil::grayImage(CaptureUtil::capture(menuWin)); int full_start = -1; int full_end = -1; int start_row = -1; int end_row = -1; int count = 0; pointList.clear(); for (int r = grayImg.rows - 1;r>=0;r --) { if (ImgDivider::isRowFull(grayImg,r,0, grayImg.cols-1,2,33,48)) { if (full_start < 0) { full_start = r; full_end = r; } else { full_end = r; } if (start_row > 0 && end_row > 0 && (start_row - end_row) > 5) { count++; printf("%d-%d\n", start_row, end_row); full_start = r; full_end = r; string path = "C:\\Users\\Administrator\\Desktop\\ocr\\menu\\"; path.append("menu_").append(to_string(count)).append(".jpg"); //cv::imwrite(path, cv::Mat(grayImg,cv::Rect(0,end_row,grayImg.cols,start_row-end_row))); pointList.push_back(cv::Point( ( 0 + grayImg.cols)/2, (start_row + end_row)/2)); if (pointList.size() >= 2) { break; } start_row = -1; end_row = -1; } } else { if (full_start >= 0) { if (start_row < 0) { start_row = r; end_row = r; } else { end_row = r; } } } } //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\menu.jpg", ); } bool LimitUpCapture::isRunning() { return running; } list LimitUpCapture::captureLimitUpCodes(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); try { if (oimg.channels() == 3) { openCLExcuter->rgb2Gray(oimg, imgData); } else { openCLExcuter->rgba2Gray(oimg, imgData); } } catch (...) { //±£´æÔ­Ê¼Í¼Æ¬ //string path = "D:\\imgs\\img.png"; //cv::imwrite(path, oimg); oimg.release(); free(imgData); imgData = NULL; throw string("»Ò¶È³ö´í"); } grayImg.data = imgData; list rowData; try { rowData = THSActionUtil::splitPlateRowArea(grayImg); } catch (string st) { free(imgData); throw st; } //ÿÐеÄÔªËØ¸öÊý int ele_count_per_line = 5; 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::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,5,splitResult); //²âÊÔ set 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 < 40) { //ÔëµãÊý¾Ý 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(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_CODE,NUM_TYPE_TIME, NUM_TYPE_PRICE,NUM_TYPE_PERCENT}; UcharDataInfo typesData = UcharDataInfo(); typesData.length = 5; 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 dataList; for (int i = 0;i < rowData.size();i++) { if (excudeIndexs.count(i) > 0) { continue; } LimitUpData limitUpData = LimitUpData(); 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 code = ""; for (int j = 0;j < num_length_per_ele;j++) { code.append(to_string(numberResult[i][num_length_per_ele * 1+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*2 + 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 * 3 + 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 * 4 + 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.limitMoney = money; if (limitUpData.code != "000000" && limitUpData.limitUpPercent != "0000.00") { dataList.push_back(limitUpData); } free(numberResult[i]); } free(numberResult); if (dataList.size() > 0) { int* unitData = (int*)malloc(sizeof(int) * 4 * dataList.size()); //ʶ±ð½ð¶îµ¥Î» int index = 0; for (list::iterator ele = dataList.begin();ele != dataList.end();ele++) { unitData[index * 4 + 0] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 0]; unitData[index * 4 + 1] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 1]; unitData[index * 4 + 2] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 2]; unitData[index * 4 + 3] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 3]; index++; } int* unitResult = (int*)malloc(sizeof(int) * dataList.size()); openCLExcuter->recognitionPlateMoneyUnit(grayImg.data, grayImg.cols, grayImg.rows, unitData, 1, dataList.size(), unitResult); index = 0; for (list::iterator ele = dataList.begin();ele != dataList.end();ele++) { switch (unitResult[index]) { case 0: (*ele).limitMoneyUnit = MONEY_UNIT_Y; break; case 1: (*ele).limitMoneyUnit = MONEY_UNIT_W; break; default: break; } index++; } free(unitData); free(unitResult); } free(rowIndex); free(splitResult); free(zeroData); free(templateNums); free(imgData); grayImg.release(); return dataList; } list LimitUpCapture::captureLimitUpCodes() { cout << "¿ªÊ¼ÔËÐÐ" << endl; HWND hwnd = getWindow(); cout << "ͬ»¨Ë³¾ä±ú£º"<< hwnd << endl; RECT wrect; GetWindowRect(win, &wrect); list flist; set codesSet; string codestr = ""; RECT menuRect; GetWindowRect(menuWin, &menuRect); list::iterator ele; for (ele = pointList.begin();ele != pointList.end();ele++) { if (kill) { break; } //ÔÝÍ£ ÔÝʱעÊ͵ô //while (pause) { // cout <<"ÕÇͣʶ±ðÔÝÍ£"<< endl; // Sleep(100); //} int x = (*ele).x;//+ menuRect.left; int y = (*ele).y;//+ menuRect.top; 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++) { if (kill) { break; } int x = wrect.right - 50; int y = wrect.top + 50; PostMessage(win, WM_MOUSEWHEEL, 0, MAKEWORD(x, y)); Sleep(200); cv::Mat oimg = CaptureUtil::capture(win); try { list codes = captureLimitUpCodes(oimg); for (list::iterator e = codes.begin();e != codes.end();e++) { string code = (*e).code; if (codesSet.count(code) == 0) { codesSet.insert(code); flist.push_back(*e); } } codes.clear(); } catch (string e) { cout << e << endl; } Sleep(50); } } return flist; } //È«²¿¿ªÊ¼ void LimitUpCapture::start() { running = true; } //È«²¿½áÊø void LimitUpCapture::stop() { running = false; } bool LimitUpCapture::isInited() { return inited; }