#include "L2DataCapture.h"
|
#include <thread>
|
#include<fstream>
|
#include "THSActionUtil.h"
|
#include <thread>
|
#include "TaskChecker.h"
|
#include "GPUtil.h"
|
#include "LogUtil.h"
|
#include "L2TradeQueueUtil.h"
|
#include "Win32Util.h"
|
|
//#define malloc(size) malloc(size)
|
//#define free(ptr) free(ptr)
|
|
bool L2DataCapture::inited;
|
bool L2DataCapture::tradeTimeCapture;
|
|
OpenCLExcuter* L2DataCapture::openCLExcuter[THS_FRAME_COUNT];
|
OpenCLExcuter* L2DataCapture::openCLExcuterQueue[THS_FRAME_COUNT];
|
|
TradeQueueCapture* L2DataCapture::tradeQueueCapture[THS_FRAME_COUNT];
|
|
|
//ÊÇ·ñÕýÔÚÖ´ÐÐ
|
bool L2DataCapture::running;
|
bool L2DataCapture::runnings[THS_FRAME_COUNT];
|
bool L2DataCapture::killRunnings[THS_FRAME_COUNT];
|
clock_t L2DataCapture::latest_running_times[THS_FRAME_COUNT];
|
|
CallbackFun L2DataCapture::data_callback;
|
|
CallbackFun_Trade_Queue L2DataCapture::trade_queue_data_callback;
|
|
string L2DataCapture::gpCodes[THS_FRAME_COUNT];
|
|
void* L2DataCapture::context;
|
|
//ÔËÐÐ
|
void L2DataCapture::_run(int index)
|
{
|
while (true) {
|
|
|
clock_t origin_start_time = clock();
|
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) {
|
if (index == 0) {
|
cout << "-----------------------¿ªÊ¼-------------------- " << endl;
|
}
|
latest_running_times[index] = clock();
|
//ʶ±ðÊý¾Ý
|
string code = gpCodes[index];
|
try {
|
clock_t start = clock();
|
cv::Mat mat = CaptureUtil::capture(index, CAPTURE_TYPE_L2);
|
if (mat.cols <= 400 || mat.rows <= 1600) {
|
mat.release();
|
mat = NULL;
|
Sleep(100);
|
throw string("½ØÍ¼³ö´í");
|
}
|
if (index == 0)
|
{
|
cout << "-----------½ØÍ¼Ê±¼äÏûºÄ£º--------- " << index << " " << clock() - start << endl;
|
}
|
|
start = clock();
|
list<TradeData*> resultList = captureLevel2TradeData(mat, index);
|
if (index == 0)
|
{
|
cout << "-----------ʶ±ðʱ¼äÏûºÄ:---------- " << index <<" ÊýÁ¿£º"<< resultList.size() << " " << clock() - start << endl;
|
}
|
long processTime = clock() - origin_start_time;
|
start = clock();
|
data_callback(index, code, start, processTime, resultList, context);
|
if (index == 0)
|
{
|
cout << "------------Êý¾Ý»Øµ÷ʱ¼äÏûºÄ£º-----------" << clock() - start << endl;
|
}
|
}
|
catch (string st) {
|
//delete (openCLExcuter[index]);
|
//openCLExcuter[index] = new OpenCLExcuter();
|
//openCLExcuter[index]->init();
|
LogUtil::getInstance()->getL2Logger().error(string("ʶ±ð³ö´í£º").append(st));
|
}
|
catch (int error_code) {
|
LogUtil::getInstance()->getL2Logger().error(string("ʶ±ð³ö´í£ºcode-").append(to_string(error_code)));
|
}
|
catch (exception& e) {
|
LogUtil::getInstance()->getL2Logger().error(string("ʶ±ð³ö´í£º").append(e.what()));
|
}
|
catch (...) {
|
LogUtil::getInstance()->getL2Logger().error(string("ʶ±ð³ö´í£º").append("δ֪´íÎó"));
|
}
|
}
|
Sleep(2);
|
if (index == 0)
|
{
|
cout << "-----------Õû¸öL2ÖÜÆÚʱ¼äÏûºÄʱ¼äÏûºÄ£º------------- " << index << " " << clock() - origin_start_time << endl;
|
}
|
if (index == 0)
|
{
|
cout << "-----------------------½áÊø-------------------- \n\n " << endl;
|
}
|
}
|
}
|
|
|
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 {
|
clock_t start = clock();
|
HWND queueHWND = CaptureUtil::getHWND(index, CAPTURE_TYPE_TRADE_QUEUE);
|
L2TradeQueue result = captureLevel2TradeQueueData(queueHWND, index);
|
long processTime = clock() - start;
|
//cout << "ʱ¼äÏûºÄ£º" << processTime << endl;
|
trade_queue_data_callback(index, code, result, context);
|
}
|
catch (...) {
|
|
}
|
}
|
Sleep(600);
|
}
|
}
|
|
std::list<string> L2DataCapture::captureLevel2TradeQueueBuyData(OpenCLExcuter* openCLExcuter, cv::Mat& grayImg, int identify)
|
{
|
if (grayImg.cols == 0 || grayImg.rows == 0) {
|
return list<string>();
|
}
|
cv::Mat img;
|
try {
|
list<ImgArea> splitAreas = L2TradeQueueUtil::splitBuyQueue(grayImg, identify);
|
int* splitResult = (int*)malloc(sizeof(int) * 4 * splitAreas.size());
|
int index = 0;
|
for (list<ImgArea>::iterator ele = splitAreas.begin(); ele != splitAreas.end(); ++ele) {
|
ImgArea area = *ele;
|
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++;
|
}
|
|
|
//¶þÖµ»¯£¬·½±ã´¦Àí
|
threshold(grayImg, img, _IMG_BINARY_THRESHOLD, 255, cv::THRESH_BINARY);
|
|
|
|
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 = 5;
|
//splitAreasQueue×î¶à12¸öÊý×Ö
|
int ele_count_per_line = splitAreas.size();
|
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[24];
|
for (int i = 0; i < 24; i++) {
|
types[i] = NUM_TYPE_NUM;
|
}
|
UcharDataInfo typesData = UcharDataInfo();
|
typesData.length = ele_count_per_line;
|
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];
|
list<string> buyQueueList;
|
for (int i = 0; i < ele_count_per_line; i++) {
|
string num = "";
|
for (int j = 0; j < num_length_per_ele; j++) {
|
num.append(to_string(lineData[num_length_per_ele * i + j]));
|
}
|
buyQueueList.push_back(num);
|
}
|
|
//ÊÍ·ÅÄÚ´æ
|
free(lineData);
|
index++;
|
free(numberResult);
|
return buyQueueList;
|
}
|
catch (...) {
|
img.release();
|
img = NULL;
|
throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
|
}
|
}
|
|
cv::Mat L2DataCapture::grayImg(OpenCLExcuter* openCLExcuter, cv::Mat& oimg)
|
{
|
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("»Ò¶È³ö´í");
|
}
|
}
|
|
return img;
|
}
|
|
void L2DataCapture::setGPCode(int index, string code) {
|
if (THS_FRAME_COUNT <= index) {
|
return;
|
}
|
gpCodes[index] = code;
|
}
|
|
string L2DataCapture::getGPCode(int index) {
|
return gpCodes[index];
|
}
|
|
static string getGPCode(int index);
|
|
L2DataCapture::L2DataCapture() {
|
|
}
|
void L2DataCapture::refreshHWND() {
|
HWND win = THSActionUtil::getL2Win();
|
if (win <= 0) {
|
throw string("δ»ñÈ¡µ½Í¬»¨Ë³LEVEL2ÅÌ¿Ú");
|
}
|
CaptureUtil::init(win);
|
}
|
|
void L2DataCapture::init(CallbackFun callback, CallbackFun_Trade_Queue trade_queue_callback, void* contex) {
|
inited = true;
|
data_callback = callback;
|
trade_queue_data_callback = trade_queue_callback;
|
context = contex;
|
|
|
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++) {
|
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();
|
}
|
|
//»ñȡͬ»¨Ë³´°¿Ú¾ä±ú
|
try {
|
refreshHWND();
|
}
|
catch (string st) {
|
throw st;
|
}
|
|
}
|
|
void L2DataCapture::reCreateChannelRunner(int index)
|
{
|
//ÏÈɱËÀÔÓÐÏß³Ì
|
killRunnings[index] = TRUE;
|
Sleep(500);
|
killRunnings[index] = FALSE;
|
|
thread rt(&(L2DataCapture::_run), index);
|
rt.detach();
|
}
|
|
bool L2DataCapture::isRunning() {
|
return running;
|
}
|
|
void L2DataCapture::start(int index) {
|
runnings[index] = true;
|
}
|
//½áÊø
|
void L2DataCapture::stop(int index) {
|
runnings[index] = false;
|
}
|
//È«²¿¿ªÊ¼
|
void L2DataCapture::start() {
|
running = true;
|
}
|
//È«²¿½áÊø
|
void L2DataCapture::stop() {
|
running = false;
|
}
|
|
void L2DataCapture::startAll() {
|
int length = sizeof(runnings) / sizeof(runnings[0]);
|
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++) {
|
runnings[i] = false;
|
}
|
}
|
|
bool L2DataCapture::isInited() {
|
return inited;
|
}
|
|
list<TradeData*> L2DataCapture::captureLevel2TradeData(cv::Mat& oimg, int identify) {
|
if (oimg.rows == 0 || oimg.cols == 0) {
|
throw ERROR_CODE_CAPTURE_FAIL;
|
}
|
|
clock_t starttime = clock();
|
|
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;
|
|
return resultList;
|
}
|
|
|
list<TradeData*> L2DataCapture::captureLevel2TradeData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, int identify)
|
{
|
bool ENABLE_LOG = FALSE;
|
|
if (oimg.cols <= 0 || oimg.rows <= 0) {
|
throw string("ͼÏñÊý¾Ý´íÎó");
|
}
|
|
//LogUtil::debug("½ØÍ¼Íê³É");
|
clock_t time_1 = clock();
|
//std::cout << "½ØÍ¼Íê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << (time_1 - starttime) << endl;
|
|
//»Ò¶È»¯
|
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("»Ò¶È³ö´í");
|
}
|
//img.data = imgData;
|
clock_t time_2_ = clock();
|
if (identify == 0&& ENABLE_LOG)
|
{
|
std::cout << "»Ò¶ÈÍê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << (time_2_ - time_1) << " ½ØÍ¼³ß´ç£º" << img.cols << "x" << img.rows << endl;
|
|
std::cout << "ͨµÀÊý£º" << oimg.channels() << endl;
|
|
LogUtil::debug("»Ò¶ÈÍê³É");
|
}
|
}
|
|
clock_t time_2 = clock();
|
|
int ele_count_per_line = 7;
|
|
|
|
//ͼÏñ·Ö¸î---¿ªÊ¼
|
list<int*> rowDataList;
|
try {
|
rowDataList = ImgUtil::divideImg(img);
|
if (rowDataList.size() == 0) {
|
throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
|
}
|
}
|
catch (...) {
|
img.release();
|
img = NULL;
|
throw int(ERROR_CODE_DIVIDE_IMG_FAIL);
|
}
|
//һάÐÐͼÏñÊý¾Ý
|
int* rowDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4);
|
list<int*>::iterator e;
|
int index = 0;
|
for (e = rowDataList.begin(); e != rowDataList.end(); e++) {
|
int* indexs = *e;
|
rowDataOneLevel[index * 4 + 0] = indexs[1];
|
rowDataOneLevel[index * 4 + 1] = indexs[0];
|
rowDataOneLevel[index * 4 + 2] = indexs[3];
|
rowDataOneLevel[index * 4 + 3] = indexs[2];
|
index++;
|
free(indexs);
|
}
|
//һά°´ÐÐÇзÖͼÏñÊý¾Ý
|
int* rowSplitDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4 * ele_count_per_line);
|
try {
|
openCLExcuter->splitL2RowData(img, rowDataOneLevel, rowDataList.size(), rowSplitDataOneLevel);
|
free(rowDataOneLevel);
|
}
|
catch (...) {
|
img.release();
|
img = NULL;
|
free(rowDataOneLevel);
|
free(rowSplitDataOneLevel);
|
throw string("ͼƬ·Ö¸ô³ö´í");
|
}
|
|
|
/*
|
for (int i = 0;i < rowDataList.size();i++) {
|
string path = "C:\\Users\\Administrator\\Desktop\\ocr\\cancel_time\\";
|
path.append(to_string(identify)).append("_").append(to_string(i)).append(".jpg");
|
int start = 4 * 7 * i;
|
start += 4 * (1);
|
int startx = rowSplitDataOneLevel[start];
|
int starty = rowSplitDataOneLevel[start + 1];
|
int endx = rowSplitDataOneLevel[start + 2];
|
int endy = rowSplitDataOneLevel[start + 3];
|
if (startx > 0) {
|
cv::imwrite(path, cv::Mat(img, cv::Rect(startx, starty, endx - startx + 1, endy - starty + 1)));
|
}
|
}
|
*/
|
|
|
//±£´æ·Ö¸ôµÄͼƬ
|
if (false) {
|
int start = 4 * ele_count_per_line * (138);
|
start += 4 * (1);
|
int startx = 385;//rowSplitDataOneLevel[start];
|
int starty = 1071;//rowSplitDataOneLevel[start + 1];
|
int endx = 389;//rowSplitDataOneLevel[start + 2];
|
int endy = 1078;//rowSplitDataOneLevel[start + 3];
|
cv::imwrite(string("C:\\Users\\Administrator\\Desktop\\ocr\\l2·ÖÎö\\test.png"), cv::Mat(img, cv::Rect(startx, starty, endx - startx + 1, endy - starty + 1)));
|
}
|
|
|
|
|
|
clock_t time_3 = clock();
|
//LogUtil::debug("·Ö¸ôÍê³É");
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "·Ö¸ôÍê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_3 - time_2 << "×ܺÄʱ£º" << time_3 - time_1 << endl;
|
|
//½á¹û³õʼ»¯
|
list<TradeData*> resultList;
|
for (int i = 0; i < rowDataList.size(); i++) {
|
TradeData* td = new TradeData;
|
resultList.push_back(td);
|
}
|
|
//------·ÇÊý×Öʶ±ð¿ªÊ¼-------
|
//ͼÏñʶ±ð(³ý¿ªÊý×ֵIJ¿·Ö)
|
|
int* notNumberResult = (int*)malloc(sizeof(int) * rowDataList.size() * 3);
|
openCLExcuter->recognitionNotNum(img.data, img.cols, img.rows, rowSplitDataOneLevel, ele_count_per_line, rowDataList.size(), notNumberResult);
|
|
|
int i = 0;
|
for (list<TradeData*>::iterator ele = resultList.begin(); ele != resultList.end(); ++ele) {
|
switch (notNumberResult[i * 3])
|
{
|
case 0:
|
(*ele)->cancelTimeUnit = TIME_SECOND; break;
|
case 1:
|
(*ele)->cancelTimeUnit = TIME_MINITE; break;
|
case 2:
|
(*ele)->cancelTimeUnit = TIME_HOUR; break;
|
|
default:
|
break;
|
}
|
|
switch (notNumberResult[i * 3 + 1])
|
{
|
case 0:
|
(*ele)->limitPrice = LIMIT_PRICE_NORMAL; break;
|
case 1:
|
(*ele)->limitPrice = LIMIT_PRICE_UP; break;
|
case 2:
|
(*ele)->limitPrice = LIMIT_PRICE_DOWN; break;
|
|
default:
|
break;
|
}
|
switch (notNumberResult[i * 3 + 2])
|
{
|
case OPERATE_BUY:
|
(*ele)->operateType = OPERATE_BUY;
|
break;
|
case OPERATE_BUY_CANCEL:
|
(*ele)->operateType = OPERATE_BUY_CANCEL;
|
break;
|
case OPERATE_SELL:
|
(*ele)->operateType = OPERATE_SELL;
|
break;
|
case OPERATE_SELL_CANCEL:
|
(*ele)->operateType = OPERATE_SELL_CANCEL;
|
break;
|
case OPERATE_OPERATE_ERROR:
|
(*ele)->operateType = OPERATE_OPERATE_ERROR;
|
break;
|
};
|
|
i++;
|
}
|
|
free(notNumberResult);
|
|
clock_t time_5 = clock();
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "·ÇÊý×ÖÊý¾Ýʶ±ðÍê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_5 - time_3 << "×ܺÄʱ£º" << time_5 - time_1 << endl;
|
|
|
//------·ÇÊý×Öʶ±ð½áÊø-------
|
|
|
|
//------Êý×Öʶ±ð¿ªÊ¼---------
|
|
unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowDataList.size()) * _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER);
|
clock_t time_31 = clock();
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý¾Ý×¼±¸-ͼÏñÊý¾Ý×¼±¸: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_31 - time_3 << "×ܺÄʱ£º" << time_31 - time_1 << endl;
|
|
int* pos = (int*)malloc(sizeof(int) * 4 * 4 * rowDataList.size());
|
|
|
index = 0;
|
for (e = rowDataList.begin(); e != rowDataList.end(); e++) {
|
|
int startS = index * 4 * ele_count_per_line;
|
|
|
int start = index * 4 * 4;
|
pos[start] = rowSplitDataOneLevel[startS + 0];
|
pos[start + 1] = rowSplitDataOneLevel[startS + 1];
|
pos[start + 2] = rowSplitDataOneLevel[startS + 2];
|
pos[start + 3] = rowSplitDataOneLevel[startS + 3];
|
|
|
start = index * 4 * 4 + 4 * 1;
|
pos[start] = rowSplitDataOneLevel[startS + 4 * 1 + 0];
|
pos[start + 1] = rowSplitDataOneLevel[startS + 4 * 1 + 1];
|
pos[start + 2] = rowSplitDataOneLevel[startS + 4 * 1 + 2];
|
pos[start + 3] = rowSplitDataOneLevel[startS + 4 * 1 + 3];
|
|
|
start = index * 4 * 4 + 4 * 2;
|
pos[start] = rowSplitDataOneLevel[startS + 4 * 2 + 0];
|
pos[start + 1] = rowSplitDataOneLevel[startS + 4 * 2 + 1];
|
pos[start + 2] = rowSplitDataOneLevel[startS + 4 * 2 + 2];
|
pos[start + 3] = rowSplitDataOneLevel[startS + 4 * 2 + 3];
|
|
|
|
start = index * 4 * 4 + 4 * 3;
|
pos[start] = rowSplitDataOneLevel[startS + 4 * 5 + 0];
|
pos[start + 1] = rowSplitDataOneLevel[startS + 4 * 5 + 1];
|
pos[start + 2] = rowSplitDataOneLevel[startS + 4 * 5 + 2];
|
pos[start + 3] = rowSplitDataOneLevel[startS + 4 * 5 + 3];
|
|
index++;
|
}
|
|
free(rowSplitDataOneLevel);
|
|
|
clock_t time_32 = clock();
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý¾Ý×¼±¸-λÖÃÊý¾Ý×¼±¸: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_32 - time_31 << "×ܺÄʱ£º" << time_32 - time_1 << endl;
|
|
// TODO ±ä³ÉÈ«¾Ö
|
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<uchar>(r)[c];
|
}
|
}
|
|
clock_t time_33 = clock();
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý¾Ý×¼±¸-0Êý¾Ý×¼±¸: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_33 - time_32 << "×ܺÄʱ£º" << time_33 - time_1 << endl;
|
try {
|
openCLExcuter->splitL2Num(img.data, img.cols, img.rows, pos, 4 * rowDataList.size(), zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, totalNumberData);
|
free(zeroData);
|
free(pos);
|
}
|
catch (...) {
|
free(zeroData);
|
free(pos);
|
free(totalNumberData);
|
throw string("splitL2Num³ö´í");
|
}
|
|
//²âÊÔ£¬Õ¹Ê¾Í¼Ïñ
|
//cv::Mat imgTest = cv::Mat::zeros(_NUMBER_L2_HEIGHT * rowDataList.size(), _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, CV_8UC1);
|
//imgTest.data = totalNumberData;
|
//cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\l2·ÖÎö\\test1.png", imgTest);
|
|
|
|
|
/*
|
list<list<int*>>::iterator e;
|
int index = 0;
|
for (e = data.begin();e != data.end();e++) {
|
index++;
|
ImgUtil::splitRowNumDataForOpenCL(img, *e, totalNumberData,index-1);
|
}
|
|
*/
|
clock_t time_34 = clock();
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý¾Ý×¼±¸-Êý×Ö·Ö¸ôÍê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_34 - time_33 << "×ܺÄʱ£º" << time_34 - time_1 << endl;
|
|
//×¼±¸Ä£°åÊý×Ö
|
uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowDataList.size()) * _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER);
|
try {
|
openCLExcuter->createNumberTemplates(rowDataList.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, ImgUtil::numsOneLevel_level2, templateNums);
|
}
|
catch (...) {
|
free(totalNumberData);
|
free(templateNums);
|
throw string("´´½¨Êý¾ÝÄ£°å³ö´í");
|
}
|
|
//ImgUtil::createTemplateNumData(data.size());
|
clock_t time_4 = clock();
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý¾Ý×¼±¸-Ä£°åÊý×Ö×¼±¸Íê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_4 - time_34 << "×ܺÄʱ£º" << time_4 - time_1 << endl;
|
|
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý¾Ý×¼±¸Íê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_4 - time_3 << "×ܺÄʱ£º" << time_4 - time_1 << endl;
|
|
|
|
|
/*
|
try {
|
resultList = (*recognitionManager).recognition(img, rowSplitDataOneLevel, rowDataList.size());
|
}
|
catch (...) {
|
throw ERROR_CODE_RECOGNITION_FAIL;
|
}
|
*/
|
|
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);
|
//ÊÍ·ÅÄÚ´æ
|
free(totalNumberData);
|
free(templateNums);
|
}
|
catch (...) {
|
//ÊÍ·ÅÄÚ´æ
|
free(totalNumberData);
|
free(templateNums);
|
throw string("Êý×Öʶ±ð³ö´í");
|
}
|
|
//Ñ»·¶ÁÈ¡Êý×Ö
|
list<TradeData*>::iterator tradeEle;
|
index = 0;
|
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]));
|
time.append(":");
|
time.append(to_string(lineData[2])).append(to_string(lineData[3]));
|
time.append(":");
|
time.append(to_string(lineData[4])).append(to_string(lineData[5]));
|
|
string cancelTime = "";
|
cancelTime.append(to_string(lineData[6])).append(to_string(lineData[7]));
|
|
string price = "";
|
price.append(to_string(lineData[6 + 2])).append(to_string(lineData[7 + 2])).append(to_string(lineData[8 + 2])).append(to_string(lineData[9 + 2]));
|
price.append(".");
|
price.append(to_string(lineData[10 + 2])).append(to_string(lineData[11 + 2]));
|
|
string num = "";
|
num.append(to_string(lineData[12 + 2])).append(to_string(lineData[13 + 2])).append(to_string(lineData[14 + 2])).append(to_string(lineData[15 + 2])).append(to_string(lineData[16 + 2]));
|
|
|
(*tradeEle)->time = time;
|
(*tradeEle)->num = stoi(num);
|
(*tradeEle)->price = price;
|
(*tradeEle)->index = index;
|
(*tradeEle)->cancelTime = stoi(cancelTime);
|
|
//ÊÍ·ÅÄÚ´æ
|
free(lineData);
|
|
index++;
|
}
|
|
free(numberResult);
|
|
clock_t time_6 = clock();
|
//LogUtil::debug("ʶ±ðÍê³É");
|
if (identify == 0 && ENABLE_LOG)
|
std::cout << "Êý×Öʶ±ðÍê³É: threadid-" << std::this_thread::get_id() << " ºÄʱ£º" << time_6 - time_5 << "×ܺÄʱ£º" << time_6 - time_1 << endl;
|
|
//ÊÍ·ÅÄÚ´æ
|
img.release();
|
rowDataList.clear();
|
list<int*>().swap(rowDataList);
|
|
return resultList;
|
}
|
|
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(HWND hwnd, int index)
|
{
|
HWND buyQueueHWND = L2TradeQueueUtil::getTradeQueueBuyHWND(hwnd);
|
//»ñȡλÖÃ
|
RECT prect;
|
Win32Util::getWindowRect(hwnd, &prect);
|
RECT buyRect;
|
Win32Util::getWindowRect(buyQueueHWND, &buyRect);
|
cv::Mat mat = CaptureUtil::capture(hwnd);
|
if (mat.cols <= 400 || mat.rows <= 30) {
|
mat.release();
|
mat = NULL;
|
Sleep(100);
|
throw string("½ØÍ¼³ö´í");
|
}
|
cv::Rect rect = cv::Rect(buyRect.left - prect.left, buyRect.top - prect.top, buyRect.right - buyRect.left + 1, buyRect.bottom - buyRect.top + 1);
|
return captureLevel2TradeQueueData(mat, rect, index);
|
}
|
|
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(cv::Mat& oimg, cv::Rect buyQueueArea, int identify)
|
{
|
return captureLevel2TradeQueueData(openCLExcuterQueue[identify], oimg, buyQueueArea, identify);
|
}
|
|
L2TradeQueue L2DataCapture::captureLevel2TradeQueueData(OpenCLExcuter* openCLExcuter, cv::Mat& oimg, cv::Rect buyQueueArea, int identify)
|
{
|
cv::Mat img = grayImg(openCLExcuter, oimg);
|
cv::Mat tmpImg = cv::Mat(img, buyQueueArea);
|
cv::Mat buyQueueImg = cv::Mat::zeros(buyQueueArea.height, buyQueueArea.width, CV_8UC1);
|
uchar* datas = (uchar*)malloc(sizeof(uchar)* buyQueueArea.height* buyQueueArea.width);
|
for (int r = 0; r < buyQueueImg.rows; r++) {
|
for (int c = 0; c < buyQueueImg.cols; c++) {
|
datas[r * buyQueueImg.cols + c] = tmpImg.ptr<uchar>(r)[c];
|
}
|
}
|
buyQueueImg.data = datas;
|
|
//¹ýÂ˻Ƶװ××Ö
|
L2TradeQueueUtil::filterTradeQueueBuyMat(buyQueueImg);
|
if (FALSE)
|
{
|
string path = string("C:\\Users\\Administrator\\Desktop\\ocr\\trade_queue\\origin\\").append(to_string(identify)).append("_").append(to_string(rand()).append(".png"));
|
cv::imwrite(path, buyQueueImg);
|
}
|
L2TradeQueue tradeQueue = captureLevel2TradeQueueViewData(openCLExcuter, img, identify);
|
try {
|
std::list<string> buyQueueList = captureLevel2TradeQueueBuyData(openCLExcuter, buyQueueImg, identify);
|
tradeQueue.buyQueue = buyQueueList;
|
}
|
catch (...) {
|
|
}
|
free(datas);
|
return tradeQueue;
|
}
|
|
L2TradeQueue L2DataCapture::captureLevel2TradeQueueViewData(OpenCLExcuter* openCLExcuter, cv::Mat& img, int identify)
|
{
|
L2TradeQueue tradeQueue;
|
try {
|
list<ImgArea> splitAreas = L2TradeQueueUtil::splitViewElements(img);
|
int* splitResult = (int*)malloc(sizeof(int) * 4 * splitAreas.size());
|
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 = 7;
|
//splitAreasQueue×î¶à8¸öÊý×Ö
|
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,NUM_TYPE_NUM,NUM_TYPE_NUM };
|
UcharDataInfo typesData = UcharDataInfo();
|
typesData.length = ele_count_per_line;
|
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[1])).append(to_string(lineData[2]));
|
sellOneTime.append(":");
|
sellOneTime.append(to_string(lineData[3])).append(to_string(lineData[4]));
|
sellOneTime.append(":");
|
sellOneTime.append(to_string(lineData[5])).append(to_string(lineData[6]));
|
|
string buyOneTime = "";
|
buyOneTime.append(to_string(lineData[num_length_per_ele * 1 + 1])).append(to_string(lineData[num_length_per_ele * 1 + 2]));
|
buyOneTime.append(":");
|
buyOneTime.append(to_string(lineData[num_length_per_ele * 1 + 3])).append(to_string(lineData[num_length_per_ele * 1 + 4]));
|
buyOneTime.append(":");
|
buyOneTime.append(to_string(lineData[num_length_per_ele * 1 + 5])).append(to_string(lineData[num_length_per_ele * 1 + 6]));
|
|
|
string sellOnePrice = "";
|
for (int i = 0; i < num_length_per_ele; i++)
|
{
|
sellOnePrice.append(to_string(lineData[num_length_per_ele * 2 + i]));
|
if (i == num_length_per_ele - 3) {
|
sellOnePrice.append(".");
|
}
|
}
|
|
string sellOneNum = "";
|
for (int i = 0; i < num_length_per_ele; i++)
|
{
|
sellOneNum.append(to_string(lineData[num_length_per_ele * 3 + i]));
|
}
|
|
string buyOnePrice = "";
|
for (int i = 0; i < num_length_per_ele; i++)
|
{
|
buyOnePrice.append(to_string(lineData[num_length_per_ele * 4 + i]));
|
if (i == num_length_per_ele - 3) {
|
buyOnePrice.append(".");
|
}
|
}
|
|
string buyOneNum = "";
|
for (int i = 0; i < num_length_per_ele; i++)
|
{
|
buyOneNum.append(to_string(lineData[num_length_per_ele * 5 + i]));
|
}
|
|
//ÊÍ·ÅÄÚ´æ
|
free(lineData);
|
index++;
|
free(numberResult);
|
|
|
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();
|
cv::Mat img = CaptureUtil::capture(hwnd);
|
|
|
/*
|
string path1 = "E:\\temp\\";
|
|
path1.append(to_string(frameIndex));
|
path1.append("\\");
|
path1.append(to_string(clock()));
|
path1.append(".jpg");
|
cv::imwrite(path1, img);
|
std::map<string, TradeData> map;
|
*/
|
try {
|
list<TradeData*> resultList = captureLevel2TradeData(img, index);
|
return resultList;
|
}
|
catch (int code) {
|
|
}
|
list<TradeData*> tempList;
|
return tempList;
|
}
|