| | |
| | | #include "TaskChecker.h" |
| | | #include "GPUtil.h" |
| | | #include "LogUtil.h" |
| | | #include "L2TradeQueueUtil.h" |
| | | |
| | | //#define malloc(size) malloc(size) |
| | | //#define free(ptr) free(ptr) |
| | |
| | | bool L2DataCapture::tradeTimeCapture; |
| | | |
| | | OpenCLExcuter* L2DataCapture::openCLExcuter[THS_FRAME_COUNT]; |
| | | OpenCLExcuter* L2DataCapture::openCLExcuterQueue[THS_FRAME_COUNT]; |
| | | |
| | | TradeQueueCapture* L2DataCapture::tradeQueueCapture[THS_FRAME_COUNT]; |
| | | |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | if (GPUtil::isBeforeTradeTime()) { |
| | | Sleep(1000); |
| | | } |
| | | |
| | | if (running && runnings[index] && gpCodes[index].length() > 0) { |
| | | latest_running_times[index] = clock(); |
| | | //识别数据 |
| | |
| | | |
| | | list<TradeData> resultList = captureLevel2TradeData(mat, index); |
| | | long processTime = clock() - start; |
| | | data_callback(index, code, start , processTime, resultList, context); |
| | | data_callback(index, code, start, processTime, resultList, context); |
| | | cout << "时间消耗:" << processTime << endl; |
| | | } |
| | | catch (string st) { |
| | | //delete (openCLExcuter[index]); |
| | | //openCLExcuter[index] = new OpenCLExcuter(); |
| | | //openCLExcuter[index]->init(); |
| | | //delete (openCLExcuter[index]); |
| | | //openCLExcuter[index] = new OpenCLExcuter(); |
| | | //openCLExcuter[index]->init(); |
| | | LogUtil::getInstance()->getL2Logger().error(string("识别出错:").append(st)); |
| | | } |
| | | catch (int error_code) { |
| | |
| | | void L2DataCapture::_run_trade_queue(int index) |
| | | { |
| | | while (true) { |
| | | if (killRunnings[index]) |
| | | break; |
| | | TaskChecker::clientLiveTime.l2[index] = clock(); |
| | | if (tradeTimeCapture) { |
| | | if (!GPUtil::isTradeTime()) { |
| | | Sleep(2); |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | if (GPUtil::isBeforeTradeTime()) { |
| | | Sleep(1000); |
| | | } |
| | | |
| | | if (running && runnings[index] && gpCodes[index].length() > 0) { |
| | | //识别数据 |
| | | string code = gpCodes[index]; |
| | | try { |
| | | list<int> numList;//= tradeQueueCapture[index]->recognition(CaptureUtil::getHWND(index, CAPTURE_TYPE_TRADE_QUEUE)); |
| | | trade_queue_data_callback(index, code, numList, context); |
| | | clock_t start = clock(); |
| | | cv::Mat mat = CaptureUtil::capture(index, CAPTURE_TYPE_TRADE_QUEUE); |
| | | if (mat.cols <= 400 || mat.rows <= 30) { |
| | | mat.release(); |
| | | mat = NULL; |
| | | Sleep(100); |
| | | throw string("截图出错"); |
| | | } |
| | | |
| | | L2TradeQueue result = captureLevel2TradeQueueData(mat, index); |
| | | long processTime = clock() - start; |
| | | cout << "时间消耗:" << processTime << endl; |
| | | trade_queue_data_callback(index, code, result, context); |
| | | } |
| | | catch (...) { |
| | | |
| | |
| | | context = contex; |
| | | |
| | | |
| | | for (int i = 0;i < THS_FRAME_COUNT;i++) |
| | | for (int i = 0; i < THS_FRAME_COUNT; i++) |
| | | { |
| | | openCLExcuter[i] = new OpenCLExcuter(); |
| | | openCLExcuter[i]->init(); |
| | | openCLExcuterQueue[i]= new OpenCLExcuter(); |
| | | openCLExcuterQueue[i]->init(); |
| | | |
| | | tradeQueueCapture[i] = new TradeQueueCapture(); |
| | | } |
| | | |
| | | running = false; |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | for (int i = 0; i < length; i++) { |
| | | runnings[i] = false; |
| | | thread rt(&(L2DataCapture::_run), i); |
| | | rt.detach(); |
| | | killRunnings[i] = FALSE; |
| | | //thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i); |
| | | //rt_trade_queue.detach(); |
| | | thread rt_trade_queue(&(L2DataCapture::_run_trade_queue), i); |
| | | rt_trade_queue.detach(); |
| | | } |
| | | |
| | | //获取同花顺窗口句柄 |
| | |
| | | |
| | | void L2DataCapture::startAll() { |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | for (int i = 0; i < length; i++) { |
| | | runnings[i] = true; |
| | | } |
| | | } |
| | | |
| | | void L2DataCapture::stopAll() { |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | for (int i = 0; i < length; i++) { |
| | | runnings[i] = false; |
| | | } |
| | | } |
| | |
| | | |
| | | clock_t starttime = clock(); |
| | | |
| | | list<TradeData> resultList= captureLevel2TradeData(openCLExcuter[identify], oimg, identify); |
| | | list<TradeData> resultList = captureLevel2TradeData(openCLExcuter[identify], oimg, identify); |
| | | |
| | | std::cout << "-------L2行情识别结束任务: threadid-" << std::this_thread::get_id() << " 序号:" << identify << " CODE:"<< gpCodes[identify] << " 耗时:" << clock() - starttime <<" 数据量:"<< resultList.size() << endl; |
| | | std::cout << "-------L2行情识别结束任务: threadid-" << std::this_thread::get_id() << " 序号:" << identify << " CODE:" << gpCodes[identify] << " 耗时:" << clock() - starttime << " 数据量:" << resultList.size() << endl; |
| | | |
| | | return resultList; |
| | | } |
| | | |
| | | |
| | | list<TradeData> L2DataCapture::captureLevel2TradeData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify) |
| | | { |
| | |
| | | int* rowDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4); |
| | | list<int*>::iterator e; |
| | | int index = 0; |
| | | for (e = rowDataList.begin();e != rowDataList.end();e++) { |
| | | for (e = rowDataList.begin(); e != rowDataList.end(); e++) { |
| | | int* indexs = *e; |
| | | rowDataOneLevel[index * 4 + 0] = indexs[1]; |
| | | rowDataOneLevel[index * 4 + 1] = indexs[0]; |
| | |
| | | free(rowSplitDataOneLevel); |
| | | throw string("图片分隔出错"); |
| | | } |
| | | |
| | | |
| | | |
| | | /* |
| | | for (int i = 0;i < rowDataList.size();i++) { |
| | |
| | | |
| | | //结果初始化 |
| | | list<TradeData> resultList; |
| | | for (int i = 0;i < rowDataList.size();i++) { |
| | | for (int i = 0; i < rowDataList.size(); i++) { |
| | | TradeData td = TradeData(); |
| | | resultList.push_back(td); |
| | | } |
| | |
| | | |
| | | |
| | | int i = 0; |
| | | for (list<TradeData>::iterator ele = resultList.begin();ele != resultList.end();++ele) { |
| | | for (list<TradeData>::iterator ele = resultList.begin(); ele != resultList.end(); ++ele) { |
| | | switch (notNumberResult[i * 3]) |
| | | { |
| | | case 0: |
| | | (*ele).cancelTimeUnit = TIME_SECOND;break; |
| | | (*ele).cancelTimeUnit = TIME_SECOND; break; |
| | | case 1: |
| | | (*ele).cancelTimeUnit = TIME_MINITE;break; |
| | | (*ele).cancelTimeUnit = TIME_MINITE; break; |
| | | case 2: |
| | | (*ele).cancelTimeUnit = TIME_HOUR;break; |
| | | (*ele).cancelTimeUnit = TIME_HOUR; break; |
| | | |
| | | default: |
| | | break; |
| | |
| | | switch (notNumberResult[i * 3 + 1]) |
| | | { |
| | | case 0: |
| | | (*ele).limitPrice = LIMIT_PRICE_NORMAL;break; |
| | | (*ele).limitPrice = LIMIT_PRICE_NORMAL; break; |
| | | case 1: |
| | | (*ele).limitPrice = LIMIT_PRICE_UP;break; |
| | | (*ele).limitPrice = LIMIT_PRICE_UP; break; |
| | | case 2: |
| | | (*ele).limitPrice = LIMIT_PRICE_DOWN;break; |
| | | (*ele).limitPrice = LIMIT_PRICE_DOWN; break; |
| | | |
| | | default: |
| | | break; |
| | |
| | | |
| | | |
| | | index = 0; |
| | | for (e = rowDataList.begin();e != rowDataList.end();e++) { |
| | | for (e = rowDataList.begin(); e != rowDataList.end(); e++) { |
| | | |
| | | int startS = index * 4 * 7; |
| | | |
| | |
| | | std::cout << "数据准备-位置数据准备: threadid-" << std::this_thread::get_id() << " 耗时:" << time_32 - time_31 << "总耗时:" << time_32 - time_1 << endl; |
| | | |
| | | 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++) |
| | | 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<uchar>(r)[c]; |
| | | } |
| | |
| | | } |
| | | */ |
| | | |
| | | uchar** numberResult=nullptr; |
| | | uchar** numberResult = nullptr; |
| | | //数字识别 |
| | | try { |
| | | numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | //释放内存 |
| | | free(totalNumberData); |
| | | free(templateNums); |
| | |
| | | //循环读取数字 |
| | | list<TradeData>::iterator tradeEle; |
| | | index = 0; |
| | | for (tradeEle = resultList.begin();tradeEle != resultList.end();tradeEle++) { |
| | | for (tradeEle = resultList.begin(); tradeEle != resultList.end(); tradeEle++) { |
| | | uchar* lineData = numberResult[index]; |
| | | string time = ""; |
| | | time.append(to_string(lineData[0])).append(to_string(lineData[1])); |
| | |
| | | return resultList; |
| | | } |
| | | |
| | | L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(HWND hwnd, int index) |
| | | { |
| | | cv::Mat mat = CaptureUtil::capture(hwnd); |
| | | return captureLevel2TradeQueueData(mat,index); |
| | | } |
| | | |
| | | L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(cv::Mat& oimg, int identify) |
| | | { |
| | | return captureLevel2TradeQueueData(openCLExcuterQueue[identify],oimg,identify); |
| | | } |
| | | |
| | | L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify) |
| | | { |
| | | cv::Mat img = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1); |
| | | |
| | | if (oimg.channels() == 1) { |
| | | //黑白图片 |
| | | img.data = oimg.data; |
| | | } |
| | | else { |
| | | try { |
| | | if (oimg.channels() == 3) |
| | | { |
| | | openCLExcuter->rgb2Gray(oimg, img.data); |
| | | } |
| | | else { |
| | | openCLExcuter->rgba2Gray(oimg, img.data); |
| | | } |
| | | oimg.release(); |
| | | } |
| | | catch (...) { |
| | | oimg.release(); |
| | | oimg = NULL; |
| | | img.release(); |
| | | img = NULL; |
| | | throw string("灰度出错"); |
| | | } |
| | | } |
| | | |
| | | |
| | | try { |
| | | list<ImgArea> splitAreas = L2TradeQueueUtil::splitElements(img); |
| | | int* splitResult = (int*)malloc(sizeof(int) * 4 * 6); |
| | | int index = 0; |
| | | for (list<ImgArea>::iterator ele = splitAreas.begin(); ele != splitAreas.end(); ++ele) { |
| | | ImgArea area = *ele; |
| | | if (area.startx < 0) { |
| | | splitResult[index * 4 + 0] = 0; |
| | | splitResult[index * 4 + 1] = 0; |
| | | splitResult[index * 4 + 2] = 0; |
| | | splitResult[index * 4 + 3] = 0; |
| | | } |
| | | else { |
| | | splitResult[index * 4 + 0] = area.startx; |
| | | splitResult[index * 4 + 1] = area.starty; |
| | | splitResult[index * 4 + 2] = area.endx; |
| | | splitResult[index * 4 + 3] = area.endy; |
| | | } |
| | | index++; |
| | | } |
| | | |
| | | |
| | | |
| | | clock_t time_2 = clock(); |
| | | 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]; |
| | | } |
| | | } |
| | | int num_length_per_ele = 6; |
| | | int ele_count_per_line = 6; |
| | | int line_number_count = ele_count_per_line * num_length_per_ele; |
| | | unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count); |
| | | unsigned char types[] = { NUM_TYPE_TIME,NUM_TYPE_TIME,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU,NUM_TYPE_PRICE, NUM_TYPE_NUM_SHOU }; |
| | | UcharDataInfo typesData = UcharDataInfo(); |
| | | typesData.length = 6; |
| | | typesData.data = types; |
| | | |
| | | openCLExcuter->splitPlateNum(img, IntDataInfo({ splitResult,(int)(ele_count_per_line * 1) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, ele_count_per_line, num_length_per_ele); |
| | | free(splitResult); |
| | | free(zeroData); |
| | | |
| | | //识别 |
| | | uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count); |
| | | try { |
| | | openCLExcuter->createNumberTemplates(1, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, line_number_count, ImgUtil::numsOneLevel_gpcode, templateNums); |
| | | } |
| | | catch (...) { |
| | | free(totalNumberData); |
| | | free(templateNums); |
| | | throw string("创建数据模板出错"); |
| | | } |
| | | |
| | | |
| | | uchar** numberResult = nullptr; |
| | | //数字识别 |
| | | try { |
| | | numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, 1 * _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); |
| | | free(templateNums); |
| | | } |
| | | catch (...) { |
| | | //释放内存 |
| | | free(totalNumberData); |
| | | free(templateNums); |
| | | throw string("数字识别出错"); |
| | | } |
| | | |
| | | img.release(); |
| | | |
| | | //循环读取数字 |
| | | uchar* lineData = numberResult[0]; |
| | | string sellOneTime = ""; |
| | | sellOneTime.append(to_string(lineData[0])).append(to_string(lineData[1])); |
| | | sellOneTime.append(":"); |
| | | sellOneTime.append(to_string(lineData[2])).append(to_string(lineData[3])); |
| | | sellOneTime.append(":"); |
| | | sellOneTime.append(to_string(lineData[4])).append(to_string(lineData[5])); |
| | | |
| | | string buyOneTime = ""; |
| | | buyOneTime.append(to_string(lineData[6])).append(to_string(lineData[7])); |
| | | buyOneTime.append(":"); |
| | | buyOneTime.append(to_string(lineData[8])).append(to_string(lineData[9])); |
| | | buyOneTime.append(":"); |
| | | buyOneTime.append(to_string(lineData[10])).append(to_string(lineData[11])); |
| | | |
| | | |
| | | string sellOnePrice = ""; |
| | | for (int i = 0; i < 6; i++) |
| | | { |
| | | sellOnePrice.append(to_string(lineData[12 + i])); |
| | | if (i == 3) { |
| | | sellOnePrice.append("."); |
| | | } |
| | | } |
| | | |
| | | string sellOneNum = ""; |
| | | for (int i = 0; i < 6; i++) |
| | | { |
| | | sellOneNum.append(to_string(lineData[18 + i])); |
| | | } |
| | | |
| | | string buyOnePrice = ""; |
| | | for (int i = 0; i < 6; i++) |
| | | { |
| | | buyOnePrice.append(to_string(lineData[24 + i])); |
| | | if (i == 3) { |
| | | buyOnePrice.append("."); |
| | | } |
| | | } |
| | | |
| | | string buyOneNum = ""; |
| | | for (int i = 0; i < 6; i++) |
| | | { |
| | | buyOneNum.append(to_string(lineData[30 + i])); |
| | | } |
| | | |
| | | //释放内存 |
| | | free(lineData); |
| | | index++; |
| | | free(numberResult); |
| | | |
| | | |
| | | L2TradeQueue tradeQueue = L2TradeQueue(); |
| | | tradeQueue.buyOnePrice = buyOnePrice; |
| | | tradeQueue.buyOneVolumn = buyOneNum; |
| | | tradeQueue.buyTime = buyOneTime; |
| | | tradeQueue.sellOnePrice = sellOnePrice; |
| | | tradeQueue.sellOneVolumn = sellOneNum; |
| | | tradeQueue.sellTime = sellOneTime; |
| | | return tradeQueue; |
| | | } |
| | | catch (...) { |
| | | img.release(); |
| | | img = NULL; |
| | | throw int(ERROR_CODE_DIVIDE_IMG_FAIL); |
| | | } |
| | | |
| | | } |
| | | |
| | | //捕获level2的盘口数据 |
| | | list<TradeData> L2DataCapture::captureLevel2TradeData(HWND hwnd, int index) throw(int) { |
| | | clock_t starttime = clock(); |
| | |
| | | return resultList; |
| | | } |
| | | catch (int code) { |
| | | |
| | | |
| | | } |
| | | list<TradeData> tempList; |
| | | return tempList; |