admin
2022-08-02 c699b06ff750003b81315009e80617041748d799
'完善'
2个文件已删除
18个文件已修改
4个文件已添加
1968 ■■■■ 已修改文件
ConsoleApplication/ConsoleApplication.vcxproj 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/ConsoleApplication.vcxproj.filters 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/OpenCLExcuter.cpp 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/OpenCLExcuter.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSActionUtil.cpp 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSActionUtil.h 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSGPDataCapture.cpp 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/THSGPDataCapture.h 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeListCapture.cpp 743 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeListCapture.h 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeSuccessCapture.cpp 346 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/TradeSuccessCapture.h 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/kernel.cl 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/main.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/win32_screen_shots.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/JsonUtil.h 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/app.aps 补丁 | 查看 | 原始文档 | blame | 历史
app/app.rc 补丁 | 查看 | 原始文档 | blame | 历史
app/appDlg.cpp 187 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/appDlg.h 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/codesDataDlog.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/codesDataDlog.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/loginDlg.cpp 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/resource.h 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ConsoleApplication/ConsoleApplication.vcxproj
@@ -143,8 +143,9 @@
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="THSGPDataCapture.cpp" />
    <ClCompile Include="TradeQueueCapture.cpp" />
    <ClCompile Include="TradeSuccessCapture.cpp" />
    <ClCompile Include="TradeListCapture.cpp" />
    <ClCompile Include="CaptureUtil.cpp" />
    <ClCompile Include="IndustryCapture.cpp" />
    <ClCompile Include="LimitUpCapture.cpp" />
@@ -162,8 +163,9 @@
    <ClCompile Include="win32_screen_shots.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="THSGPDataCapture.h" />
    <ClInclude Include="TradeQueueCapture.h" />
    <ClInclude Include="TradeSuccessCapture.h" />
    <ClInclude Include="TradeListCapture.h" />
    <ClInclude Include="CaptureUtil.h" />
    <ClInclude Include="error.h" />
    <ClInclude Include="ImgDivider.h" />
ConsoleApplication/ConsoleApplication.vcxproj.filters
@@ -60,10 +60,13 @@
    <ClCompile Include="IndustryCapture.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="TradeSuccessCapture.cpp">
    <ClCompile Include="TradeQueueCapture.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="TradeQueueCapture.cpp">
    <ClCompile Include="TradeListCapture.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
    <ClCompile Include="THSGPDataCapture.cpp">
      <Filter>源文件</Filter>
    </ClCompile>
  </ItemGroup>
@@ -113,10 +116,13 @@
    <ClInclude Include="IndustryCapture.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="TradeSuccessCapture.h">
    <ClInclude Include="TradeQueueCapture.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="TradeQueueCapture.h">
    <ClInclude Include="TradeListCapture.h">
      <Filter>头文件</Filter>
    </ClInclude>
    <ClInclude Include="THSGPDataCapture.h">
      <Filter>头文件</Filter>
    </ClInclude>
  </ItemGroup>
ConsoleApplication/OpenCLExcuter.cpp
@@ -7,9 +7,18 @@
        throw string("Get platform failed!");
    }
    //获取设备
    error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_GPU, 1, &devices, NULL);
    //error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_GPU, 1, &devices, NULL);
    //if (error != 0) {
    //    error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_CPU, 1, &devices, NULL);
    //    if (error != 0) {
    //        throw string("Get device failed!");
    //    }
    //}
    error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_CPU, 1, &devices, NULL);
    if (error != 0) {
        error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_CPU, 1, &devices, NULL);
        error = clGetDeviceIDs(platforms, CL_DEVICE_TYPE_GPU, 1, &devices, NULL);
        if (error != 0) {
            throw string("Get device failed!");
        }
