#include "TradeListCapture.h"
|
#include <set>
|
#include "Win32Util.h"
|
#include "TaskChecker.h"
|
#include "GPUtil.h"
|
bool TradeListCapture::tradeTimeCapture_success;
|
bool TradeListCapture::tradeTimeCapture_delegate;
|
OpenCLExcuter* TradeListCapture::openCLExcuterDelegate;
|
OpenCLExcuter* TradeListCapture::openCLExcuterSuccess;
|
|
bool TradeListCapture::inited;
|
bool TradeListCapture::kill_d;
|
bool TradeListCapture::kill_s;
|
HWND TradeListCapture::trade_delegate_win;
|
HWND TradeListCapture::trade_success_win;
|
HWND TradeListCapture::trade_simple_delegate_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;
|
if (tradeTimeCapture_success) {
|
if (!GPUtil::isTradeTime()) {
|
Sleep(100);
|
continue;
|
}
|
}
|
|
TaskChecker::clientLiveTime.tradeSuccess = clock();
|
if (running_s && inited) {
|
clock_t start = clock();
|
try {
|
list<TradeSuccessData> 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;
|
if (tradeTimeCapture_delegate) {
|
if (!GPUtil::isTradeTime()) {
|
Sleep(100);
|
continue;
|
}
|
}
|
//1sÒ»´Î
|
if (running_d && inited) {
|
clock_t start = clock();
|
try {
|
list<TradeDelegateData> datas = captureSimpleTradeDelegateInfo();
|
string money = getSimpleAvaiableMoney();
|
//cout << "ºÄʱ:" << clock() - start << " ÊýÁ¿£º" << datas.size() << endl;
|
data_callback_delegate(datas, money, context);
|
datas.clear();
|
}
|
catch (...) {
|
|
}
|
Sleep(500);
|
}
|
else {
|
Sleep(2000);
|
}
|
}
|
}
|
|
|
|
cv::Mat TradeListCapture::grayImgs(cv::Mat oimg, OpenCLExcuter* openCLExcuter) {
|
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, 64);
|
}
|
else {
|
openCLExcuter->rgba2ThresholdInvert(oimg.data, oimg.cols, oimg.rows, imgData, 64);
|
}
|
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();
|
openCLExcuterDelegate = new OpenCLExcuter();
|
openCLExcuterDelegate->init();
|
|
openCLExcuterSuccess = new OpenCLExcuter();
|
openCLExcuterSuccess->init();
|
|
thread rt(&(TradeListCapture::_run_s));
|
rt.detach();
|
|
|
thread rt1(&(TradeListCapture::_run_d));
|
rt1.detach();
|
|
inited = true;
|
try {
|
refreshTradeSuccessHWND();
|
}
|
catch (...) {
|
|
}
|
|
try {
|
refreshTradeDelegateHWND();
|
}
|
catch (...) {
|
|
}
|
|
try {
|
refreshTradeSimpleDelegateHWND();
|
}
|
catch (...) {
|
|
}
|
|
|
}
|
void TradeListCapture::selectTradeSimpleDelegate(MatOcrFun matMcrFun)
|
{
|
try {
|
//ˢд°¿Ú
|
refreshTradeSimpleDelegateHWND();
|
}
|
catch (...) {
|
|
}
|
HWND win = THSActionUtil::getTradeSimpleDelegateWindow();
|
HWND menuWin = TradeListCapture::getSimpleTradeLeftMenu(win);
|
if (menuWin > 0) {
|
cv::Mat img = CaptureUtil::capture(menuWin);
|
cv::Mat grayImg = ImgUtil::grayImage(img);
|
img.release();
|
list<OCRResult> resultList = matMcrFun("µ±ÈÕίÍÐ", grayImg);
|
if (resultList.size() > 0) {
|
OCRResult result = *(resultList.begin());
|
RECT menuWinRect;
|
Win32Util::getWindowRect(menuWin, &menuWinRect);
|
int x = menuWinRect.left + result.rect.left + (result.rect.right - result.rect.left) / 2;
|
int y = menuWinRect.top + result.rect.top + (result.rect.bottom - result.rect.top) / 2;
|
//µã»÷
|
Win32Util::click(x, y, 10);
|
}
|
}
|
}
|
void TradeListCapture::selectTradeSuccess(MatOcrFun matMcrFun)
|
{
|
try {
|
//ˢд°¿Ú
|
refreshTradeSuccessHWND();
|
}
|
catch (...) {
|
|
}
|
HWND win = THSActionUtil::getTradeSuccessWindow();
|
HWND menuWin = TradeListCapture::getSimpleTradeLeftMenu(win);
|
if (menuWin > 0) {
|
cv::Mat img = CaptureUtil::capture(menuWin);
|
cv::Mat grayImg = ImgUtil::grayImage(img);
|
img.release();
|
list<OCRResult> resultList = matMcrFun("µ±Èճɽ»", grayImg);
|
if (resultList.size() > 0) {
|
OCRResult result = *(resultList.begin());
|
RECT menuWinRect;
|
Win32Util::getWindowRect(menuWin, &menuWinRect);
|
int x = menuWinRect.left + result.rect.left + (result.rect.right - result.rect.left) / 2;
|
int y = menuWinRect.top + result.rect.top + (result.rect.bottom - result.rect.top) / 2;
|
//µã»÷
|
Win32Util::click(x, y, 10);
|
}
|
}
|
}
|
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::refreshTradeSimpleDelegateHWND()
|
{
|
HWND hwnd = THSActionUtil::getTradeSimpleDelegateWindow();
|
if (hwnd <= 0)
|
throw string("ͬ»¨Ë³Ô¶º½°æ¾«¼ò½»Ò×Ò³ÃæÎ´´ò¿ª");
|
|
HWND win = FindWindowExA(hwnd, NULL, "AfxMDIFrame140s", NULL);
|
HWND child = NULL;
|
HWND content = 0;
|
for (int i = 0; i < 3; i++) {
|
child = FindWindowExA(win, child, "#32770", NULL);
|
if (child > 0) {
|
|
HWND table = FindWindowExA(child, NULL, NULL, "HexinScrollWnd");
|
if (table > 0) {
|
content = table;
|
break;
|
}
|
}
|
}
|
if (content <= 0)
|
throw string("δ»ñÈ¡µ½ÄÚÈÝ´°¿Ú¾ä±ú");
|
|
trade_simple_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<TradeSuccessData> TradeListCapture::captureTradeSuccessInfo(cv::Mat oimg) {
|
cv::Mat grayImg = grayImgs(oimg, openCLExcuterSuccess);
|
list<TradeSuccessData> dataList;
|
//·Ö¸ôÔªËØ
|
int empty_start = -1;
|
int empty_end = -1;
|
int data_start = -1;
|
int data_end = -1;
|
list<int*> 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<int*>::iterator ele = rowData.begin(); ele != rowData.end(); ele++) {
|
free(*ele);
|
}
|
return dataList;
|
}
|
//ȥͷȥβ
|
list<int*>::iterator start = rowData.begin();
|
list<int*>::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<int*>::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());
|
|
openCLExcuterSuccess->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<uchar>(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;
|
|
openCLExcuterSuccess->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);
|
openCLExcuterSuccess->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
|
uchar** numberResult = openCLExcuterSuccess->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<uchar>(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<TradeSuccessData> TradeListCapture::captureTradeSuccessInfo() {
|
|
HWND win = THSActionUtil::getTradeSuccessWindow();
|
//Ë¢ÐÂÊý¾Ý,°´F5Ë¢ÐÂ
|
Win32Util::virtualKeyboard(win, VK_F5);
|
//HWND toolBar = FindWindowExA(win, NULL, "ToolbarWindow32", NULL);
|
//RECT rect;
|
//Win32Util::getWindowRect(toolBar, &rect);
|
//Win32Util::click(rect.left + 170, rect.top + 5);
|
cv::Mat oimg = CaptureUtil::capture(trade_success_win);
|
if (oimg.cols < 10 || oimg.rows < 10) {
|
throw string("½ØÍ¼³ö´í");
|
}
|
list<TradeSuccessData> codes = captureTradeSuccessInfo(oimg);
|
return codes;
|
}
|
|
|
//˳Ðò£ºÎ¯ÍÐʱ¼ä-´úÂë-ίÍÐÊýÁ¿-ίÍм۸ñ-³É½»¾ù¼Û-³ÉЧÊýÁ¿-²Ù×÷
|
list<TradeDelegateData> TradeListCapture::captureTradeDelegateInfo(cv::Mat oimg) {
|
|
cv::Mat grayImg = grayImgs(oimg, openCLExcuterDelegate);
|
|
list<TradeDelegateData> dataList;
|
//·Ö¸ôÔªËØ
|
int empty_start = -1;
|
int empty_end = -1;
|
int data_start = -1;
|
int data_end = -1;
|
list<int*> rowData;
|
for (int r = 0; r < grayImg.rows; r++) {
|
if (ImgDivider::isRowEmpty(grayImg, r, 0, 100)) {
|
|
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<int*>::iterator ele = rowData.begin(); ele != rowData.end(); ele++) {
|
free(*ele);
|
}
|
return dataList;
|
}
|
|
//ȥͷȥβ
|
list<int*>::iterator start = rowData.begin();
|
list<int*>::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<int*>::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());
|
|
openCLExcuterDelegate->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<uchar>(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;
|
|
openCLExcuterDelegate->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);
|
openCLExcuterDelegate->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
|
uchar** numberResult = openCLExcuterDelegate->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<uchar>(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<TradeDelegateData> TradeListCapture::captureTradeDelegateInfo() {
|
cv::Mat oimg = CaptureUtil::capture(trade_delegate_win);
|
if (oimg.cols < 10 || oimg.rows < 10) {
|
throw string("½ØÍ¼³ö´í");
|
}
|
|
list<TradeDelegateData> codes = captureTradeDelegateInfo(oimg);
|
return codes;
|
}
|
|
HWND TradeListCapture::getSimpleTradeLeftMenu(HWND tradeWin)
|
{
|
HWND win = FindWindowEx(tradeWin, NULL, TEXT("AfxMDIFrame140s"), NULL);
|
if (win <= 0) {
|
throw string("δ»ñÈ¡µ½²Ëµ¥¾ä±ú");
|
}
|
win = FindWindowEx(win, NULL, TEXT("AfxWnd140s"), NULL);
|
if (win <= 0) {
|
throw string("δ»ñÈ¡µ½²Ëµ¥¾ä±ú");
|
}
|
win = FindWindowEx(win, NULL, NULL, TEXT("HexinScrollWnd"));
|
return win;
|
}
|
|
list<TradeDelegateData> TradeListCapture::captureSimpleTradeDelegateInfo(cv::Mat img)
|
{
|
cv::Mat grayImg = grayImgs(img, openCLExcuterDelegate);
|
|
list<TradeDelegateData> dataList;
|
//·Ö¸ôÔªËØ
|
int empty_start = -1;
|
int empty_end = -1;
|
int data_start = -1;
|
int data_end = -1;
|
list<int*> rowData;
|
for (int r = 0; r < grayImg.rows; r++) {
|
if (ImgDivider::isRowEmpty(grayImg, r, 0, 100)) {
|
|
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<int*>::iterator ele = rowData.begin(); ele != rowData.end(); ele++) {
|
free(*ele);
|
}
|
return dataList;
|
}
|
|
//ȥͷȥβ
|
list<int*>::iterator start = rowData.begin();
|
list<int*>::iterator end = rowData.end();
|
int start_end = (*start)[1];
|
free(*start);
|
|
rowData.erase(start);
|
if (rowData.size() == 1)
|
{
|
std::advance(end, -1);
|
if ((*end)[0] - start_end > 30)
|
{
|
free(*end);
|
rowData.erase(end);
|
}
|
}
|
else {
|
//Èç¹û×îºóÒ»ÌõÊý¾ÝÓëµ¹ÊýµÚ¶þÌõÊý¾ÝµÄ
|
std::advance(end, -1);
|
int end_start = (*end)[0];
|
std::advance(end, -1);
|
if (end_start - (*end)[1] > 15) {
|
//ɾ³ý×îºó1ÌõÊý¾Ý
|
std::advance(end, 1);
|
free(*end);
|
rowData.erase(end);
|
}
|
}
|
|
int* rowIndex = (int*)malloc(sizeof(int) * rowData.size() * 4);
|
|
int index = 0;
|
for (list<int*>::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 = 8;
|
int length_per_num = 9;
|
|
|
int* splitResult = (int*)malloc(sizeof(int) * 4 * ele_count_per_line * rowData.size());
|
|
openCLExcuterDelegate->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 0, 7, 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<uchar>(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_NUM,NUM_TYPE_CODE,NUM_TYPE_PRICE,NUM_TYPE_PRICE,NUM_TYPE_CODE, NUM_TYPE_CODE };
|
typesData.length = ele_count_per_line;
|
typesData.data = types;
|
|
openCLExcuterDelegate->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);
|
openCLExcuterDelegate->createNumberTemplates(rowData.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums);
|
uchar** numberResult = openCLExcuterDelegate->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 apply_time = "";
|
for (int j = length_per_num - 9; j < length_per_num; j++)
|
{
|
apply_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 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 * 4 + 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 * 5 + 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 * 6 + j]));
|
}
|
success_num = to_string(stoi(success_num));
|
|
|
//ÂòÈëÂô³ö
|
int start = i * 4 * ele_count_per_line + 7 * 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<uchar>(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.apply_time = apply_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<TradeDelegateData> TradeListCapture::captureSimpleTradeDelegateInfo()
|
{
|
|
HWND win = THSActionUtil::getTradeSimpleDelegateWindow();
|
//Ë¢ÐÂÊý¾Ý,°´F5Ë¢ÐÂ
|
Win32Util::virtualKeyboard(win, VK_F5);
|
|
cv::Mat oimg = CaptureUtil::capture(trade_simple_delegate_win);
|
if (oimg.cols < 10 || oimg.rows < 10) {
|
throw string("½ØÍ¼³ö´í");
|
}
|
|
list<TradeDelegateData> codes = captureSimpleTradeDelegateInfo(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;
|
}
|
|
string TradeListCapture::getSimpleAvaiableMoney()
|
{
|
HWND hwnd = THSActionUtil::getTradeSimpleDelegateWindow();
|
if (hwnd <= 0) {
|
throw string("ίÍд°¿Úδ´ò¿ª");
|
}
|
HWND win = FindWindowExA(hwnd, NULL, "AfxMDIFrame140s", NULL);
|
HWND child = NULL;
|
HWND avaiableMoneyHWND = 0;
|
for (int i = 0; i < 5; i++) {
|
child = FindWindowExA(win, child, "#32770", NULL);
|
if (child > 0 && Win32Util::isWindowShow(child)) {
|
HWND table = FindWindowExA(child, NULL, NULL, "HexinScrollWnd");
|
if (table > 0) {
|
child = FindWindowExA(child, NULL, "#32770", NULL);
|
avaiableMoneyHWND = GetDlgItem(child, 0x000003F8);
|
break;
|
}
|
}
|
}
|
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;
|
}
|