ConsoleApplication/OpenCLExcuter.h
@@ -10,6 +10,7 @@
    NUM_TYPE_MONEY,
    NUM_TYPE_PRICE,
    NUM_TYPE_CODE,
    NUM_TYPE_NUM,
};
ConsoleApplication/THSActionUtil.cpp
@@ -73,7 +73,7 @@
    return 0;
}
HWND THSActionUtil::getTradeWindow() {
HWND THSActionUtil::getTradeDelegateWindow() {
    list<HWND> wlist = Win32Util::searchWindow("专业版下单");
    list<HWND>::iterator ele;
    for (ele = wlist.begin();ele != wlist.end();ele++) {
@@ -84,6 +84,16 @@
}
HWND THSActionUtil::getTradeSuccessWindow() {
    list<HWND> wlist = Win32Util::searchWindow("网上股票交易系统");
    list<HWND>::iterator ele;
    for (ele = wlist.begin();ele != wlist.end();ele++) {
        HWND hwnd = *ele;
        return hwnd;
    }
    return 0;
}
ConsoleApplication/THSActionUtil.h
@@ -47,7 +47,9 @@
    static HWND getIndustryWindow();
    //交易句柄
    static HWND getTradeWindow();
    static HWND getTradeSuccessWindow();
    static HWND getTradeDelegateWindow();
    //检测环境
ConsoleApplication/THSGPDataCapture.cpp
New file
@@ -0,0 +1,268 @@
#include "THSGPDataCapture.h"
#include <set>
#include "Win32Util.h"
OpenCLExcuter* THSGPDataCapture::openCLExcuter;
bool THSGPDataCapture::inited;
RecognitionManager* THSGPDataCapture::recognitionManager;
cv::Mat THSGPDataCapture::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->rgb2Gray(oimg.data, oimg.cols, oimg.rows, imgData);
    }
    else {
        openCLExcuter->rgba2Gray(oimg.data, oimg.cols, oimg.rows, imgData);
    }
    grayImg.data = imgData;
    return grayImg;
}
void THSGPDataCapture::init() {
    recognitionManager = new RecognitionManager();
    openCLExcuter = new OpenCLExcuter();
    openCLExcuter->init();
}
list<list<GPDataStruct>> THSGPDataCapture::captureGPData(cv::Mat grayImg, SplitType types[], int length_per_num) {
    list<int*> rowData = THSActionUtil::splitPlateRowArea(grayImg);
    //每行的元素个数
    int ele_count_per_line = sizeof(types) / sizeof(types[0]);
    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<int*>::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 * length_per_num;
    openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 1, 2, splitResult);
    //分割数字
    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];
        }
    }
    unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * rowData.size()) * _NUMBER_GP_CODE_WIDTH * 10 * line_number_count);
    uchar* types_char = (uchar*)malloc(sizeof(uchar) * ele_count_per_line);
    for (int i = 0;i < ele_count_per_line;i++) {
        types_char[i] = types[i];
    }
    UcharDataInfo typesData = UcharDataInfo();
    typesData.length = 2;
    typesData.data = types_char;
    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, length_per_num);
    free(types_char);
    //识别数字
    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);
    list<list<GPDataStruct>> dataList;
    //解析数据,GPDataStruct
    for (int i = 0;i < rowData.size();i++) {
        list<GPDataStruct> lineData;
        for (int p = 0;p < ele_count_per_line;p++) {
            GPDataStruct industryData = GPDataStruct();
            switch (types[p]) {
            case NUM_TYPE_TIME: {
                //时间
                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 * p + j]));
                }
                industryData.type = NUM_TYPE_TIME;
                industryData.content = time;
            }break;
            case NUM_TYPE_MONEY: {
                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 * p + j]));
                }
                char* priceCode;
                priceCode = new char[20];
                sprintf_s(priceCode, money.length(), "%.2lf", stod(money));
                std::string _str(priceCode);
                money = _str;
                industryData.type = NUM_TYPE_MONEY;
                industryData.content = money;
            }break;
            case NUM_TYPE_PRICE:
            {
                string price = "";
                for (int j = 0;j < length_per_num;j++)
                {
                    if (j == length_per_num - 2) {
                        price.append(".");
                    }
                    price.append(to_string(numberResult[i][length_per_num * p + j]));
                }
                char* priceCode;
                priceCode = new char[20];
                sprintf_s(priceCode, price.length(), "%.2lf", stod(price));
                std::string _str(priceCode);
                price = _str;
                industryData.type = NUM_TYPE_PRICE;
                industryData.content = price;
            }
            break;
            case NUM_TYPE_CODE: {
                //股票代码
                string code = "";
                for (int j = length_per_num - 6;j < length_per_num;j++)
                {
                    code.append(to_string(numberResult[i][length_per_num * p + j]));
                }
                industryData.type = NUM_TYPE_CODE;
                industryData.content = code;
            }
                              break;
            case NUM_TYPE_NUM:
                //数字
                string num = "";
                for (int j = 0;j < length_per_num;j++)
                {
                    num.append(to_string(numberResult[i][length_per_num * p + j]));
                }
                num = to_string(stoi(num));
                industryData.type = NUM_TYPE_NUM;
                industryData.content = num;
                break;
            }
            lineData.push_back(industryData);
        }
        free(numberResult[i]);
        dataList.push_back(lineData);
    }
    free(numberResult);
    list<int> moneyIndexs;
    for (int p = 0;p < ele_count_per_line;p++) {
        if (types[p] == NUM_TYPE_MONEY) {
            moneyIndexs.push_back(p);
        }
    }
    if (moneyIndexs.size() > 0)
    {
        int* unitData = (int*)malloc(sizeof(int) * 4 * moneyIndexs.size() * rowData.size());
        //识别金额单位
        int line = 0;
        for (list<list<GPDataStruct>>::iterator ele = dataList.begin();ele != dataList.end();ele++) {
            int index = 0;
            for (list<int>::iterator e = moneyIndexs.begin();e != moneyIndexs.end();e++) {
                int start_index = (line * moneyIndexs.size() + index) * 4;
                unitData[start_index + 0] = splitResult[line * 4 * ele_count_per_line + *e * 4 + 0];
                unitData[start_index + 1] = splitResult[line * 4 * ele_count_per_line + *e * 4 + 1];
                unitData[start_index + 2] = splitResult[line * 4 * ele_count_per_line + *e * 4 + 2];
                unitData[start_index + 3] = splitResult[line * 4 * ele_count_per_line + *e * 4 + 3];
                string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
                path.append(to_string(line)).append("_1.jpg");
                //cv::imwrite(path, cv::Mat(grayImg,cv::Rect(unitData[start_index + 0], unitData[start_index + 1], unitData[start_index + 2]- unitData[start_index + 0]+1, unitData[start_index + 3]- unitData[start_index + 1]+1)));
                index++;
            }
            line++;
        }
        int* unitResult = (int*)malloc(sizeof(int) * moneyIndexs.size() * dataList.size());
        openCLExcuter->recognitionPlateMoneyUnit(grayImg.data, grayImg.cols, grayImg.rows, unitData, moneyIndexs.size(), dataList.size(), unitResult);
        int index = 0;
        for (list<list<GPDataStruct>>::iterator ele = dataList.begin();ele != dataList.end();ele++) {
            int data_index = index * moneyIndexs.size();
            int cIndex = 0;
            for (list<GPDataStruct>::iterator e = (*ele).begin();e != (*ele).end();e++) {
                if ((*e).type == NUM_TYPE_MONEY) {
                    switch (unitResult[data_index + cIndex])
                    {
                    case 0:
                        (*e).unit = MONEY_UNIT_Y;
                        break;
                    case 1:
                        (*e).unit = MONEY_UNIT_W;
                        break;
                    default:
                        break;
                    }
                    cIndex++;
                }
            }
            index++;
        }
        free(unitData);
        free(unitResult);
    }
    free(rowIndex);
    free(splitResult);
    free(zeroData);
    free(totalNumberData);
    free(templateNums);
    free(grayImg.data);
    grayImg.release();
    return dataList;
}
bool THSGPDataCapture::isInited() {
    return inited;
}
ConsoleApplication/THSGPDataCapture.h
New file
@@ -0,0 +1,41 @@
#pragma once
#include <string>
#include <iostream>
#include <list>
#include "ImgUtil.h"
#include "RecognitionManager.h"
#include "THSActionUtil.h"
struct GPDataStruct
{
    //
    SplitType type;
    string content;
    MoneyUnit unit;
};
class THSGPDataCapture
{
private:
    static OpenCLExcuter* openCLExcuter;
    static RecognitionManager* recognitionManager;
    static bool inited;
public:
    void init();
    static list<list<GPDataStruct>> captureGPData(cv::Mat grayImg, SplitType types[], int length_per_num);
    static cv::Mat grayImgs(cv::Mat img);
    bool isInited();
    void stop();
};
ConsoleApplication/TradeListCapture.cpp
New file
@@ -0,0 +1,743 @@
#include "TradeListCapture.h"
#include <set>
#include "Win32Util.h"
OpenCLExcuter* TradeListCapture::openCLExcuter;
bool TradeListCapture::inited;
HWND TradeListCapture::trade_delegate_win;
HWND TradeListCapture::trade_success_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) {
        //1s一次
        if (running_s && inited) {
            clock_t start = clock();
            list<TradeSuccessData> datas = captureTradeSuccessInfo();
            cout << "耗时:" << clock() - start << "  数量:" << datas.size() << endl;
            data_callback_success(datas, context);
            datas.clear();
            Sleep(500);
        }
        else {
            Sleep(2000);
        }
    }
}
void TradeListCapture::_run_d() {
    while (true) {
        //1s一次
        if (running_d && inited) {
            clock_t start = clock();
            list<TradeDelegateData> datas = captureTradeDelegateInfo();
            string money = getAvaiableMoney();
            cout << "耗时:" << clock() - start << "  数量:" << datas.size() << endl;
            data_callback_delegate(datas, money, context);
            datas.clear();
            Sleep(100);
        }
        else {
            Sleep(2000);
        }
    }
}
cv::Mat TradeListCapture::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 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();
    openCLExcuter = new OpenCLExcuter();
    openCLExcuter->init();
    thread rt(&(TradeListCapture::_run_s));
    rt.detach();
    thread rt1(&(TradeListCapture::_run_d));
    rt1.detach();
    inited = true;
    try {
        refreshTradeSuccessHWND();
    }
    catch (...) {
    }
    try {
        refreshTradeDelegateHWND();
    }
    catch (...) {
    }
}
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::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);
    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)
    {
        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());
    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<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;
    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 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);
        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);
        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(numberResult);
    free(rowIndex);
    free(splitResult);
    free(zeroData);
    free(templateNums);
    free(grayImg.data);
    grayImg.release();
    return dataList;
}
list<TradeSuccessData> TradeListCapture::captureTradeSuccessInfo() {
    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);
    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, 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)
    {
        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());
    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<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;
    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++) {
        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(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;
}
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;
}
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;
}
ConsoleApplication/TradeListCapture.h
New file
@@ -0,0 +1,109 @@
#pragma once
#include <string>
#include <iostream>
#include <list>
#include "ImgUtil.h"
#include "RecognitionManager.h"
#include "THSActionUtil.h"
enum TradeType
{
    TRADE_TYPE_BUY,
    TRADE_TYPE_SELL,
};
struct TradeSuccessData
{
    string code;
    string time;
    string num;
    string money;
    string price;
    string trade_num;
    TradeType type;
    //辅助功能
    int index;
};
struct TradeDelegateData
{
    string code;
    string time;
    string num;
    string price;
    string trade_price;
    string trade_num;
    TradeType type;
    //辅助功能
    int index;
};
typedef void (*CallbackFun_Trade_Success)(list<TradeSuccessData> dataList, void* contex);
typedef void (*CallbackFun_Trade_Delegate)(list<TradeDelegateData> dataList,string avaiableMoney, void* contex);
class TradeListCapture
{
private:
    static OpenCLExcuter* openCLExcuter;
    static RecognitionManager* recognitionManager;
    static bool inited;
    //是否正在执行
    static bool running_s;
    static bool running_d;
    static CallbackFun_Trade_Success data_callback_success;
    static CallbackFun_Trade_Delegate data_callback_delegate;
    static void* context;
    static void _run_s();
    static void _run_d();
    //委托窗体
    static HWND trade_delegate_win;
    //成功窗体
    static HWND trade_success_win;
public:
    void init(CallbackFun_Trade_Success callback_s, CallbackFun_Trade_Delegate callback_d, void* context);
    void refreshTradeDelegateHWND();
    void refreshTradeSuccessHWND();
    static cv::Mat grayImgs(cv::Mat img);
    //交易成功
    static list<TradeSuccessData> captureTradeSuccessInfo(cv::Mat img);
    static list<TradeSuccessData> captureTradeSuccessInfo();
    //交易委托
    static list<TradeDelegateData> captureTradeDelegateInfo(cv::Mat img);
    static list<TradeDelegateData> captureTradeDelegateInfo();
    //获取账户的剩余资金
    static string getAvaiableMoney();
    bool isInited();
    bool isRunningTradeSuccess();
    bool isRunningTradeDelegate();
    //开始
    void startTradeSuccess();
    //结束
    void stopTradeSuccess();
    //开始
    void startTradeDelegate();
    //结束
    void stopTradeDelegate();
};
ConsoleApplication/TradeSuccessCapture.cpp
File was deleted
ConsoleApplication/TradeSuccessCapture.h
File was deleted
ConsoleApplication/kernel.cl
@@ -51,7 +51,7 @@
}
//分隔板块数字
__kernel void split_plate_num(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, __global const unsigned char* types, int width, int num_width, int num_height, int ele_count_per_line,int length_per_num,
__kernel void split_plate_num(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, __global const unsigned char* types, int width, int num_width, int num_height, int ele_count_per_line, int length_per_num,
    __global unsigned char* result) {
    int index = get_global_id(0);
@@ -142,7 +142,7 @@
            temp[8] = get_binary_value(img_in[get_one_level_position(width, startx + i - 2, endy - 2)]);
            temp[9] = get_binary_value(img_in[get_one_level_position(width, startx + i - 3, endy - 2)]);
            if (temp[3] > 0 && temp[2] > 0 && temp[6] > 0 && temp[7] > 0) {
                int t = temp[0] + temp[1] + temp[4] + temp[5]+ temp[8]+ temp[9];
                int t = temp[0] + temp[1] + temp[4] + temp[5] + temp[8] + temp[9];
                if (t == 0) {
                    m1_s = i - 5;
                    m1_e = i;
@@ -170,7 +170,7 @@
            temp[8] = get_binary_value(img_in[get_one_level_position(width, startx + i + 2, endy - 2)]);
            temp[9] = get_binary_value(img_in[get_one_level_position(width, startx + i + 3, endy - 2)]);
            if (temp[2] > 0 && temp[3] > 0 && temp[6] > 0 && temp[7] > 0) {
                int t = temp[0] + temp[1] + temp[4] + temp[5]+ temp[8] + temp[9];
                int t = temp[0] + temp[1] + temp[4] + temp[5] + temp[8] + temp[9];
                if (t == 0) {
                    m2_s = i;
                    m2_e = i + 5;
@@ -194,7 +194,8 @@
            nps[9] = -1;
            nps[10] = -1;
            nps[11] = -1;
        }else {
        }
        else {
            //3个时间的坐标
            nps[0] = startx;
            nps[1] = starty;
@@ -334,7 +335,8 @@
            nps[5] = -1;
            nps[6] = -1;
            nps[7] = -1;
        }else {
        }
        else {
            nps[0] = startx;
            nps[1] = starty;
            nps[2] = startx + m_s - 1;
@@ -347,7 +349,7 @@
        }
    }
@@ -429,8 +431,8 @@
        }
    }
    //代码
    else if (type == 3) {
    //代码与数字
    else if (type == 3 || type == 4) {
        //手数
        nps[0] = startx;
        nps[1] = starty;
@@ -452,7 +454,7 @@
    //最大分割20个数
    int numCount = 0;
    //记录分割得到的数据
    int  numberCols[20*2];
    int  numberCols[20 * 2];
    int i;
    for (i = 0;i < 3;i++) {
@@ -566,7 +568,7 @@
                int index_1 = r * (num_width * 10 * num_count);
                for (int c = 0;c < num_width;c++) {
                    int findex = index_0 + index_1 + index_2 + index_3 + c;
                        //printf("index:%d-findex:%d value:%d \n", index, findex, numData[r * num_width + c]);
                    //printf("index:%d-findex:%d value:%d \n", index, findex, numData[r * num_width + c]);
                    result[findex] = numData[r * num_width + c];
                }
            }
@@ -950,8 +952,8 @@
        }
    }
    //代码
    else if (type == 3) {
    //代码与数字
    else if (type == 3 || type == 4) {
        //手数
        nps[0] = startx;
        nps[1] = starty;
@@ -973,7 +975,7 @@
    //最大分割20个数
    int numCount = 0;
    //记录分割得到的数据
    int  numberCols[20*2];
    int  numberCols[20 * 2];
    int i;
    for (i = 0;i < 3;i++) {
@@ -2064,7 +2066,7 @@
    __global int* result) {
    int index = get_global_id(0);
    int start = index * 4;
    int startx = rowIndexs[start+0];
    int startx = rowIndexs[start + 0];
    int starty = rowIndexs[start + 1];
    int endx = rowIndexs[start + 2];
    int endy = rowIndexs[start + 3];
@@ -2080,15 +2082,20 @@
            }
        }
        if (empty) {
            unit_start = i+1;
            unit_start = i + 1;
            break;
        }
    }
    //printf("index:%d unit_start:%d\n", index, unit_start);
    int count = 0;
    for (int c = unit_start;c <= endx;c++) {
        for (int y = starty;y <= endy;y++) {
            count+=(get_binary_value(imgs[get_one_level_position(width, c, y)]) > 0 ? 1 : 0);
    if (unit_start > -1)
    {
        for (int c = unit_start;c <= endx;c++) {
            for (int y = starty;y <= endy;y++) {
                count += (get_binary_value(imgs[get_one_level_position(width, c, y)]) > 0 ? 1 : 0);
            }
        }
    }
    if (count >= 48) {
ConsoleApplication/main.cpp
@@ -4,7 +4,7 @@
#include "Win32Util.h"
#include "LimitUpCapture.h"
#include "IndustryCapture.h"
#include "TradeSuccessCapture.h"
#include "TradeListCapture.h"
void gray();
void ths();
/*
@@ -117,6 +117,9 @@
    
}
void onTradeListCallBack(list<TradeSuccessData> dataList, void* contex) {
}
int main() {
    cout << "开始程序" << endl;
@@ -127,13 +130,15 @@
    //Win32Util::keyboardNum("000333", 10);
    ImgUtil::init();
    cv::Mat img = CaptureUtil::capture(HWND(0x00020E12));
    BuySuccessCapture* buySuccessCapture = new BuySuccessCapture();
    //buySuccessCapture->init(Null,Null);
    buySuccessCapture->captureTradeSuccessInfo();
    //cv::Mat grayImg = buySuccessCapture->grayImgs(cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\order_origin.jpg"));
    TradeListCapture* tradeListCapture = new TradeListCapture();
    tradeListCapture->init(NULL,NULL,NULL);
    tradeListCapture->refreshTradeDelegateHWND();
    //cv::Mat img= tradeListCapture->grayImgs(CaptureUtil::capture(HWND(0x00055B0E)));
    //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\trade\\gray_1.png",img);
    list<TradeDelegateData> dataList = tradeListCapture->captureTradeDelegateInfo();
    return 0;
    ImgUtil::init();
@@ -145,7 +150,7 @@
    //industryCapture->init();
    cout << "LimitUpCapture初始化完成" << endl;
        industryCapture->captureIndustryCodes();
    list<list<IndustryData>> datas=    industryCapture->captureIndustryCodes();
    
    delete industryCapture;
ConsoleApplication/win32_screen_shots.cpp
@@ -22,14 +22,8 @@
            if (GetWindowRect(h, &rect) == FALSE)
                break;
            if (rect.left < 0)
                rect.left = 0;
            if (rect.top < 0)
                rect.top = 0;
            width = rect.right - rect.left;
            height = rect.bottom - rect.top;
            width = abs( rect.right - rect.left);
            height =abs( rect.bottom - rect.top);
            hdc = GetWindowDC(h);
            if (hdc == nullptr)
app/JsonUtil.h
@@ -4,7 +4,7 @@
#include "json/json.h"
#include <THSActionUtil.h>
#include "LimitUpCapture.h"
#include "TradeSuccessCapture.h"
#include "TradeListCapture.h"
#include "IndustryCapture.h"
class JsonUtil {
@@ -125,13 +125,41 @@
        int index = 0;
        for (ele = dataList.begin();ele != dataList.end();ele++) {
            Json::Value  item;
            item["date"] = (*ele).date;
            item["price"] = (*ele).price;
            item["code"] = (*ele).code;
            item["time"] = (*ele).time;
            item["num"] = (*ele).num;
            item["money"] = (*ele).money;
            item["trade_num"] = (*ele).trade_num;
            item["type"] = (*ele).type;
            data[index++] = item;
        }
        root["data"] = data;
        return toJsonStr(root);
    }
    static  std::string loadTradeDelegateData(list<TradeDelegateData>  dataList) {
        Json::Value root;
        root["type"] = 5;
        Json::Value data;
        std::list<TradeDelegateData>::iterator ele;
        int index = 0;
        for (ele = dataList.begin();ele != dataList.end();ele++) {
            Json::Value  item;
            item["code"] = (*ele).code;
            item["time"] = (*ele).time;
            item["num"] = (*ele).num;
            item["type"] = (*ele).type;
            item["price"] = (*ele).price;
            item["trade_price"] = (*ele).trade_price;
            item["trade_num"] = (*ele).trade_num;
            data[index++] = item;
        }
@@ -171,19 +199,33 @@
    }
    static  std::string loadGPCodeData(std::list<string> codeList) {
    static  std::string loadGPCodeData(std::list<IndustryData> codeList) {
        Json::Value root;
        root["type"] = 1;
        Json::Value data;
        std::list<string>::iterator ele;
        std::list<IndustryData>::iterator ele;
        int index = 0;
        for (ele = codeList.begin();ele != codeList.end();ele++) {
            data[index++] = *ele;
            Json::Value item;
            item["code"] = (*ele).code;
            item["zyltgb"] = (*ele).zyltMoney;
            item["zyltgb_unit"] = (*ele).zyltMoneyUnit;
            data[index++] = item;
        }
        root["data"] = data;
        return toJsonStr(root);
    }
    static  std::string loadHeartbeatData(int client) {
        Json::Value root;
        root["type"] = 30;
        Json::Value data;
        data["client"] = client;
        root["data"] = data;
        return toJsonStr(root);
    }
    static  std::string loadLoginData(string account,string pwd) {
@@ -197,11 +239,14 @@
    }
    static  std::string loadHeartbeatData(int client) {
    static  std::string loadAvailableMoney(int client,string money) {
        Json::Value root;
        root["type"] = 30;
        root["type"] = 6;
        Json::Value data;
        data["client"] = client;
        data["money"] = money;
        root["data"] = data;
        return toJsonStr(root);
    }
app/app.aps
Binary files differ
app/app.rc
Binary files differ
app/appDlg.cpp
@@ -82,8 +82,9 @@
    capture = new  L2DataCapture();
    recognitionManager = new RecognitionManager();
    limitUpCapture = new LimitUpCapture();
    buySuccessCapture = new BuySuccessCapture();
    tradeListCapture = new TradeListCapture();
    industryCapture = new IndustryCapture();
    gpDataCapture = new THSGPDataCapture();
}
void CappDlg::DoDataExchange(CDataExchange* pDX)
@@ -95,6 +96,7 @@
    DDX_Control(pDX, IDC_INDUSTRY, industryBtn);
    DDX_Control(pDX, IDC_BUTTON5, btnL2);
    DDX_Control(pDX, IDC_BUTTON8, uploadGPBtn);
    DDX_Control(pDX, IDC_BUTTON_TRADE_DELEGATE, delegateBtn);
}
BEGIN_MESSAGE_MAP(CappDlg, CDialogEx)
@@ -112,6 +114,7 @@
    ON_BN_CLICKED(IDC_BUTTON12, &CappDlg::OnBnClickedButton12)
    ON_BN_CLICKED(IDC_BUTTON_TRADE, &CappDlg::OnBnClickedButtonTrade)
    ON_BN_CLICKED(IDC_INDUSTRY, &CappDlg::OnBnClickedIndustry)
    ON_BN_CLICKED(IDC_BUTTON_TRADE_DELEGATE, &CappDlg::OnBnClickedButtonTradeDelegate)
END_MESSAGE_MAP()
@@ -150,6 +153,7 @@
    ((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(TRUE);
    ((CButton*)GetDlgItem(IDC_CHECK2))->SetCheck(TRUE);
    ((CButton*)GetDlgItem(IDC_CHECK3))->SetCheck(TRUE);
    ((CButton*)GetDlgItem(IDC_CHECK4))->SetCheck(TRUE);
    if (authoritySet.count(AUTHORITY_L2) > 0) {
@@ -173,9 +177,20 @@
        tradeBtn.EnableWindow(FALSE);
    }
    if (authoritySet.count(AUTHORITY_TRADE_DELEGATE) > 0) {
        delegateBtn.EnableWindow(TRUE);
    }
    else {
        delegateBtn.EnableWindow(FALSE);
    }
    if (authoritySet.count(AUTHORITY_THS_INDUSTRY) > 0) {
        industryBtn.EnableWindow(TRUE);
    }else{
    }
    else {
        industryBtn.EnableWindow(FALSE);
    }
@@ -189,7 +204,7 @@
    CString st;
    CString idStr(to_string( clientNum).c_str());
    CString idStr(to_string(clientNum).c_str());
    st.Format(_T("客户端ID:%s"), idStr);
    GetDlgItem(IDC_STATIC3)->SetWindowTextW(st);
@@ -352,6 +367,42 @@
            app->socketManager->resetClient(8);
            app->socketManager->Connect(8);
        }
        cout << "####交易成功数据处理时间:" << (clock() - time_start) << endl;
    }
}
void CappDlg::OnTradeDelegateDataCallback(list<TradeDelegateData> dataList, string money, void* context)
{
    //转为json
    CappDlg* app = (CappDlg*)context;
    //cout << "回调:" << std::this_thread::get_id() << ":" << index << endl;
    CButton* btn = (CButton*)app->GetDlgItem(IDC_CHECK4);
    bool check = btn->GetCheck();
    if (check) {
        string data = JsonUtil::loadTradeDelegateData(dataList);
        clock_t time_start = clock();
        try {
            app->socketManager->sendMsg(8, data.c_str());
        }
        catch (string st) {
            //重新连接服务器
            app->socketManager->resetClient(8);
            app->socketManager->Connect(8);
        }
        //上传账户可用余额
        data = JsonUtil::loadAvailableMoney(app->clientNum, money);
        try {
            app->socketManager->sendMsg(8, data.c_str());
        }
        catch (string st) {
            app->socketManager->resetClient(8);
            app->socketManager->Connect(8);
        }
        cout << "####交易成功数据处理时间:" << (clock() - time_start) << endl;
    }
}
@@ -588,7 +639,7 @@
    clock_t time = clock();
    CString path = GUITool::selectImage();
    std:string p = Tool::cstring2String(path);
std:string p = Tool::cstring2String(path);
    if (p.length() <= 0) {
        return;
    }
@@ -678,10 +729,11 @@
//股票代码识别
void CappDlg::OnBnClickedButton7()
{
    if (!capture->isInited())
    if (!gpDataCapture->isInited())
    {
        try {
            capture->init(OnL2DataCallback, OnTradeQueueDataCallback, this);
            gpDataCapture->init();
        }
        catch (string st) {
            CString msg(st.c_str());
@@ -690,24 +742,43 @@
        }
    }
    list<CString> paths = GUITool::selectMulImages();
    std::list<string> fResultList;
    std::list<IndustryData> fResultList;
    for (list<CString>::iterator ele = paths.begin();ele != paths.end();ele++) {
        CString path = *ele;
    std:string p = Tool::cstring2String(path);
        std::list<string> resultList = THSActionUtil::recognitionGPCode(cv::imread(p), recognitionManager);
        for (std::list<string>::iterator ele1 = resultList.begin();ele1 != resultList.end();ele1++) {
        cv::Mat grayImg = gpDataCapture->grayImgs(cv::imread(p));
        SplitType types[] = { NUM_TYPE_MONEY, NUM_TYPE_CODE };
        list<list<GPDataStruct>>  resultList = gpDataCapture->captureGPData(grayImg, types, 6);
        for (list<list<GPDataStruct>>::iterator ele1 = resultList.begin();ele1 != resultList.end();ele1++) {
            IndustryData industryData = IndustryData();
            list<GPDataStruct>::iterator e = (*ele1).begin();
            industryData.zyltMoney = (*e).content;
            industryData.zyltMoneyUnit = (*e).unit;
            advance(e, 1);
            industryData.code = (*e).content;
            if (industryData.code == "000000") {
                continue;
            }
            bool contains = false;
            for (std::list<string>::iterator e = fResultList.begin();e != fResultList.end();e++) {
                if (*e == *ele1) {
            for (std::list<IndustryData>::iterator e = fResultList.begin();e != fResultList.end();e++) {
                if ((*e).code == industryData.code) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                fResultList.push_back(*ele1);
                fResultList.push_back(industryData);
            }
        }
    }
    codesDataDlog::codeData = fResultList;
    codesDataDlog::upload = false;
@@ -718,11 +789,10 @@
//截图上传股票代码
void CappDlg::OnBnClickedButton8()
{
    //
    if (!capture->isInited())
    if (!gpDataCapture->isInited())
    {
        try {
            capture->init(OnL2DataCallback, OnTradeQueueDataCallback, this);
            gpDataCapture->init();
        }
        catch (string st) {
            CString msg(st.c_str());
@@ -731,24 +801,43 @@
        }
    }
    list<CString> paths = GUITool::selectMulImages();
    std::list<string> fResultList;
    std::list<IndustryData> fResultList;
    for (list<CString>::iterator ele = paths.begin();ele != paths.end();ele++) {
        CString path = *ele;
    std:string p = Tool::cstring2String(path);
        std::list<string> resultList = THSActionUtil::recognitionGPCode(cv::imread(p), recognitionManager);
        for (std::list<string>::iterator ele1 = resultList.begin();ele1 != resultList.end();ele1++) {
        cv::Mat grayImg = gpDataCapture->grayImgs(cv::imread(p));
        SplitType types[] = { NUM_TYPE_MONEY, NUM_TYPE_CODE };
        list<list<GPDataStruct>>  resultList = gpDataCapture->captureGPData(grayImg, types, 6);
        for (list<list<GPDataStruct>>::iterator ele1 = resultList.begin();ele1 != resultList.end();ele1++) {
            IndustryData industryData = IndustryData();
            list<GPDataStruct>::iterator e = (*ele1).begin();
            industryData.zyltMoney = (*e).content;
            industryData.zyltMoneyUnit = (*e).unit;
            advance(e, 1);
            industryData.code = (*e).content;
            if (industryData.code == "000000") {
                continue;
            }
            bool contains = false;
            for (std::list<string>::iterator e = fResultList.begin();e != fResultList.end();e++) {
                if (*e == *ele1) {
            for (std::list<IndustryData>::iterator e = fResultList.begin();e != fResultList.end();e++) {
                if ((*e).code == industryData.code) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                fResultList.push_back(*ele1);
                fResultList.push_back(industryData);
            }
        }
    }
    codesDataDlog::codeData = fResultList;
    codesDataDlog::upload = TRUE;
@@ -805,10 +894,10 @@
{
    if (!buySuccessCapture->isInited()) {
    if (!tradeListCapture->isInited()) {
        try
        {
            buySuccessCapture->init(OnTradeSuccessDataCallback, this);
            tradeListCapture->init(OnTradeSuccessDataCallback, OnTradeDelegateDataCallback, this);
        }
        catch (string st)
        {
@@ -818,14 +907,14 @@
        }
    }
    if (
        buySuccessCapture->isRunning()) {
        buySuccessCapture->stop();
        tradeListCapture->isRunningTradeSuccess()) {
        tradeListCapture->stopTradeSuccess();
        tradeBtn.SetWindowTextW(_T("启动成交识别任务"));
    }
    else {
        try
        {
            buySuccessCapture->refreshHWND();
            tradeListCapture->refreshTradeSuccessHWND();
        }
        catch (string st)
        {
@@ -834,7 +923,7 @@
            return;
        }
        buySuccessCapture->start();
        tradeListCapture->startTradeSuccess();
        tradeBtn.SetWindowTextW(_T("暂停成交识别任务"));
    }
}
@@ -878,3 +967,47 @@
        industryBtn.SetWindowTextW(_T("开始行业识别"));
    }
}
//委托识别任务
void CappDlg::OnBnClickedButtonTradeDelegate()
{
    if (!tradeListCapture->isInited()) {
        try
        {
            tradeListCapture->init(OnTradeSuccessDataCallback, OnTradeDelegateDataCallback, this);
        }
        catch (string st)
        {
            CString msg(st.c_str());
            AfxMessageBox(msg);
            return;
        }
    }
    if (
        tradeListCapture->isRunningTradeDelegate()) {
        tradeListCapture->stopTradeDelegate();
        delegateBtn.SetWindowTextW(_T("启动委托识别任务"));
    }
    else {
        try
        {
            tradeListCapture->refreshTradeDelegateHWND();
        }
        catch (string st)
        {
            CString msg(st.c_str());
            AfxMessageBox(msg);
            return;
        }
        tradeListCapture->startTradeDelegate();
        delegateBtn.SetWindowTextW(_T("暂停委托识别任务"));
    }
}
app/appDlg.h
@@ -8,8 +8,9 @@
#include "LimitUpCapture.h"
#include "CaptureUtil.h"
#include "RecognitionManager.h"
#include "TradeSuccessCapture.h"
#include "TradeListCapture.h"
#include "IndustryCapture.h"
#include "THSGPDataCapture.h"
#include "pthread.h"
#pragma comment(lib, "pthreadVC2.lib")
@@ -33,14 +34,16 @@
    SocketManager *socketManager;
    L2DataCapture* capture;
    LimitUpCapture* limitUpCapture;
    BuySuccessCapture* buySuccessCapture;
    TradeListCapture* tradeListCapture;
    IndustryCapture* industryCapture;
    THSGPDataCapture* gpDataCapture;
    void OnDataCallback(int index, list<TradeData> dataList);
    static void  OnL2DataCallback(int index,string code, list<TradeData> dataList, void* context);
    static void  OnTradeQueueDataCallback(int index, string code, list<int> numList, void* context);
    static void  OnLimitUpDataCallback(list<LimitUpData> dataList, void* context);
    static void  OnTradeSuccessDataCallback(list<TradeSuccessData> dataList, void* context);
    static void  OnTradeDelegateDataCallback(list<TradeDelegateData> dataList,string money, void* context);
    static void OnIndustryDataCallback(list<IndustryData>  dataList, void* context);
    static bool  OnActionCallback(string data, void* context);
@@ -105,4 +108,6 @@
    CButton industryBtn;
    CButton btnL2;
    CButton uploadGPBtn;
    CButton delegateBtn;
    afx_msg void OnBnClickedButtonTradeDelegate();
};
app/codesDataDlog.cpp
@@ -19,7 +19,7 @@
IMPLEMENT_DYNAMIC(codesDataDlog, CDialogEx)
std::list<string> codesDataDlog::codeData;
std::list<IndustryData> codesDataDlog::codeData;
bool  codesDataDlog::upload;
codesDataDlog::codesDataDlog(CWnd* pParent /*=nullptr*/)
@@ -77,8 +77,8 @@
    CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT2);
    string data = "";
    for (list<string>::iterator ele = codeData.begin();ele != codeData.end();ele++) {
        data.append(*ele).append("\r\n");
    for (list<IndustryData>::iterator ele = codeData.begin();ele != codeData.end();ele++) {
        data.append((*ele).code).append(" ").append((*ele).zyltMoney).append( (*ele).zyltMoneyUnit== MONEY_UNIT_Y?"亿":"万").append("\r\n");
    }
    CString cdata(data.c_str());
app/codesDataDlog.h
@@ -1,5 +1,6 @@
#pragma once
#include "L2DataCapture.h"
#include "IndustryCapture.h"
// codesDataDlog 对话框
@@ -9,7 +10,7 @@
    DECLARE_DYNAMIC(codesDataDlog)
public:
    static std::list<string> codeData;
    static std::list<IndustryData> codeData;
    static bool upload;
public:
app/loginDlg.cpp
@@ -104,6 +104,9 @@
            else if (authority._Equal("trade_delegate")) {
                alist.insert(AUTHORITY_TRADE_DELEGATE);
            }
            else if (authority._Equal("code_upload")) {
                alist.insert(AUTHORITY_UPLOAD_CODE);
            }
        }
        //赋值权限
        CappDlg::authoritySet = alist;
app/resource.h
@@ -20,7 +20,6 @@
#define IDC_CHECK1                      1010
#define IDC_BUTTON10                    1011
#define IDC_LIST1                       1012
#define IDC_BUTTON11                    1012
#define IDC_BUTTON1                     1013
#define IDC_BUTTON20                    1014
#define IDC_STATIC3                     1016
@@ -34,6 +33,8 @@
#define IDC_EDIT_PWD                    1026
#define IDC_EDIT_ACCOUNT                1027
#define IDC_BUTTON_LOGIN                1028
#define IDC_CHECK4                      1029
#define IDC_BUTTON_TRADE_DELEGATE       1030
// Next default values for new objects
// 
@@ -41,7 +42,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        136
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1029
#define _APS_NEXT_CONTROL_VALUE         1031
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif