| | |
| | | #include "CaptureUtil.h" |
| | | |
| | | HWND CaptureUtil::frames[8]; |
| | | HWND CaptureUtil::level2Frames[8]; |
| | | std::list<FrameInfo> CaptureUtil::tempFrames; |
| | | |
| | | BOOL CALLBACK CaptureUtil::EnumChildProc(HWND hwndChild, LPARAM lParam) { |
| | |
| | | if (string(className) == "AfxWnd100s") { |
| | | RECT rect; |
| | | GetWindowRect(hwndChild, &rect); |
| | | bool show= IsWindowVisible(hwndChild); |
| | | |
| | | if (rect.right - rect.left < 1000&& rect.right - rect.left>400) |
| | | if (show&&rect.right - rect.left < 1000&& rect.right - rect.left>400) |
| | | { |
| | | FrameInfo info = FrameInfo(); |
| | | info.frame = hwndChild; |
| | |
| | | } |
| | | return TRUE; |
| | | } |
| | | void CaptureUtil::init(std::string winName) { |
| | | void CaptureUtil::init(HWND l2win) { |
| | | tempFrames.clear(); |
| | | HWND root = FindWindowA(NULL, winName.c_str()); |
| | | HWND root = l2win; |
| | | |
| | | root = FindWindowEx(root, NULL, TEXT("AfxFrameOrView100s"), NULL); |
| | | |
| | | EnumChildWindows(root, EnumChildProc, NULL); |
| | | |
| | | //TODO list排序 |
| | | |
| | | |
| | | |
| | | //赋值 |
| | | std::list<FrameInfo>::iterator ele; |
| | | int index = 0; |
| | |
| | | if (index > 7) { |
| | | break; |
| | | } |
| | | frames[index++] = (*ele).frame; |
| | | level2Frames[index++] = (*ele).frame; |
| | | } |
| | | } |
| | | HWND CaptureUtil::getHWND(int index) { |
| | | return frames[index]; |
| | | return level2Frames[index]; |
| | | } |
| | | |
| | | cv::Mat CaptureUtil::capture(int index) { |
| | |
| | | { |
| | | private: |
| | | static std::list<FrameInfo> tempFrames; |
| | | static HWND frames[8]; |
| | | static HWND level2Frames[8]; |
| | | static BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam); |
| | | static HWND getHWND(int index); |
| | | |
| | | public: |
| | | //初始化 |
| | | static void init(std::string winName); |
| | | static void init(HWND l2win); |
| | | |
| | | //截图 |
| | | static cv::Mat capture(int index); |
| | |
| | | <CharacterSet>Unicode</CharacterSet> |
| | | </PropertyGroup> |
| | | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> |
| | | <ConfigurationType>Application</ConfigurationType> |
| | | <ConfigurationType>StaticLibrary</ConfigurationType> |
| | | <UseDebugLibraries>true</UseDebugLibraries> |
| | | <PlatformToolset>v142</PlatformToolset> |
| | | <CharacterSet>Unicode</CharacterSet> |
| | |
| | | return true; |
| | | } |
| | | |
| | | bool ImgDivider::isRowFull(cv::Mat img, int row, int startCol, int endCol, int simple,int splitColorFrom, int splitColorTo) { |
| | | int emptyCount = 0; |
| | | for (int i = startCol;i <= endCol;i += simple) { |
| | | uchar data = img.ptr<uchar>(row)[i]; |
| | | if (data > splitColorTo|| data< splitColorFrom) { |
| | | //允许最大有10个空数据 |
| | | if (emptyCount < 10) { |
| | | emptyCount++; |
| | | continue; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | bool ImgDivider::isRowEmpty(cv::Mat img, int row) { |
| | | int cols = img.cols; |
| | | for (int i = 0;i < cols;i += 1) { |
| | |
| | | |
| | | static bool isRowFull(cv::Mat img, int row,int startCol,int endCol, int simple); |
| | | |
| | | |
| | | static bool isRowFull(cv::Mat img, int row, int startCol, int endCol, int simple, int splitColorFrom, int splitColorTo); |
| | | |
| | | //空数据行 |
| | | static bool isRowEmpty(cv::Mat img, int row, int startCol, int endCol); |
| | | |
| | |
| | | } |
| | | return nums; |
| | | } |
| | | //分隔整数 |
| | | list<cv::Mat> ImgUtil::splitNum(cv::Mat src) throw(string) { |
| | | |
| | | list<cv::Mat> ImgUtil::splitNum(cv::Mat src,int threshold_value) throw(string) { |
| | | cv::Mat binary; |
| | | //去除上下的空白图 |
| | | threshold(src, binary, _IMG_BINARY_THRESHOLD, 255, cv::THRESH_BINARY); |
| | | threshold(src, binary, threshold_value , 255, cv::THRESH_BINARY); |
| | | int rows = src.rows; |
| | | int cols = src.cols; |
| | | |
| | |
| | | }*/ |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | //分隔整数 |
| | | list<cv::Mat> ImgUtil::splitNum(cv::Mat src) throw(string) { |
| | | return splitNum(src,_IMG_BINARY_THRESHOLD); |
| | | } |
| | | |
| | | cv::Mat ImgUtil::formatNumLevel2(cv::Mat num) throw(string) { |
| | |
| | | } |
| | | |
| | | list<int*> ImgUtil::divideImg(cv::Mat img, bool save) { |
| | | //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\demo\\0_gray.jpg", img); |
| | | clock_t start_time = clock(); |
| | | LogUtil::info("开始分隔图像"); |
| | | list<list<int*>> resultList; |
| | |
| | | } |
| | | |
| | | if (contentStartRow < 0) { |
| | | LogUtil::error("图像分隔出错:title分隔出错"); |
| | | throw string("图像分隔出错:title分隔出错"); |
| | | } |
| | | |
| | | LogUtil::debug("\n\n\n\n"); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | //释放数据 |
| | | free(*ele); |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | |
| | | #ifndef _NUMBER_GP_CODE_WIDTH |
| | | #define _NUMBER_GP_CODE_WIDTH 11 |
| | | #define _NUMBER_GP_CODE_WIDTH 12 |
| | | #endif |
| | | |
| | | #ifndef _NUMBER_GP_CODE_HEIGHT |
| | |
| | | //分隔整数 |
| | | static list<cv::Mat> splitNum(cv::Mat img) throw(string); |
| | | |
| | | static list<cv::Mat> splitNum(cv::Mat img,int threshold_value) throw(string); |
| | | |
| | | static cv::Mat formatNumGPCode(cv::Mat num) throw(string); |
| | | }; |
| | | |
| | |
| | | |
| | | |
| | | |
| | | void OpenCLExcuter::splitNum(unsigned char* img, int img_width, int img_height, int* pos, int pos_count, unsigned char* zero, int num_width,int num_height,int num_count, unsigned char* result) { |
| | | void OpenCLExcuter::splitL2Num(unsigned char* img, int img_width, int img_height, int* pos, int pos_count, unsigned char* zero, int num_width,int num_height,int num_count, unsigned char* result) { |
| | | clock_t time_0 = clock(); |
| | | |
| | | kernel = clCreateKernel(program, "split_num", &error); |
| | |
| | | |
| | | |
| | | |
| | | void OpenCLExcuter::splitRowData(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs, int lines, |
| | | void OpenCLExcuter::splitL2RowData(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs, int lines, |
| | | int* result) { |
| | | |
| | | kernel = clCreateKernel(program, "splitRowData", &error); |
| | |
| | | clReleaseMemObject(memObject3); |
| | | } |
| | | |
| | | void OpenCLExcuter::recognitionNotNum(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs,int colCount, int lines, |
| | | int* result) { |
| | | |
| | | clock_t time_1 = clock(); |
| | | |
| | | |
| | | kernel = clCreateKernel(program, "recognition_not_num", &error); |
| | | if (kernel == NULL) { |
| | | throw("Couldn't create kernel!\n"); |
| | | } |
| | | |
| | | |
| | | int inputSize = imgWidth * imgHeight; |
| | | int resultSize = lines * 2; |
| | | |
| | | |
| | | //创建缓存对象 |
| | | |
| | | cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, imgs, &error); |
| | | if (error < 0) { |
| | | throw("Creat memObject1 failed!\n"); |
| | | } |
| | | |
| | | cl_mem memObject2 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * lines * 4 * colCount, rowIndexs, &error); |
| | | if (error < 0) { |
| | | throw("Creat memObject2 failed!\n"); |
| | | } |
| | | |
| | | |
| | | cl_mem memObject3 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, |
| | | sizeof(int) * resultSize, NULL, &error); |
| | | if (error < 0) { |
| | | throw("Creat memObject3 failed!\n"); |
| | | } |
| | | |
| | | |
| | | //设置内核参数 |
| | | error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); |
| | | error = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memObject2); |
| | | error |= clSetKernelArg(kernel, 2, sizeof(int), &imgWidth); |
| | | error |= clSetKernelArg(kernel, 3, sizeof(cl_mem), &memObject3); |
| | | |
| | | if (error != CL_SUCCESS) { |
| | | throw("Error setting kernel arguments!\n"); |
| | | } |
| | | //执行内核 |
| | | size_t globalWorkSize[1] = { resultSize }; |
| | | size_t localWorkSize[1] = { 1 }; |
| | | |
| | | const int work_dim = 1; |
| | | |
| | | error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, |
| | | localWorkSize, 0, NULL, NULL); |
| | | if (error != CL_SUCCESS) { |
| | | throw("Error queuing kernel for execution!\n"); |
| | | } |
| | | |
| | | //读取执行结果 |
| | | error = clEnqueueReadBuffer(queue, memObject3, CL_TRUE, 0, resultSize * sizeof(int), |
| | | result, 0, NULL, NULL); |
| | | if (error != CL_SUCCESS) { |
| | | throw("Error reading result buffer!\n"); |
| | | } |
| | | |
| | | //printf("%d %d %d %d \n", result[0], result[1], result[2], result[3]); |
| | | |
| | | clReleaseKernel(kernel); |
| | | clReleaseMemObject(memObject1); |
| | | clReleaseMemObject(memObject2); |
| | | clReleaseMemObject(memObject3); |
| | | |
| | | } |
| | | |
| | | |
| | | void OpenCLExcuter::rgb2Gray(unsigned char* imgs, int imgWidth, int imgHeight, |
| | | unsigned char* result) { |
| | |
| | | |
| | | } |
| | | |
| | | |
| | | void OpenCLExcuter::rgba2Gray(unsigned char* imgs, int imgWidth, int imgHeight, |
| | | unsigned char* result) { |
| | | |
| | | kernel = clCreateKernel(program, "rgba2GrayImg", &error); |
| | | if (kernel == NULL) { |
| | | throw("Couldn't create kernel!\n"); |
| | | } |
| | | |
| | | |
| | | int inputSize = imgWidth * imgHeight * 4; |
| | | int resultSize = imgWidth * imgHeight; |
| | | |
| | | |
| | | //创建缓存对象 |
| | | |
| | | cl_mem memObject1 = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(uchar) * inputSize, imgs, &error); |
| | | if (error < 0) { |
| | | throw("Creat memObject1 failed!\n"); |
| | | } |
| | | |
| | | cl_mem memObject2 = clCreateBuffer(context, CL_MEM_WRITE_ONLY, |
| | | sizeof(uchar) * resultSize, NULL, &error); |
| | | if (error < 0) { |
| | | throw("Creat memObject2 failed!\n"); |
| | | } |
| | | |
| | | |
| | | //设置内核参数 |
| | | error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memObject1); |
| | | error |= clSetKernelArg(kernel, 1, sizeof(int), &imgWidth); |
| | | error = clSetKernelArg(kernel, 2, sizeof(cl_mem), &memObject2); |
| | | |
| | | if (error != CL_SUCCESS) { |
| | | throw("Error setting kernel arguments!\n"); |
| | | } |
| | | //执行内核 |
| | | size_t globalWorkSize[1] = { imgHeight }; |
| | | size_t localWorkSize[1] = { 1 }; |
| | | |
| | | const int work_dim = 1; |
| | | |
| | | error = clEnqueueNDRangeKernel(queue, kernel, work_dim, NULL, globalWorkSize, |
| | | localWorkSize, 0, NULL, NULL); |
| | | if (error != CL_SUCCESS) { |
| | | throw("Error queuing kernel for execution!\n"); |
| | | } |
| | | |
| | | //读取执行结果 |
| | | error = clEnqueueReadBuffer(queue, memObject2, CL_TRUE, 0, resultSize * sizeof(uchar), |
| | | result, 0, NULL, NULL); |
| | | if (error != CL_SUCCESS) { |
| | | throw("Error reading result buffer!\n"); |
| | | } |
| | | |
| | | clReleaseKernel(kernel); |
| | | clReleaseMemObject(memObject1); |
| | | clReleaseMemObject(memObject2); |
| | | |
| | | } |
| | | |
| | | void OpenCLExcuter::destory() { |
| | | //释放资源 |
| | | clReleaseDevice(devices); |
| | |
| | | public: |
| | | void init(); |
| | | void destory(); |
| | | unsigned char** recognition_numbers(unsigned char* data, unsigned char* b_in, const int rows, const int cols, const int num_width, const int num_height, const int num_count); |
| | | |
| | | //分隔每一行需要识别的数字 |
| | | void splitNum(unsigned char* img, int img_width, int img_height, int* pos, int pos_count, unsigned char* zero, int num_width, int num_height, int number_count, unsigned char* result); |
| | | |
| | | //将RGB图片转为灰度图片 |
| | | void rgb2Gray(unsigned char* imgs, int imgWidth, int imgHeight, |
| | | unsigned char* result); |
| | | |
| | | void rgba2Gray(unsigned char* imgs, int imgWidth, int imgHeight, |
| | | unsigned char* result); |
| | | |
| | | //创建识别的数字模板 |
| | | void createNumberTemplates(int lines, int num_width, int num_height, int num_count, uchar* numsOneLevelData, unsigned char* result); |
| | | |
| | | //识别数字 |
| | | unsigned char** recognition_numbers(unsigned char* data, unsigned char* num_templates, const int rows, const int cols, const int num_width, const int num_height, const int num_count); |
| | | |
| | | //分隔每一行需要识别的数字 |
| | | //将连续的数字图片分隔成单个数字的图片,方便识别 |
| | | void splitL2Num(unsigned char* img, int img_width, int img_height, int* pos, int pos_count, unsigned char* zero, int num_width, int num_height, int number_count, unsigned char* result); |
| | | |
| | | |
| | | //分隔行数据 |
| | | void splitRowData(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs, int lines, |
| | | //每一行的数据分隔成7个区域 |
| | | void splitL2RowData(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs, int lines, |
| | | int* result); |
| | | |
| | | void rgb2Gray(unsigned char* imgs, int imgWidth, int imgHeight, |
| | | unsigned char* result); |
| | | |
| | | //识别非数字 |
| | | void recognitionNotNum(unsigned char* imgs, int imgWidth, int imgHeight, int* rowIndexs, int colCount, int lines, |
| | | int* result); |
| | | |
| | | |
| | | }; |
| | | |
| | |
| | | { |
| | | if (rowData[(index-1) * 4] > 0) { |
| | | //涨停 |
| | | (tradeData).limitPrice = true; |
| | | (tradeData).limitPrice = LIMIT_PRICE_UP; |
| | | } |
| | | else |
| | | { |
| | | (tradeData).limitPrice = false; |
| | | (tradeData).limitPrice = LIMIT_PRICE_NORMAL; |
| | | } |
| | | } |
| | | break; |
| | |
| | | //LogUtil::debug("像素值:%d\n", pixelCount); |
| | | |
| | | if (abs(pixelCount - 39) < 5) { |
| | | return BUY; |
| | | return OPERATE_BUY; |
| | | } |
| | | else if (abs(pixelCount - 51) < 5) { |
| | | return SELL; |
| | | return OPERATE_SELL; |
| | | } |
| | | else if (abs(pixelCount - 105) < 5) { |
| | | return BUY_CANCEL; |
| | | return OPERATE_BUY_CANCEL; |
| | | } |
| | | else if (abs(pixelCount - 117) < 5) { |
| | | return SELL_CANCEL; |
| | | return OPERATE_SELL_CANCEL; |
| | | } |
| | | |
| | | //pixelSet.insert(pixelCount); |
| | |
| | | |
| | | //} |
| | | |
| | | return OPERATE_ERROR; |
| | | return OPERATE_OPERATE_ERROR; |
| | | } |
| | | |
| | | std::string RecognitionManager::recognitionPrice(std::string cpath) { |
| | |
| | | #include "OpenCLExcuter.h" |
| | | |
| | | using namespace std; |
| | | |
| | | enum LIMIT_PRICE { |
| | | LIMIT_PRICE_NORMAL, |
| | | LIMIT_PRICE_UP, |
| | | LIMIT_PRICE_DOWN, |
| | | }; |
| | | |
| | | struct TradeData |
| | | { |
| | | //排序值 |
| | |
| | | //价格 |
| | | string price; |
| | | //是否为涨停价 |
| | | bool limitPrice; |
| | | LIMIT_PRICE limitPrice; |
| | | //手数 |
| | | int num; |
| | | //操作类型 |
| | |
| | | |
| | | enum OperateType { |
| | | //买 |
| | | BUY, |
| | | OPERATE_BUY, |
| | | //买撤 |
| | | BUY_CANCEL, |
| | | OPERATE_BUY_CANCEL, |
| | | //卖 |
| | | SELL, |
| | | OPERATE_SELL, |
| | | //卖撤 |
| | | SELL_CANCEL, |
| | | OPERATE_SELL_CANCEL, |
| | | //错误 |
| | | OPERATE_ERROR, |
| | | OPERATE_OPERATE_ERROR, |
| | | }; |
| | | |
| | | class NumberData { |
| | |
| | | #include "ScreenDataCapture.h" |
| | | #include <thread> |
| | | #include<fstream> |
| | | #include "THSActionUtil.h" |
| | | #include <thread> |
| | | bool ScreenDataCapture::inited; |
| | | OpenCLExcuter* ScreenDataCapture::openCLExcuter[THS_FRAME_COUNT]; |
| | | //是否正在执行 |
| | | bool ScreenDataCapture::running; |
| | | bool ScreenDataCapture::runnings[THS_FRAME_COUNT]; |
| | | clock_t ScreenDataCapture::latest_running_times[THS_FRAME_COUNT]; |
| | | |
| | | CallbackFun ScreenDataCapture::data_callback; |
| | | |
| | | string ScreenDataCapture::gpCodes[THS_FRAME_COUNT]; |
| | | |
| | | void* ScreenDataCapture::context; |
| | | |
| | | //运行 |
| | | void ScreenDataCapture::_run(int index) |
| | | { |
| | | while (true) { |
| | | if (running && runnings[index]&& gpCodes[index].length()>0) { |
| | | latest_running_times[index] = clock(); |
| | | //识别数据 |
| | | string code = gpCodes[index]; |
| | | list<TradeData> resultList=captureLevel2TradeData(CaptureUtil::capture(index), index); |
| | | data_callback(index,code, resultList, context); |
| | | } |
| | | Sleep(2); |
| | | } |
| | | } |
| | | |
| | | void ScreenDataCapture::setGPCode(int index, string code) { |
| | | int length = sizeof(gpCodes) / sizeof(gpCodes[0]); |
| | | if (length <= index) { |
| | | return; |
| | | } |
| | | |
| | | gpCodes[index] = code; |
| | | } |
| | | |
| | | string ScreenDataCapture::getGPCode(int index) { |
| | | return gpCodes[index]; |
| | | } |
| | | |
| | | static string getGPCode(int index); |
| | | |
| | | ScreenDataCapture::ScreenDataCapture() { |
| | | |
| | | openCLExcuter = new OpenCLExcuter(); |
| | | openCLExcuter->init(); |
| | | } |
| | | void ScreenDataCapture::refreshHWND() { |
| | | HWND win = THSActionUtil::getL2Win(); |
| | | if (win <= 0) { |
| | | throw string("未获取到同花顺LEVEL2盘口"); |
| | | } |
| | | CaptureUtil::init(win); |
| | | } |
| | | |
| | | void ScreenDataCapture::init(CallbackFun callback, void* contex) { |
| | | inited = true; |
| | | data_callback = callback; |
| | | context = contex; |
| | | |
| | | |
| | | for (int i = 0;i < THS_FRAME_COUNT;i++) |
| | | { |
| | | openCLExcuter[i] = new OpenCLExcuter(); |
| | | openCLExcuter[i]->init(); |
| | | } |
| | | //获取同花顺窗口句柄 |
| | | try { |
| | | refreshHWND(); |
| | | } |
| | | catch (string st) { |
| | | throw st; |
| | | } |
| | | running = false; |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | runnings[i] = false; |
| | | thread rt(&(ScreenDataCapture::_run),i); |
| | | rt.detach(); |
| | | } |
| | | |
| | | } |
| | | |
| | | bool ScreenDataCapture::isRunning() { |
| | | return running; |
| | | } |
| | | |
| | | void ScreenDataCapture::start(int index) { |
| | | runnings[index] = true; |
| | | } |
| | | //结束 |
| | | void ScreenDataCapture::stop(int index) { |
| | | runnings[index] = false; |
| | | } |
| | | //全部开始 |
| | | void ScreenDataCapture::start() { |
| | | running = true; |
| | | } |
| | | //全部结束 |
| | | void ScreenDataCapture::stop() { |
| | | running = false; |
| | | } |
| | | |
| | | void ScreenDataCapture::startAll() { |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | runnings[i] = true; |
| | | } |
| | | } |
| | | |
| | | void ScreenDataCapture::stopAll() { |
| | | int length = sizeof(runnings) / sizeof(runnings[0]); |
| | | for (int i = 0;i < length;i++) { |
| | | runnings[i] = false; |
| | | } |
| | | } |
| | | |
| | | bool ScreenDataCapture::isInited() { |
| | | return inited; |
| | | } |
| | | |
| | | list<TradeData> ScreenDataCapture::captureLevel2TradeData(cv::Mat oimg, int identify) { |
| | | if (oimg.rows == 0 || oimg.cols == 0) { |
| | |
| | | |
| | | //灰度化 |
| | | cv::Mat img = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);//ImgUtil::grayImage(oimg); |
| | | uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols); |
| | | |
| | | openCLExcuter->rgb2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols); |
| | | // |
| | | if (oimg.channels() == 3) |
| | | { |
| | | openCLExcuter[identify]->rgb2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | } |
| | | else { |
| | | openCLExcuter[identify]->rgba2Gray(oimg.data, oimg.cols, oimg.rows, imgData); |
| | | } |
| | | img.data = imgData; |
| | | oimg.release(); |
| | | |
| | |
| | | rowDataOneLevel[index * 4 + 2] = indexs[3]; |
| | | rowDataOneLevel[index * 4 + 3] = indexs[2]; |
| | | index++; |
| | | free(indexs); |
| | | } |
| | | |
| | | int* rowSplitDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4 * 7); |
| | | openCLExcuter->splitRowData(imgData, img.cols, img.rows, rowDataOneLevel, rowDataList.size(), rowSplitDataOneLevel); |
| | | openCLExcuter[identify]->splitL2RowData(imgData, img.cols, img.rows, rowDataOneLevel, rowDataList.size(), rowSplitDataOneLevel); |
| | | free(rowDataOneLevel); |
| | | |
| | | |
| | |
| | | clock_t time_33 = clock(); |
| | | std::cout << "数据准备-0数据准备: threadid-" << std::this_thread::get_id() << " 耗时:" << time_33 - time_32 << endl; |
| | | |
| | | openCLExcuter->splitNum(imgData, img.cols, img.rows, pos, 3 * rowDataList.size(), zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, totalNumberData); |
| | | openCLExcuter[identify]->splitL2Num(imgData, img.cols, img.rows, pos, 3 * rowDataList.size(), zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, totalNumberData); |
| | | |
| | | free(pos); |
| | | free(zeroData); |
| | |
| | | //准备模板数字 |
| | | uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * rowDataList.size()) * _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER); |
| | | |
| | | openCLExcuter->createNumberTemplates(rowDataList.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, ImgUtil::numsOneLevel_level2 ,templateNums); |
| | | openCLExcuter[identify]->createNumberTemplates(rowDataList.size(), _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER, ImgUtil::numsOneLevel_level2 ,templateNums); |
| | | |
| | | //ImgUtil::createTemplateNumData(data.size()); |
| | | clock_t time_4 = clock(); |
| | |
| | | |
| | | |
| | | //图像识别(除开数字的部分) |
| | | RecognitionManager* recognitionManager = new RecognitionManager(); |
| | | list<TradeData> resultList; |
| | | |
| | | |
| | | int* notNumberResult = (int*)malloc(sizeof(int)* rowDataList.size()*2); |
| | | openCLExcuter[identify]->recognitionNotNum(img.data,img.cols,img.rows, rowSplitDataOneLevel,7, rowDataList.size(), notNumberResult); |
| | | |
| | | |
| | | |
| | | for (int i = 0;i < rowDataList.size();i++) { |
| | | TradeData td = TradeData(); |
| | | switch (notNumberResult[i * 2]) |
| | | { |
| | | case 0: |
| | | td.limitPrice = LIMIT_PRICE_NORMAL;break; |
| | | case 1: |
| | | td.limitPrice = LIMIT_PRICE_UP;break; |
| | | case 2: |
| | | td.limitPrice = LIMIT_PRICE_DOWN;break; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | switch (notNumberResult[i * 2 + 1]) |
| | | { |
| | | case OPERATE_BUY: |
| | | td.operateType = OPERATE_BUY; |
| | | break; |
| | | case OPERATE_BUY_CANCEL: |
| | | td.operateType = OPERATE_BUY_CANCEL; |
| | | break; |
| | | case OPERATE_SELL: |
| | | td.operateType = OPERATE_SELL; |
| | | break; |
| | | case OPERATE_SELL_CANCEL: |
| | | td.operateType = OPERATE_SELL_CANCEL; |
| | | break; |
| | | case OPERATE_OPERATE_ERROR: |
| | | td.operateType = OPERATE_OPERATE_ERROR; |
| | | break; |
| | | }; |
| | | |
| | | resultList.push_back(td); |
| | | } |
| | | |
| | | free(notNumberResult); |
| | | |
| | | /* |
| | | try { |
| | | resultList = (*recognitionManager).recognition(img, rowSplitDataOneLevel, rowDataList.size()); |
| | | } |
| | | catch (...) { |
| | | throw ERROR_CODE_RECOGNITION_FAIL; |
| | | } |
| | | */ |
| | | |
| | | clock_t time_5 = clock(); |
| | | std::cout << "非数字数据识别完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_5 - time_4 << endl; |
| | | |
| | | //数字识别 |
| | | uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | uchar** numberResult = openCLExcuter[identify]->recognition_numbers(totalNumberData, templateNums, rowDataList.size() * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * _NUMBER_L2_TOTAL_NUMBER, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, _NUMBER_L2_TOTAL_NUMBER); |
| | | //释放内存 |
| | | free(totalNumberData); |
| | | free(templateNums); |
| | |
| | | std::cout << "数字识别完成: threadid-" << std::this_thread::get_id() << " 耗时:" << time_6 - time_5 << endl; |
| | | |
| | | //释放内存 |
| | | //img.release(); |
| | | free(imgData); |
| | | img.release(); |
| | | rowDataList.clear(); |
| | | list<int*>().swap(rowDataList); |
| | | //free(imgData); |
| | | free(rowSplitDataOneLevel); |
| | | |
| | | delete recognitionManager; |
| | | |
| | | std::cout << "-------结束任务: threadid-" << std::this_thread::get_id() << " 序号:" << identify << " 耗时:" << clock() - starttime << endl; |
| | | |
| | |
| | | } |
| | | |
| | | //捕获level2的盘口数据 |
| | | list<TradeData> ScreenDataCapture::captureLevel2TradeData(int frameIndex) throw(int) { |
| | | cv::Mat img = CaptureUtil::capture(frameIndex); |
| | | list<TradeData> ScreenDataCapture::captureLevel2TradeData(HWND hwnd, int index) throw(int) { |
| | | cv::Mat img = CaptureUtil::capture(hwnd); |
| | | |
| | | /* |
| | | string path1 = "E:\\temp\\"; |
| | |
| | | std::map<string, TradeData> map; |
| | | */ |
| | | |
| | | return captureLevel2TradeData(img, frameIndex); |
| | | return captureLevel2TradeData(img, index); |
| | | } |
| | |
| | | #include <map> |
| | | #include "OpenCLExcuter.h" |
| | | #include "CaptureUtil.h" |
| | | #define THS_FRAME_COUNT 1 |
| | | |
| | | typedef void (*CallbackFun)(int index, string code, list<TradeData> dataList, void* contex); |
| | | |
| | | class ScreenDataCapture |
| | | { |
| | | private: |
| | | OpenCLExcuter* openCLExcuter; |
| | | static OpenCLExcuter* openCLExcuter[THS_FRAME_COUNT]; |
| | | static bool inited; |
| | | //是否正在执行 |
| | | static bool running; |
| | | static bool runnings[THS_FRAME_COUNT]; |
| | | static clock_t latest_running_times[THS_FRAME_COUNT]; |
| | | |
| | | static string gpCodes[THS_FRAME_COUNT]; |
| | | |
| | | static CallbackFun data_callback; |
| | | |
| | | static void* context; |
| | | |
| | | static void _run(int index); |
| | | |
| | | |
| | | |
| | | public: |
| | | ScreenDataCapture(); |
| | | //捕获level2的盘口数据 |
| | | list<TradeData> captureLevel2TradeData(int winIndex) throw(int); |
| | | |
| | | //初始化 |
| | | void init(CallbackFun callback, void* context); |
| | | |
| | | list<TradeData> captureLevel2TradeData(cv::Mat oimg,int identify); |
| | | void refreshHWND(); |
| | | |
| | | bool isRunning(); |
| | | |
| | | //开始 |
| | | void start(int index); |
| | | //结束 |
| | | void stop(int index); |
| | | //全部开始 |
| | | void start(); |
| | | //全部结束 |
| | | void stop(); |
| | | //全部开始 |
| | | void startAll(); |
| | | //全部结束 |
| | | void stopAll(); |
| | | |
| | | bool isInited(); |
| | | |
| | | //捕获level2的盘口数据 |
| | | static list<TradeData> captureLevel2TradeData(HWND hwnd,int index) throw(int); |
| | | static list<TradeData> captureLevel2TradeData(cv::Mat oimg,int identify); |
| | | //设置代码 |
| | | static void setGPCode(int index, string code); |
| | | //获取代码 |
| | | static string getGPCode(int index); |
| | | |
| | | }; |
| | | |
| | |
| | | #include "ImgDivider.h" |
| | | #include "Win32Util.h" |
| | | |
| | | RecognitionManager* THSActionUtil::recognitionManager; |
| | | |
| | | bool isMainScreen(string str) { |
| | | if (str.find("同花顺(") != string::npos) { |
| | | cout << str << endl; |
| | | if (str.find("副屏") == string::npos) { |
| | | if (str.find("热门股") != string::npos || str.find("我的板块") != string::npos) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | bool isSecondScreen(string str) { |
| | | return str.find("同花顺(") != string::npos && str.find("副屏") != string::npos; |
| | | } |
| | | |
| | | //获取副屏 |
| | | HWND getSecondWindow() { |
| | |
| | | for (ele = wlist.begin();ele != wlist.end();ele++) { |
| | | HWND hwnd = *ele; |
| | | string str = Win32Util::getWindowName(hwnd); |
| | | if (str.find("同花顺") != string::npos && str.find("副屏") != string::npos) |
| | | if (isSecondScreen(str)) |
| | | { |
| | | return hwnd; |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | HWND THSActionUtil::getL2Win() { |
| | | list<HWND> wlist = Win32Util::searchWindow("同花顺("); |
| | | list<HWND>::iterator ele; |
| | | for (ele = wlist.begin();ele != wlist.end();ele++) { |
| | | HWND hwnd = *ele; |
| | | string str = Win32Util::getWindowName(hwnd); |
| | | |
| | | |
| | | if (isMainScreen(str)) { |
| | | return hwnd; |
| | | } |
| | | |
| | | } |
| | | return 0; |
| | | } |
| | | bool THSActionUtil::checkEnv() { |
| | | |
| | | list<HWND> wlist = Win32Util::searchWindow("同花顺("); |
| | | list<HWND>::iterator ele; |
| | | bool fp = false; |
| | | bool zp = false; |
| | | for (ele = wlist.begin();ele != wlist.end();ele++) { |
| | | HWND hwnd = *ele; |
| | | string str = Win32Util::getWindowName(hwnd); |
| | | if (isSecondScreen(str)) |
| | | { |
| | | fp = true; |
| | | } |
| | | |
| | | if (isMainScreen(str)) { |
| | | zp = true; |
| | | } |
| | | |
| | | } |
| | | |
| | | if (!zp) { |
| | | throw string("同花顺主屏L2窗口未打开"); |
| | | } |
| | | |
| | | |
| | | if (!fp) { |
| | | throw string("同花顺副屏没有打开"); |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | void THSActionUtil::openSecondScreen() { |
| | |
| | | for (ele = wlist.begin();ele != wlist.end();ele++) { |
| | | HWND hwnd = *ele; |
| | | string str = Win32Util::getWindowName(hwnd); |
| | | if (str.find("同花顺") != string::npos && str.find("副屏") != string::npos) |
| | | if (isSecondScreen(str)) |
| | | { |
| | | cout << str << endl; |
| | | SetForegroundWindow(hwnd); |
| | |
| | | break; |
| | | } |
| | | |
| | | if (str.find("同花顺") != string::npos && str.find("热门股") != string::npos) { |
| | | if (isMainScreen(str)) { |
| | | cout << hwnd << endl; |
| | | //获取尺寸 |
| | | RECT rc; |
| | |
| | | } |
| | | |
| | | if (!open) { |
| | | if (mainPage <= 0) { |
| | | throw("未找到首页"); |
| | | } |
| | | |
| | | Win32Util::focus(mainPage); |
| | | //查找主窗口的工具栏 |
| | | HWND tool = FindWindowExA(mainPage, NULL, "AfxControlBar100s", NULL); |
| | |
| | | } |
| | | } |
| | | //添加股票 |
| | | void THSActionUtil::setGP(std::string quickCode, list<std::string> codeList) { |
| | | bool THSActionUtil::setGP(std::string quickCode, list<std::string> codeList) { |
| | | |
| | | list<std::string> tempCodeList; |
| | | for (std::list<string>::iterator e = codeList.begin();e != codeList.end();e++) { |
| | | tempCodeList.push_back(*e); |
| | | } |
| | | |
| | | //打开副屏 |
| | | HWND sw = getSecondWindow(); |
| | | if (sw <= 0) |
| | |
| | | if (sw <= 0) { |
| | | throw("未打开副屏"); |
| | | } |
| | | |
| | | Win32Util::focus(sw); |
| | | //打开板块 |
| | | Win32Util::keyboardNum(quickCode); |
| | | Win32Util::keyboardNum(quickCode, 100); |
| | | Win32Util::keyboard(VK_RETURN, 200); |
| | | Sleep(1000); |
| | | |
| | | Sleep(2000); |
| | | //设置板块中的股票 |
| | | |
| | | //获取板块内容句柄 |
| | | |
| | | HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL); |
| | | cv::Mat img = CaptureUtil::capture(content); |
| | | if (img.cols <= 0 || img.rows <= 0) { |
| | | throw("板块截屏内容为空"); |
| | | cv::Mat oimg = CaptureUtil::capture(content); |
| | | cout << "副屏截图:" << oimg.rows << "-" << oimg.cols << endl; |
| | | |
| | | if (oimg.cols <= 0 || oimg.rows <= 0) { |
| | | throw string("板块截屏内容为空"); |
| | | } |
| | | |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | | oimg.release(); |
| | | std::list<GPCodeArea> areaList = recognitionGPArea(img); |
| | | |
| | | std::list<string> addList; |
| | | std::list<GPCodeArea> delList; |
| | | std::list<GPCodeArea> resultList = recognitionNum(img, areaList); |
| | | |
| | | for (std::list<GPCodeArea>::reverse_iterator ele= resultList.rbegin();ele != resultList.rend();++ele) { |
| | | for (std::list<GPCodeArea>::reverse_iterator ele = resultList.rbegin();ele != resultList.rend();++ele) { |
| | | |
| | | bool contains = false; |
| | | std::list<string>::iterator e; |
| | | for (e = codeList.begin();e != codeList.end();e++) { |
| | | for (e = tempCodeList.begin();e != tempCodeList.end();e++) { |
| | | if (*e == (*ele).code) { |
| | | contains = true; |
| | | break; |
| | |
| | | } |
| | | else |
| | | { |
| | | codeList.remove((*ele).code); |
| | | tempCodeList.remove((*ele).code); |
| | | } |
| | | |
| | | |
| | | } |
| | | //-----先删除需要删除的 |
| | | //获取内容板块坐标 |
| | | RECT rect; |
| | | GetWindowRect(content, &rect); |
| | | |
| | | |
| | | for (std::list<GPCodeArea>::iterator ele = delList.begin();ele != delList.end();++ele) { |
| | | |
| | | RECT rect; |
| | | GetWindowRect(sw, &rect); |
| | | Win32Util::mouseMove(rect.left + 10, rect.top + 5, 1); |
| | | Win32Util::click(10); |
| | | |
| | | for (std::list<GPCodeArea>::iterator ele = delList.begin();ele != delList.end();++ele) { |
| | | RECT rect; |
| | | GetWindowRect(content, &rect); |
| | | Win32Util::focus(sw); |
| | | int x = rect.left; |
| | | int y = rect.top; |
| | | x += (*ele).startx+5; |
| | | y += (*ele).starty+5; |
| | | //选中删除 |
| | | Win32Util::click(x,y,50); |
| | | x += (*ele).startx + 5; |
| | | y += (*ele).starty + 5; //选中删除 |
| | | Win32Util::mouseMove(x, y, 50); |
| | | Win32Util::click(10); |
| | | Win32Util::keyboard(VK_DELETE, 50); |
| | | } |
| | | img.release(); |
| | | |
| | | //----增加 |
| | | //截图,识别出增加按钮位置,点击增加,输入内容 |
| | | for (std::list<string>::iterator ele = tempCodeList.begin();ele != tempCodeList.end();++ele) { |
| | | addGP(*ele); |
| | | Sleep(100); |
| | | } |
| | | |
| | | oimg = CaptureUtil::capture(content); |
| | | if (oimg.cols <= 0 || oimg.rows <= 0) { |
| | | throw("板块截屏内容为空"); |
| | | } |
| | | img = ImgUtil::grayImage(oimg); |
| | | areaList = recognitionGPArea(img); |
| | | resultList = recognitionNum(img, areaList); |
| | | for (std::list<GPCodeArea>::iterator ele = resultList.begin();ele != resultList.end();++ele) { |
| | | bool contains = false; |
| | | std::list<string>::iterator e; |
| | | for (e = codeList.begin();e != codeList.end();e++) { |
| | | if (*e == (*ele).code) { |
| | | contains = true; |
| | | break; |
| | | } |
| | | } |
| | | if (contains) { |
| | | codeList.remove((*ele).code); |
| | | } |
| | | } |
| | | |
| | | if (codeList.size() == 0) { |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | void add(string code) { |
| | | void THSActionUtil::addGP(string code) { |
| | | //打开副屏 |
| | | HWND sw = getSecondWindow(); |
| | | if (sw <= 0) |
| | |
| | | } |
| | | |
| | | HWND content = FindWindowExA(sw, NULL, "AfxFrameOrView100s", NULL); |
| | | cv::Mat img = CaptureUtil::capture(content); |
| | | cv::Mat oimg = CaptureUtil::capture(content); |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | | if (img.cols <= 0 || img.rows <= 0) { |
| | | throw("板块截屏内容为空"); |
| | | } |
| | |
| | | for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();++ele) { |
| | | GPCodeArea codeArea = *ele; |
| | | if (codeArea.type == IMG_TYPE_ADD) { |
| | | Win32Util::focus(sw); |
| | | RECT rc; |
| | | GetWindowRect(HWND(0x00161728), &rc); |
| | | GetWindowRect(content, &rc); |
| | | int y = rc.top + codeArea.starty + (codeArea.endy - codeArea.starty) / 2; |
| | | int x = rc.left + codeArea.startx + (codeArea.endx - codeArea.startx) / 2; |
| | | Win32Util::click(x, y, 50); |
| | | Sleep(10); |
| | | Win32Util::click(x, y, 50); |
| | | Sleep(10); |
| | | Win32Util::click(x, y, 50); |
| | | //输入股票代码 |
| | | Win32Util::keyboardNum(code,1000); |
| | | Win32Util::keyboardNum(code, 1000); |
| | | Win32Util::keyboard(VK_RETURN, 1500); |
| | | //关闭按钮 |
| | | Sleep(100); |
| | |
| | | } |
| | | } |
| | | |
| | | //识别股票代码 |
| | | std::list<GPCodeArea> THSActionUtil::recognitionGPArea(cv::Mat img) { |
| | | //获取title分隔线 |
| | | int rows = img.rows; |
| | | int cols = img.cols; |
| | | int r; |
| | | int contentStartRow = -1; |
| | | for (r = 5;r < img.rows;r++) { |
| | | if (ImgDivider::isRowFull(img, r, cols - 100, cols - 5, 2)) { |
| | | contentStartRow = r; |
| | | } |
| | | list<GPCodeArea> splitGPCodeArea(cv::Mat img, int start_row, int start_col, int end_row, int end_col) { |
| | | |
| | | if (contentStartRow > -1) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (contentStartRow < 0) { |
| | | throw("起始行分隔出错"); |
| | | } |
| | | |
| | | //分隔列 |
| | | int c = 0; |
| | | int startC = -1; |
| | | int endC = -1; |
| | | for (c = 50;c < cols;c++) { |
| | | if (ImgDivider::isColFull(img, c, contentStartRow + 5, contentStartRow + 100, 2)) { |
| | | if (startC < 0) { |
| | | startC = c; |
| | | } |
| | | else { |
| | | if (c - startC < 20) { |
| | | startC = c; |
| | | } |
| | | else { |
| | | endC = c; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (startC < 0 || endC < 0) { |
| | | throw("内容框分隔出错"); |
| | | } |
| | | //cv::imshow("内容", cv::Mat(img, cv::Rect(startC, contentStartRow, endC - startC, rows - contentStartRow))); |
| | | std::list<GPCodeArea> resultList; |
| | | |
| | | startC += 1; |
| | | endC -= 1; |
| | | list<GPCodeArea> resultList; |
| | | |
| | | //分隔行内容 |
| | | int emptyStartRow = -1; |
| | |
| | | int endf = -1; |
| | | std::list<int*> dataItemList; |
| | | |
| | | for (int i = contentStartRow + 30;i < rows;i++) { |
| | | bool empty = ImgDivider::isRowEmpty(img, i, startC, startC + 50, 1, 64) && ImgDivider::isRowEmpty(img, i, startC + (endC - startC) / 2 - 40, startC + (endC - startC) / 2 + 40, 1, 64); |
| | | for (int i = start_row;i < end_row;i++) { |
| | | bool empty = ImgDivider::isRowEmpty(img, i, start_col, start_col + 50, 1, _IMG_BINARY_THRESHOLD) && ImgDivider::isRowEmpty(img, i, start_col + (end_col - start_col) / 2 - 40, start_col + (end_col - start_col) / 2 + 40, 1, _IMG_BINARY_THRESHOLD); |
| | | if (empty) { |
| | | if (emptyStartRow < 0) { |
| | | emptyStartRow = i; |
| | |
| | | //内容坐标 |
| | | //LogUtil::debug("内容的高度为:%d \n", endf - startf); |
| | | int* dd = (int*)malloc(sizeof(int) * 4); |
| | | *dd = startC; |
| | | *dd = start_col; |
| | | *(dd + 1) = startf; |
| | | *(dd + 2) = endC; |
| | | *(dd + 2) = end_col; |
| | | *(dd + 3) = endf; |
| | | //行数据高大于6才为有效的行高 |
| | | if (endf - startf > 6) |
| | |
| | | |
| | | } |
| | | |
| | | //识别股票代码 |
| | | std::list<GPCodeArea> THSActionUtil::recognitionGPArea(cv::Mat img) { |
| | | |
| | | //imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\test.jpg", img); |
| | | //获取title分隔线 |
| | | int rows = img.rows; |
| | | int cols = img.cols; |
| | | int r; |
| | | int contentStartRow = -1; |
| | | for (r = 5;r < img.rows;r++) { |
| | | if (ImgDivider::isRowFull(img, r, cols - 100, cols - 5, 2)) { |
| | | contentStartRow = r; |
| | | } |
| | | |
| | | if (contentStartRow > -1) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (contentStartRow < 0) { |
| | | throw("起始行分隔出错"); |
| | | } |
| | | |
| | | //分隔列 |
| | | int c = 0; |
| | | int startC = -1; |
| | | int endC = -1; |
| | | for (c = 50;c < cols;c++) { |
| | | if (ImgDivider::isColFull(img, c, contentStartRow + 5, contentStartRow + 100, 2)) { |
| | | if (startC < 0) { |
| | | startC = c; |
| | | } |
| | | else { |
| | | if (c - startC < 20) { |
| | | startC = c; |
| | | } |
| | | else { |
| | | endC = c; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (startC < 0 || endC < 0) { |
| | | throw("内容框分隔出错"); |
| | | } |
| | | //cv::imshow("内容", cv::Mat(img, cv::Rect(startC, contentStartRow, endC - startC, rows - contentStartRow))); |
| | | |
| | | startC += 1; |
| | | endC -= 1; |
| | | std::list<GPCodeArea> resultList = splitGPCodeArea(img, contentStartRow + 30, startC, rows, endC); |
| | | return resultList; |
| | | |
| | | } |
| | | |
| | | std::list<GPCodeArea> THSActionUtil::recognitionNum(cv::Mat img, std::list<GPCodeArea> areaList) { |
| | | |
| | | if (!recognitionManager) { |
| | |
| | | |
| | | std::list<GPCodeArea>::iterator ele; |
| | | |
| | | int index = 0; |
| | | for (ele = areaList.begin();ele != areaList.end();ele++) { |
| | | index++; |
| | | GPCodeArea codeArea = *ele; |
| | | if (codeArea.type == IMG_TYPE_GP) { |
| | | cv::Mat nums = cv::Mat(img, cv::Rect(codeArea.startx, codeArea.starty, codeArea.endx - codeArea.startx + 1, codeArea.endy - codeArea.starty + 1)); |
| | | std::list<cv::Mat> list2 = ImgUtil::splitNum(nums); |
| | | //保存分隔的数据 |
| | | if (false) { |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\gpcode\\"; |
| | | path.append(to_string(index)); |
| | | path.append(".jpg"); |
| | | cv::imwrite(path, nums); |
| | | } |
| | | |
| | | std::list<cv::Mat> list2 = ImgUtil::splitNum(nums, 96); |
| | | if (false) { |
| | | std::list<cv::Mat>::iterator e; |
| | | int ci = 0; |
| | | for (e = list2.begin();e != list2.end();e++) { |
| | | ci++; |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\gpcode\\"; |
| | | path.append(to_string(index)).append("_").append(to_string(ci)); |
| | | path.append(".jpg"); |
| | | cv::imwrite(path, *e); |
| | | } |
| | | |
| | | } |
| | | |
| | | std::list<uchar> resultList = recognitionManager->recognitionGPCode(list2); |
| | | std::list<uchar>::iterator ele1; |
| | | string code = ""; |
| | |
| | | code.append(to_string(*ele1)); |
| | | } |
| | | codeArea.code = code; |
| | | cout << code << endl; |
| | | codeList.push_back(codeArea); |
| | | } |
| | | } |
| | | |
| | | return codeList; |
| | | } |
| | | |
| | | |
| | | //分隔L2数据的目录 |
| | | std::list<GPCodeArea> splitL2Cate(cv::Mat img) { |
| | | int cols = img.cols; |
| | | int contentStartRow = -1; |
| | | int contentEndRow = -1; |
| | | for (int r = 5;r < img.rows;r++) { |
| | | if (ImgDivider::isRowFull(img, r, 10, 200, 2, 10, 30) && ImgDivider::isRowFull(img, r, img.cols - 200, img.cols - 1, 2, 10, 30)) { |
| | | if (contentStartRow < 0) |
| | | { |
| | | contentStartRow = r; |
| | | } |
| | | else { |
| | | if (r - contentStartRow > 10) { |
| | | contentEndRow = r; |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | if (contentStartRow > -1 && contentEndRow > -1) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (contentStartRow < 0 || contentEndRow < 0) { |
| | | throw("起始行或结束行分隔出错"); |
| | | } |
| | | |
| | | //分隔列 |
| | | list<int*> dataColIndexs; |
| | | int startf = -1; |
| | | int endf = -1; |
| | | int startIndex = -1; |
| | | for (int i = 10;i < cols;i++) { |
| | | if (startIndex == -1) { |
| | | startIndex = i; |
| | | } |
| | | |
| | | bool full = ImgDivider::isColFull(img, i, contentStartRow, contentEndRow, 2); |
| | | if (full) { |
| | | if (startf < 0) |
| | | { |
| | | startf = i; |
| | | endf = i; |
| | | } |
| | | else { |
| | | endf = i; |
| | | } |
| | | } |
| | | else { |
| | | if (startf > -1 && endf > -1) { |
| | | int width = endf - startf + 1; |
| | | int* dd = (int*)malloc(sizeof(int) * 2); |
| | | |
| | | *dd = startIndex; |
| | | *(dd + 1) = startf - 1; |
| | | |
| | | dataColIndexs.push_back(dd); |
| | | startIndex = i; |
| | | } |
| | | startf = -1; |
| | | endf = -1; |
| | | } |
| | | |
| | | } |
| | | |
| | | if (startf > -1 && endf > -1) { |
| | | int width = endf - startf + 1; |
| | | int* dd = (int*)malloc(sizeof(int) * 2); |
| | | |
| | | *dd = startIndex; |
| | | *(dd + 1) = startf - 1; |
| | | LogUtil::debug("列数据:%d-%d\n", *dd, *(dd + 1)); |
| | | |
| | | dataColIndexs.push_back(dd); |
| | | |
| | | startf = -1; |
| | | endf = -1; |
| | | } |
| | | |
| | | if (cols - startIndex > 50) { |
| | | |
| | | int* dd = (int*)malloc(sizeof(int) * 2); |
| | | |
| | | *dd = startIndex; |
| | | *(dd + 1) = cols - 1; |
| | | |
| | | dataColIndexs.push_back(dd); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | std::list<GPCodeArea> areaList; |
| | | list<int*>::iterator ele; |
| | | for (ele = dataColIndexs.begin();ele != dataColIndexs.end();ele++) { |
| | | int* p = *ele; |
| | | int startx = *p; |
| | | int endx = *(p + 1); |
| | | |
| | | GPCodeArea area = GPCodeArea(); |
| | | area.startx = startx; |
| | | area.endx = endx; |
| | | area.starty = contentStartRow; |
| | | area.endy = contentEndRow; |
| | | areaList.push_back(area); |
| | | } |
| | | return areaList; |
| | | } |
| | | |
| | | |
| | | |
| | | std::map<int,string> THSActionUtil::getListenL2GPCodes() { |
| | | std::list<GPCodeArea> areaList = getListenL2GP(); |
| | | std::map<int, string> map; |
| | | for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();ele++) { |
| | | GPCodeArea data = (*ele); |
| | | if (map.count(data.cateIndex)==0&&data.type== IMG_TYPE_GP) { |
| | | map[data.cateIndex] = data.code; |
| | | } |
| | | } |
| | | |
| | | return map; |
| | | } |
| | | |
| | | |
| | | std::list<GPCodeArea> THSActionUtil::getListenL2GP() { |
| | | //截图当前有哪些股票代码 |
| | | list<HWND> wlist = Win32Util::searchWindow("同花顺("); |
| | | HWND mainPage = 0; |
| | | list<HWND>::iterator ele; |
| | | for (ele = wlist.begin();ele != wlist.end();ele++) { |
| | | HWND hwnd = *ele; |
| | | string str = Win32Util::getWindowName(hwnd); |
| | | if (isMainScreen(str)) { |
| | | cout << hwnd << endl; |
| | | //获取尺寸 |
| | | RECT rc; |
| | | GetWindowRect(hwnd, &rc); |
| | | if (rc.right - rc.left > 200 && rc.bottom - rc.top > 200) { |
| | | mainPage = hwnd; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (mainPage <= 0) { |
| | | throw string("L2监听未打开"); |
| | | } |
| | | |
| | | HWND content = FindWindowExA(mainPage, NULL, "AfxFrameOrView100s", NULL); |
| | | //截图 |
| | | cv::Mat oimg = CaptureUtil::capture(content); |
| | | cv::Mat img = ImgUtil::grayImage(oimg); |
| | | oimg.release(); |
| | | //分隔图片 |
| | | |
| | | std::list<GPCodeArea> areaList = splitL2Cate(img); |
| | | |
| | | int index = 0; |
| | | for (std::list<GPCodeArea>::iterator ele = areaList.begin();ele != areaList.end();ele++) { |
| | | GPCodeArea area = *ele; |
| | | index++; |
| | | std::list<GPCodeArea> resultList = splitGPCodeArea(img, area.starty + 20, area.startx, area.endy, area.endx); |
| | | if (false) { |
| | | std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\gpcode\\"; |
| | | path.append(std::to_string(index)).append("_listen.jpg"); |
| | | imwrite(path, cv::Mat(img, cv::Rect(area.startx, area.starty, area.endx - area.startx + 1, area.endy - area.starty + 1))); |
| | | } |
| | | |
| | | for (std::list<GPCodeArea>::iterator ele1 = resultList.begin();ele1 != resultList.end();ele1++) { |
| | | GPCodeArea areaC = *ele1; |
| | | if (areaC.type == IMG_TYPE_GP) { |
| | | list<cv::Mat> nums = ImgUtil::splitNum(cv::Mat(img, cv::Rect(areaC.startx, areaC.starty, areaC.endx - areaC.startx + 1, areaC.endy - areaC.starty + 1)), 96); |
| | | if (!recognitionManager) { |
| | | recognitionManager = new RecognitionManager(); |
| | | } |
| | | if (nums.size() != 6) { |
| | | throw string("代码分隔出错"); |
| | | } |
| | | |
| | | |
| | | list<uchar> rresult = recognitionManager->recognitionGPCode(nums); |
| | | string num; |
| | | for (std::list<uchar>::iterator e = rresult.begin();e != rresult.end();e++) { |
| | | num.append(to_string(*e)); |
| | | } |
| | | (*ele1).code = num; |
| | | (*ele1).cateIndex = index-1; |
| | | } |
| | | } |
| | | |
| | | return resultList; |
| | | } |
| | | |
| | | } |
| | | bool THSActionUtil::setListenL2GP(int p, string code) { |
| | | |
| | | |
| | | std::list<GPCodeArea> resultList = getListenL2GP(); |
| | | |
| | | HWND content = FindWindowExA(getL2Win(), NULL, "AfxFrameOrView100s", NULL); |
| | | |
| | | int index = 0; |
| | | for (std::list<GPCodeArea>::iterator ele = resultList.begin();ele != resultList.end();ele++) { |
| | | GPCodeArea result = *ele; |
| | | if (result.code == code) { |
| | | //点击 |
| | | RECT rc; |
| | | GetWindowRect(content, &rc); |
| | | int x = rc.left + result.startx + 5; |
| | | int y = rc.top + result.starty + 5; |
| | | Win32Util::focus(content); |
| | | Win32Util::click(x, y, 50); |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | |
| | | int endx; |
| | | int endy; |
| | | std::string code; |
| | | |
| | | //L2数据有效 |
| | | int cateIndex; |
| | | }; |
| | | //同花顺事件 |
| | | class THSActionUtil |
| | | { |
| | | private: |
| | | static RecognitionManager *recognitionManager; |
| | | static void addGP(string code); |
| | | static std::list<GPCodeArea> getListenL2GP(); |
| | | |
| | | public: |
| | | |
| | | static HWND getL2Win(); |
| | | |
| | | //检测环境 |
| | | static bool checkEnv(); |
| | | |
| | | //打开同花顺的副屏幕 |
| | | static void openSecondScreen(); |
| | | //设置股票 |
| | | static void setGP(std::string quickCode, list<std::string> codeList); |
| | | static bool setGP(std::string quickCode, list<std::string> codeList); |
| | | //识别股票代码 |
| | | static std::list<GPCodeArea> recognitionGPArea(cv::Mat img); |
| | | |
| | |
| | | static std::list<GPCodeArea> recognitionNum(cv::Mat img,std::list<GPCodeArea> areaList); |
| | | |
| | | |
| | | //设置获取level2的股票数据 |
| | | static bool setListenL2GP(int p,string code); |
| | | |
| | | //设置获取level2的股票代码 |
| | | static std::map<int, string> getListenL2GPCodes(); |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | |
| | | string Win32Util::getWindowName(HWND hwnd) { |
| | | int length = GetWindowTextLength(hwnd); |
| | | TCHAR getbuf[100]; |
| | | TCHAR getbuf[1000]; |
| | | GetWindowText(hwnd, getbuf, length + 1); |
| | | int iLen = WideCharToMultiByte(CP_ACP, 0, getbuf, -1, NULL, 0, NULL, NULL); //首先计算TCHAR 长度。 |
| | | char* chRtn = new char[iLen * sizeof(char)]; //定义一个 TCHAR 长度大小的 CHAR 类型。 |
| | |
| | | |
| | | __kernel void recognition_numbers_1(__global const unsigned char* a_in, |
| | | __global const unsigned char* b_in, int width,int num_width,int num_height,int num_count, |
| | | __global const unsigned char* b_in, int width, int num_width, int num_height, int num_count, |
| | | __global unsigned char* result) { |
| | | |
| | | int p = get_global_id(0); |
| | | int startIndex = p / width * width * num_width * num_height + p % (num_count*10) * num_width; |
| | | int startIndex = p / width * width * num_width * num_height + p % (num_count * 10) * num_width; |
| | | unsigned char t = 0; |
| | | for (int r = 0;r < num_height;r++) |
| | | for (int c = 0;c < num_width;c++) { |
| | |
| | | int endIndex = (index + 1) * 10; |
| | | |
| | | //获取最小值 |
| | | int min =255; |
| | | int min = 255; |
| | | int minIndex = 11; |
| | | |
| | | for (int i = startIndex;i < endIndex;i++) |
| | |
| | | return v >= 64 ? 1 : 0; |
| | | } |
| | | |
| | | __kernel void split_num(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, int width,int num_width,int num_height,int num_count, |
| | | __kernel void split_num(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, int width, int num_width, int num_height, int num_count, |
| | | __global unsigned char* result) { |
| | | |
| | | int index = get_global_id(0); |
| | |
| | | //开始填充数据 |
| | | for (i = 0;i < maxNumberCount;i++) { |
| | | |
| | | unsigned char numData[100*100]; |
| | | unsigned char numData[100 * 100]; |
| | | |
| | | if (fresult[i * 2] == -1) { |
| | | //填充0 |
| | |
| | | for (int c = 0;c < num_width;c++) { |
| | | unsigned char value = get_binary_value(zero[r * num_width + c]); |
| | | //设置输出坐标的值 |
| | | numData[r* num_width+c] = value; |
| | | numData[r * num_width + c] = value; |
| | | } |
| | | } |
| | | |
| | |
| | | //填充空白0 |
| | | value = get_binary_value(img_in[get_one_level_position(width, _startx + c, r)]); |
| | | //设置输出坐标的值 |
| | | numData[(r - starty)* num_width+c] = value; |
| | | numData[(r - starty) * num_width + c] = value; |
| | | } |
| | | else { |
| | | numData[(r - starty)* num_width+c] = 0; |
| | | numData[(r - starty) * num_width + c] = 0; |
| | | } |
| | | } |
| | | } |
| | |
| | | for (int c = 0;c < num_width;c++) { |
| | | int findex = index_0 + index_1 + index_2 + index_3 + c; |
| | | //printf("index:%d-findex:%d \n",index, findex); |
| | | result[findex] = numData[r* num_width+c]; |
| | | result[findex] = numData[r * num_width + c]; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | __kernel void createTemplateNumbers(__global unsigned char* numbers,int num_width,int num_height, int countPerLine, |
| | | __kernel void createTemplateNumbers(__global unsigned char* numbers, int num_width, int num_height, int countPerLine, |
| | | __global unsigned char* result) { |
| | | |
| | | int gid = get_global_id(0); |
| | |
| | | __kernel void rgb2GrayImg(__global unsigned char* imgs, int width, |
| | | __global unsigned char* result) { |
| | | |
| | | int rowIndex= get_global_id(0); |
| | | int rowIndex = get_global_id(0); |
| | | |
| | | for (int c = 0;c < width;c++) { |
| | | int index = rowIndex * width + c; |
| | | int start = index * 3; |
| | | unsigned char R = imgs[start]; |
| | | unsigned G = imgs[start + 1]; |
| | | unsigned B = imgs[start + 2]; |
| | | unsigned char G = imgs[start + 1]; |
| | | unsigned char B = imgs[start + 2]; |
| | | result[index] = (76 * R + 150 * G + 30 * B) >> 8; |
| | | } |
| | | } |
| | | |
| | | __kernel void rgba2GrayImg(__global unsigned char* imgs, int width, |
| | | __global unsigned char* result) { |
| | | |
| | | int rowIndex = get_global_id(0); |
| | | |
| | | for (int c = 0;c < width;c++) { |
| | | int index = rowIndex * width + c; |
| | | int start = index * 4; |
| | | unsigned char R = imgs[start]; |
| | | unsigned char G = imgs[start + 1]; |
| | | unsigned char B = imgs[start + 2]; |
| | | result[index] = (76 * R + 150 * G + 30 * B) >> 8; |
| | | } |
| | | } |
| | | |
| | | |
| | | //L2非数字识别 |
| | | __kernel void recognition_not_num(__global unsigned char* imgs, __global int* rowIndexs, int width, |
| | | __global int* result) { |
| | | |
| | | int index = get_global_id(0); |
| | | int row = index / 2; |
| | | int baseIndex = row * 4 * 7; |
| | | if (index % 2 == 0) { |
| | | //涨跌停价 |
| | | //获取数据坐标 |
| | | int startx = baseIndex + 3 * 4; |
| | | int starty = startx + 1; |
| | | int endx = startx + 2; |
| | | int endy = startx + 3; |
| | | if (rowIndexs[startx] <= 0 && rowIndexs[starty] <= 0 && rowIndexs[endx] <= 0 && rowIndexs[endy] <= 0) { |
| | | result[row * 2] = 0; |
| | | } |
| | | else { |
| | | startx = rowIndexs[startx]; |
| | | starty = rowIndexs[starty]; |
| | | endx = rowIndexs[endx]; |
| | | endy = rowIndexs[endy]; |
| | | |
| | | result[row * 2] = 1; |
| | | //去除上下的空白 |
| | | for (int r = starty;r <= endy;r++) |
| | | { |
| | | bool empty = true; |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | if (get_binary_value(value)) { |
| | | empty = 0; |
| | | break; |
| | | } |
| | | } |
| | | if (!empty) { |
| | | starty = r; |
| | | break; |
| | | } |
| | | } |
| | | for (int r = endy;r >= starty;r--) |
| | | { |
| | | bool empty = true; |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | if (get_binary_value(value)) { |
| | | empty = 0; |
| | | break; |
| | | } |
| | | } |
| | | if (!empty) { |
| | | endy = r; |
| | | break; |
| | | } |
| | | } |
| | | int my = (starty + endy) / 2; |
| | | //计算上半部分的值 |
| | | int topValue = 0; |
| | | for (int r = starty;r <= my;r++) |
| | | { |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | topValue += get_binary_value(value); |
| | | |
| | | } |
| | | } |
| | | //计算下半部分的值 |
| | | int bottomValue = 0; |
| | | for (int r = my;r <= endy;r++) |
| | | { |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | bottomValue += get_binary_value(value); |
| | | |
| | | } |
| | | } |
| | | |
| | | if (topValue > bottomValue) { |
| | | //涨停 |
| | | result[row * 2] = 1; |
| | | } |
| | | else { |
| | | //跌停 |
| | | result[row * 2] = 2; |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | //操作类型 |
| | | //计算值 |
| | | int startx = baseIndex + 6 * 4; |
| | | int starty = startx + 1; |
| | | int endx = startx + 2; |
| | | int endy = startx + 3; |
| | | startx = rowIndexs[startx]; |
| | | starty = rowIndexs[starty]; |
| | | endx = rowIndexs[endx]; |
| | | endy = rowIndexs[endy]; |
| | | |
| | | //printf("%d: %d %d %d %d\n",row, startx, starty, endx, endy); |
| | | |
| | | unsigned int pixelCount = 0; |
| | | for (int r = starty;r <= endy;r++) |
| | | { |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char val = imgs[get_one_level_position(width, c, r)]; |
| | | pixelCount+=get_binary_value(val); |
| | | } |
| | | } |
| | | |
| | | //初始化错误复制 |
| | | int value = 4; |
| | | if (abs(pixelCount - 39) < 5) { |
| | | //买 |
| | | value = 0; |
| | | } |
| | | else if (abs(pixelCount - 51) < 5) { |
| | | //卖 |
| | | value = 2; |
| | | } |
| | | else if (abs(pixelCount - 105) < 5) { |
| | | //买撤 |
| | | value = 1; |
| | | } |
| | | else if (abs(pixelCount - 117) < 5) { |
| | | //卖撤 |
| | | value = 3; |
| | | } |
| | | result[row * 2 + 1] = value; |
| | | } |
| | | |
| | | } |
| | |
| | | //同花顺(v9.10.50) - 深圳Level-2分时走势 |
| | | //同花顺(v9.10.50) - pppp |
| | | list<TradeData> map = creenDataCapture->captureLevel2TradeData(cv::imread( "C:\\Users\\Administrator\\Desktop\\ocr\\demo\\0_388.jpg"),p); |
| | | break; |
| | | //break; |
| | | } |
| | | |
| | | return 0L; |
| | |
| | | } |
| | | */ |
| | | |
| | | void notify(int index,string code, list<TradeData> data,void *context) { |
| | | cout << index << endl; |
| | | } |
| | | |
| | | int main() { |
| | | //THSActionUtil::openSecondScreen(); |
| | | ImgUtil::init(); |
| | | |
| | | ScreenDataCapture* capture = new ScreenDataCapture(); |
| | | capture->init(notify,nullptr); |
| | | capture->start(); |
| | | capture->startAll(); |
| | | /* |
| | | RecognitionUtil::init(); |
| | | CaptureUtil::init("同花顺(v9.10.50) - 热门股888");// 热门股888 |
| | | ImgUtil::init(); |
| | | ths(); |
| | | std::list<string> codeList; |
| | | codeList.push_back("000333"); |
| | | bool setResult = THSActionUtil::setListenL2GP(4,"000333"); |
| | | printf("设置股票代码结果:%d\n", setResult); |
| | | cv::waitKey(0); |
| | | cv::destroyAllWindows(); |
| | | return 0; |
| | | |
| | | */ |
| | | |
| | | /* |
| | | RecognitionManager* recognitionManager = new RecognitionManager(); |
| | |
| | | } |
| | | */ |
| | | |
| | | |
| | | cv::waitKey(0); |
| | | cv::destroyAllWindows(); |
| | | return 0; |
| | | |
| | | |
| | | |
| | | string path = "C:\\Users\\Administrator\\Desktop\\ocr\\temp.jpg"; |
| | | |
| | | |
| | | cv::Mat img = CaptureUtil::capture(HWND(0x00010CA6)); |
| | | cv::imwrite(path, img); |
| | | |
| | | |
| | | |
| | | //return 0; |
| | | |
| | | /* |
| | | |
| | | RecognitionUtil::init(); |
| | | CaptureUtil::init("同花顺(v9.10.50) - 热门股888");// 热门股888 |
| | | ImgUtil::init(); |
| | | for (int i = 0;i < 1;i++) |
| | | { |
| | |
| | | |
| | | |
| | | system("PAUSE"); |
| | | |
| | | */ |
| | | system("PAUSE"); |
| | | cv::waitKey(0); |
| | | cv::destroyAllWindows(); |
| | | |
| | |
| | | |
| | | int main__() { |
| | | |
| | | CaptureUtil::init("同花顺(v9.10.50) - 我的页面13"); |
| | | for (int i =5;i < 6;i++) |
| | | { |
| | | cv::Mat img= CaptureUtil::capture(1); |
| | |
| | | std::ostringstream out_str; |
| | | out_str << setiosflags(ios::fixed) << std::setprecision(2) << stof(tradeData.price); |
| | | |
| | | |
| | | |
| | | ws->label(index, 0, tradeData.time, xf); |
| | | ws->label(index, 1, out_str.str(), xf); |
| | | ws->label(index, 2, tradeData.limitPrice ? L"涨停价" : L"非涨停价", xf); |
| | | if (tradeData.limitPrice == LIMIT_PRICE_NORMAL) { |
| | | ws->label(index, 2, L"正常价", xf); |
| | | } |
| | | else if (tradeData.limitPrice == LIMIT_PRICE_UP) { |
| | | ws->label(index, 2, L"涨停价", xf); |
| | | } |
| | | else if (tradeData.limitPrice == LIMIT_PRICE_DOWN) { |
| | | ws->label(index, 2, L"跌停价", xf); |
| | | } |
| | | ws->label(index, 3, to_string(tradeData.num), xf); |
| | | |
| | | |
| | |
| | | wstring operate; |
| | | switch (tradeData.operateType) |
| | | { |
| | | case BUY: |
| | | case OPERATE_BUY: |
| | | operate = L"买";break; |
| | | case BUY_CANCEL: |
| | | case OPERATE_BUY_CANCEL: |
| | | operate = L"买撤";break; |
| | | case SELL: |
| | | case OPERATE_SELL: |
| | | operate = L"卖";break; |
| | | case SELL_CANCEL: |
| | | case OPERATE_SELL_CANCEL: |
| | | operate = L"卖撤";break; |
| | | default: |
| | | break; |
New file |
| | |
| | | #pragma once |
| | | #include <string> |
| | | #include <list> |
| | | #include "json/json.h" |
| | | #include <THSActionUtil.h> |
| | | Json::Value toJson(std::list<TradeData> dataList) { |
| | | Json::Value root; |
| | | |
| | | std::list<TradeData>::iterator ele; |
| | | int index = 0; |
| | | for (ele = dataList.begin();ele != dataList.end();ele++) { |
| | | Json::Value item; |
| | | item["time"] = (*ele).time; |
| | | item["price"] = (*ele).price; |
| | | item["num"] = (*ele).num; |
| | | item["limitPrice"] = (*ele).limitPrice; |
| | | item["operateType"] = (*ele).operateType; |
| | | root[index++] = item; |
| | | } |
| | | return root; |
| | | } |
| | | |
| | | //json对象转为字符串 |
| | | std::string toJsonStr(Json::Value json) { |
| | | Json::StreamWriterBuilder writerBuilder; |
| | | //不自动换行 |
| | | writerBuilder.settings_["indentation"] = ""; |
| | | std::ostringstream os; |
| | | std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter()); |
| | | jsonWriter->write(json, &os); |
| | | string jsonStr = os.str(); |
| | | return jsonStr; |
| | | } |
| | | |
| | | std::string loadData(int clientID, int channel,string code, std::list<TradeData> dataList) { |
| | | Json::Value data; |
| | | data["channel"] = channel; |
| | | data["code"] = code; |
| | | data["data"] = toJson(dataList); |
| | | Json::Value root; |
| | | root["type"] = 0; |
| | | root["client"] = clientID; |
| | | root["data"] = data; |
| | | return toJsonStr(root); |
| | | } |
| | | |
| | | Json::Value parseJson(string data) { |
| | | Json::Value root; |
| | | Json::Reader reader; |
| | | reader.parse(data, root); |
| | | return root; |
| | | } |
| | | |
| | | |
New file |
| | |
| | | #include "pch.h" |
| | | #include "NetWorkUtil.h" |
| | | #include <windows.h> |
| | | #include <winsock.h> |
| | | #include <string> |
| | | using namespace std; |
| | | #pragma comment(lib,"wsock32.lib") |
| | | |
| | | int NetWorkUtil::get_localhost_ip(char* buff) { |
| | | struct hostent* ph = 0; |
| | | WSADATA w; |
| | | WSAStartup(0x0101, &w);//这一行必须在使用任何SOCKET函数前写! |
| | | gethostname(buff, 256); |
| | | string hostNmae = buff;//此处获得本机名称 |
| | | ph = gethostbyname(buff); |
| | | const char* IP = inet_ntoa(*((struct in_addr*)ph->h_addr_list[0]));//此处获得本机IP |
| | | WSACleanup(); |
| | | return 0; |
| | | } |
New file |
| | |
| | | #pragma once |
| | | class NetWorkUtil |
| | | { |
| | | public: |
| | | static int get_localhost_ip(char* buff); |
| | | |
| | | |
| | | |
| | | }; |
| | | |
| | |
| | | #include "pch.h" |
| | | #include "SocketManager.h" |
| | | #define CHANNEL_NUM 9 |
| | | #include <thread> |
| | | |
| | | SocketManager::SocketManager() { |
| | | init(); |
| | | SOCKET SocketManager::socketServer; |
| | | |
| | | ActionCallback SocketManager::actionCallback; |
| | | |
| | | void* SocketManager::callbackContext; |
| | | |
| | | SocketManager::SocketManager(ActionCallback callback, void* context) { |
| | | init(callback,context); |
| | | } |
| | | |
| | | SocketManager::~SocketManager() { |
| | | |
| | | } |
| | | void SocketManager::init() { |
| | | |
| | | void SocketManager::processMsg(SOCKET client, void* context) { |
| | | while (true) |
| | | { |
| | | //一直读取消息 |
| | | char recvBuff[1024]; |
| | | memset(recvBuff, 0, sizeof(recvBuff)); |
| | | int recv_len = recv(client, recvBuff, sizeof(recvBuff), 0); |
| | | if (recv_len > 0) |
| | | { |
| | | cout << "接受到操作指令:" << recvBuff << endl; |
| | | try { |
| | | bool success = actionCallback(string(recvBuff), callbackContext); |
| | | //发送操作结果 |
| | | if (success) |
| | | { |
| | | char buff[] = "OK"; |
| | | int iSend = send(client, buff, sizeof(buff), 0); |
| | | cout << "返回给客户端数据:" << buff << endl; |
| | | } |
| | | else { |
| | | char buff[] = "FAIL"; |
| | | int iSend = send(client, buff, sizeof(buff), 0); |
| | | cout << "返回给客户端数据:" << buff << endl; |
| | | } |
| | | } |
| | | catch (string st) { |
| | | char buff[] = "FAIL"; |
| | | int iSend = send(client, buff, sizeof(buff), 0); |
| | | cout << "设置采集代码出错:" << st << endl; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | void SocketManager::runSocketServer(void* context) { |
| | | //创建server |
| | | WSADATA wsaData; |
| | | WSAStartup(MAKEWORD(2, 2), &wsaData);//初始化 |
| | | socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
| | | sockaddr_in sockaddr; |
| | | sockaddr.sin_family = AF_INET; |
| | | sockaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); |
| | | sockaddr.sin_port = htons(LOCAL_SERVER_PORT); |
| | | int result; |
| | | if (bind(socketServer, (const struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { |
| | | closesocket(socketServer); |
| | | WSACleanup(); |
| | | printf("绑定失败\n"); |
| | | return; |
| | | } |
| | | //在本地绑定端口 |
| | | result = listen(socketServer, SOMAXCONN);//开始监听 |
| | | |
| | | SocketManager* sm = (SocketManager*)context; |
| | | |
| | | |
| | | printf("wait for connection...\n"); |
| | | |
| | | |
| | | while (true) |
| | | { |
| | | int nsize = sizeof(SOCKADDR); |
| | | SOCKADDR clientAddr; |
| | | SOCKET client = accept(sm->socketServer, &clientAddr, &nsize); |
| | | if (client == SOCKET_ERROR) |
| | | { |
| | | cout << "连接失败" << endl; |
| | | continue; |
| | | } |
| | | |
| | | thread msg(SocketManager::processMsg, client, context); |
| | | msg.detach(); |
| | | } |
| | | |
| | | closesocket(socketServer); |
| | | WSACleanup(); |
| | | |
| | | } |
| | | |
| | | void SocketManager::init(ActionCallback callback, void* contex) { |
| | | |
| | | actionCallback = callback; |
| | | callbackContext = contex; |
| | | clientaddr.sin_family = AF_INET; |
| | | clientaddr.sin_port = htons(PORT); |
| | | clientaddr.sin_addr.S_un.S_addr = inet_addr(ADDR); |
| | | //建立8个连接 |
| | | //建立9个连接,前8个为数据传输通道,后一个为命令传输通道 |
| | | sockClients.clear(); |
| | | for (int i = 0;i < 8;i++) |
| | | for (int i = 0;i < CHANNEL_NUM;i++) |
| | | { |
| | | addClient(i); |
| | | } |
| | | Connect(); |
| | | |
| | | thread server(SocketManager::runSocketServer, this); |
| | | server.detach(); |
| | | } |
| | | |
| | | int SocketManager::getClientsNum() { |
| | |
| | | } |
| | | |
| | | int SocketManager::Connect() { |
| | | int scount=0; |
| | | int scount = 0; |
| | | list<SOCKET>::iterator ele; |
| | | for (ele = sockClients.begin();ele != sockClients.end();++ele) { |
| | | int i = connect(*ele, (sockaddr*)&clientaddr, sizeof(clientaddr)); |
| | |
| | | } |
| | | |
| | | |
| | | BOOL SocketManager::sendMsg(int p, char* msg) { |
| | | BOOL SocketManager::sendMsg(int p, const char* msg) { |
| | | SOCKET socket = getClient(p); |
| | | char buffer[1024]; |
| | | send(socket, msg, strlen(msg), 0); |
| | |
| | | #include "framework.h" |
| | | #include <atlstr.h> |
| | | using namespace std; |
| | | |
| | | #define LOCAL_SERVER_ADDR "127.0.0.1" |
| | | #define LOCAL_SERVER_PORT 9006 |
| | | |
| | | typedef bool (*ActionCallback)(string data, void* contex); |
| | | |
| | | class SocketManager |
| | | { |
| | | |
| | | |
| | | private: |
| | | list<SOCKET> sockClients; |
| | | static SOCKET socketServer; |
| | | static void runSocketServer(void* context); |
| | | static void processMsg(SOCKET client, void* context); |
| | | const int PORT = 9001; |
| | | const char* ADDR = "127.0.0.1"; |
| | | sockaddr_in clientaddr; |
| | |
| | | //添加客户端 |
| | | void addClient(int p); |
| | | |
| | | |
| | | static void* callbackContext; |
| | | static ActionCallback actionCallback; |
| | | |
| | | public: |
| | | SocketManager(); |
| | | SocketManager(ActionCallback callback,void * context); |
| | | ~SocketManager(); |
| | | |
| | | void init(); |
| | | void init(ActionCallback callback, void* contex); |
| | | |
| | | int getClientsNum(); |
| | | |
| | |
| | | void disConnect(); |
| | | int disConnect(int p); |
| | | |
| | | BOOL sendMsg(int,char *); |
| | | BOOL sendMsg(int, const char *); |
| | | |
| | | |
| | | }; |
| | |
| | | <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
| | | </ResourceCompile> |
| | | <PostBuildEvent> |
| | | <Command>editbin /SUBSYSTEM:CONSOLE $(OutDir)\$(ProjectName).exe</Command> |
| | | </PostBuildEvent> |
| | | </ItemDefinitionGroup> |
| | | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
| | | <ClCompile> |
| | |
| | | <ClInclude Include="BasicExcelVC6.hpp" /> |
| | | <ClInclude Include="ExcelUtil.h" /> |
| | | <ClInclude Include="GUITool.h" /> |
| | | <ClInclude Include="JsonUtil.h" /> |
| | | <ClInclude Include="level2DataDlg.h" /> |
| | | <ClInclude Include="appDlg.h" /> |
| | | <ClInclude Include="framework.h" /> |
| | |
| | | <ClInclude Include="lib_json\include\json\value.h" /> |
| | | <ClInclude Include="lib_json\include\json\version.h" /> |
| | | <ClInclude Include="lib_json\include\json\writer.h" /> |
| | | <ClInclude Include="NetWorkUtil.h" /> |
| | | <ClInclude Include="pch.h" /> |
| | | <ClInclude Include="Resource.h" /> |
| | | <ClInclude Include="SocketManager.h" /> |
| | |
| | | <ClCompile Include="json_writer.cpp" /> |
| | | <ClCompile Include="level2DataDlg.cpp" /> |
| | | <ClCompile Include="appDlg.cpp" /> |
| | | <ClCompile Include="NetWorkUtil.cpp" /> |
| | | <ClCompile Include="pch.cpp"> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> |
| | |
| | | <ClInclude Include="lib_json\include\json\writer.h"> |
| | | <Filter>头文件\json</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="NetWorkUtil.h"> |
| | | <Filter>头文件</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="JsonUtil.h"> |
| | | <Filter>头文件</Filter> |
| | | </ClInclude> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClCompile Include="app.cpp"> |
| | |
| | | <ClCompile Include="json_writer.cpp"> |
| | | <Filter>源文件\json</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="NetWorkUtil.cpp"> |
| | | <Filter>源文件</Filter> |
| | | </ClCompile> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="app.rc"> |
| | |
| | | #include "appDlg.h" |
| | | #include "afxdialogex.h" |
| | | #include "level2DataDlg.h" |
| | | #include "THSActionUtil.h" |
| | | #include "NetWorkUtil.h" |
| | | #include "JsonUtil.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | |
| | | |
| | | // CappDlg 对话框 |
| | | |
| | | |
| | | |
| | | CappDlg::CappDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_APP_DIALOG, pParent) |
| | | { |
| | | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); |
| | | |
| | | socketManager = new SocketManager(); |
| | | socketManager = new SocketManager(CappDlg::OnActionCallback, this); |
| | | RecognitionUtil::init(); |
| | | CaptureUtil::init("同花顺(v9.10.50) - 热门股888");// 热门股888 |
| | | ImgUtil::init(); |
| | | capture = new ScreenDataCapture(); |
| | | |
| | | capture = new ScreenDataCapture(); |
| | | } |
| | | |
| | | void CappDlg::DoDataExchange(CDataExchange* pDX) |
| | |
| | | ON_BN_CLICKED(IDC_BUTTON10, &CappDlg::OnBnClickedButton10) |
| | | ON_BN_CLICKED(IDC_BUTTON9, &CappDlg::OnBnClickedButton9) |
| | | ON_BN_CLICKED(IDC_BUTTON4, &CappDlg::OnBnClickedButton4) |
| | | ON_BN_CLICKED(IDC_BUTTON20, &CappDlg::OnBnClickedButton20) |
| | | ON_BN_CLICKED(IDC_BUTTON5, &CappDlg::OnBnClickedButton5) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | SetIcon(m_hIcon, FALSE); // 设置小图标 |
| | | |
| | | // TODO: 在此添加额外的初始化代码 |
| | | CString st; |
| | | char ip[32]; |
| | | NetWorkUtil::get_localhost_ip(ip); |
| | | |
| | | CString ipStr(ip); |
| | | |
| | | st.Format(_T("本机IP:%s"), ipStr); |
| | | GetDlgItem(IDC_STATIC3)->SetWindowTextW(st); |
| | | |
| | | return TRUE; // 除非将焦点设置到控件,否则返回 TRUE |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | void CappDlg::OnDataCallback(int index, string code, list<TradeData> dataList, void* context) { |
| | | //转为json |
| | | CappDlg* app = (CappDlg*)context; |
| | | //cout << "回调:" << std::this_thread::get_id() << ":" << index << endl; |
| | | CButton* btn = (CButton*)app->GetDlgItem(IDC_CHECK1); |
| | | bool check = btn->GetCheck(); |
| | | if (check) { |
| | | string data = loadData(0, index, code, dataList); |
| | | app->socketManager->sendMsg(index, data.c_str()); |
| | | } |
| | | } |
| | | |
| | | |
| | | bool CappDlg::OnActionCallback(string data, void* context) { |
| | | //转为json |
| | | CappDlg* app = (CappDlg*)context; |
| | | cout << "action回调:" << std::this_thread::get_id() << ":" << data << endl; |
| | | //解析命令 |
| | | Json::Value root = parseJson(data); |
| | | if (root["action"].asString() == "setGPCode") { |
| | | //设置股票代码 |
| | | int index = root["data"]["index"].asInt(); |
| | | string code = root["data"]["code"].asString(); |
| | | string quickCode = "5"; |
| | | quickCode.append(to_string(index + 1)); |
| | | list<string> codeList; |
| | | codeList.push_back(code); |
| | | try { |
| | | |
| | | if (!app->capture->isInited()) { |
| | | throw string("采集器尚未初始化"); |
| | | } |
| | | |
| | | //暂停采集 |
| | | app->capture->stop(index); |
| | | |
| | | bool result = THSActionUtil::setGP(quickCode, codeList); |
| | | if (!result) { |
| | | throw string("设置版块监控的GP失败"); |
| | | } |
| | | |
| | | THSActionUtil::setListenL2GP(index, code); |
| | | map<int, string> results = THSActionUtil::getListenL2GPCodes(); |
| | | //设置代码 |
| | | for (map<int, string>::iterator ele = results.begin();ele != results.end();ele++) { |
| | | int key = (*ele).first; |
| | | string value = (*ele).second; |
| | | app->capture->setGPCode(key, value); |
| | | } |
| | | } |
| | | catch (string e) { |
| | | CString msg(e.c_str()); |
| | | AfxMessageBox(msg); |
| | | throw e; |
| | | } |
| | | |
| | | //恢复采集 |
| | | app->capture->start(index); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | void CappDlg::OnBnClickedButton1() |
| | | { |
| | |
| | | void CappDlg::OnBnClickedButton10() |
| | | { |
| | | socketManager->disConnect(); |
| | | socketManager->init(); |
| | | try { |
| | | socketManager->init(CappDlg::OnActionCallback, this); |
| | | } |
| | | catch (string st) { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | int scount = 0; |
| | | int num = socketManager->getClientsNum(); |
| | | for (int i = 0; i < num; i++) |
| | |
| | | //识别测试 |
| | | void CappDlg::OnBnClickedButton9() |
| | | { |
| | | |
| | | if (!capture->isInited()) |
| | | { |
| | | try { |
| | | capture->init(OnDataCallback, this); |
| | | } |
| | | catch (string st) { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | clock_t time = clock(); |
| | | list<TradeData> result = capture->captureLevel2TradeData(cv::imread("C:\\Users\\Administrator\\Desktop\\ocr\\new.jpg"), 0); |
| | | time = clock() - time; |
| | |
| | | |
| | | HWND hwndPointNow = NULL; |
| | | |
| | | hwndPointNow =(HWND) WindowFromPoint(pNow); // 获取鼠标所在窗口的句柄 |
| | | hwndPointNow = (HWND)WindowFromPoint(pNow); // 获取鼠标所在窗口的句柄 |
| | | |
| | | if (hwndPointNow) |
| | | |
| | |
| | | |
| | | |
| | | } |
| | | |
| | | //环境检测 |
| | | void CappDlg::OnBnClickedButton20() |
| | | { |
| | | try { |
| | | THSActionUtil::checkEnv(); |
| | | AfxMessageBox(_T("检测通过")); |
| | | } |
| | | catch (const string& st) { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | } |
| | | } |
| | | |
| | | |
| | | //启动任务 |
| | | void CappDlg::OnBnClickedButton5() |
| | | { |
| | | //检测环境 |
| | | |
| | | try { |
| | | THSActionUtil::checkEnv(); |
| | | } |
| | | catch (string st) { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | return; |
| | | } |
| | | |
| | | CButton* btn = (CButton*)GetDlgItem(IDC_BUTTON5); |
| | | |
| | | if (!capture->isInited()) |
| | | { |
| | | try { |
| | | capture->init(OnDataCallback, this); |
| | | } |
| | | catch (string st) { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | return; |
| | | } |
| | | } |
| | | if (!capture->isRunning()) { |
| | | |
| | | try { |
| | | map<int, string> result = THSActionUtil::getListenL2GPCodes(); |
| | | //设置代码 |
| | | for (map<int, string>::iterator ele = result.begin();ele != result.end();ele++) { |
| | | int key= (*ele).first; |
| | | string value = (*ele).second; |
| | | capture->setGPCode(key,value); |
| | | } |
| | | |
| | | } |
| | | catch (string st) { |
| | | CString msg(st.c_str()); |
| | | AfxMessageBox(msg); |
| | | return; |
| | | } |
| | | |
| | | //刷新窗口句柄 |
| | | capture->refreshHWND(); |
| | | //句柄初始化 |
| | | capture->start(); |
| | | capture->startAll(); |
| | | btn->SetWindowText(_T("暂停识别任务")); |
| | | } |
| | | else { |
| | | capture->stop(); |
| | | capture->stopAll(); |
| | | btn->SetWindowText(_T("启动识别任务")); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | #include "ScreenDataCapture.h" |
| | | #include "CaptureUtil.h" |
| | | |
| | | |
| | | |
| | | |
| | | // CappDlg 对话框 |
| | | class CappDlg : public CDialogEx |
| | | { |
| | |
| | | private: |
| | | SocketManager *socketManager; |
| | | ScreenDataCapture* capture; |
| | | void OnDataCallback(int index, list<TradeData> dataList); |
| | | static void OnDataCallback(int index,string code, list<TradeData> dataList, void* context); |
| | | static bool OnActionCallback(string data, void* context); |
| | | |
| | | |
| | | // 构造 |
| | |
| | | afx_msg void OnBnClickedButton10(); |
| | | afx_msg void OnBnClickedButton9(); |
| | | afx_msg void OnBnClickedButton4(); |
| | | afx_msg void OnBnClickedButton20(); |
| | | afx_msg void OnBnClickedButton5(); |
| | | }; |
| | |
| | | |
| | | #define ROWS 8 |
| | | #define COLS 5 |
| | | |
| | | __kernel void createBuffer(__global const float* a_in, |
| | | __global const float* b_in, |
| | | __global float* result) { |
| | | int gid = get_global_id(0); |
| | | result[gid] = a_in[gid] * b_in[gid]; |
| | | } |
| | | |
| | | __kernel void test1(__global const unsigned char* a_in, |
| | | __global const unsigned char* b_in, int width, |
| | | __kernel void recognition_numbers_1(__global const unsigned char* a_in, |
| | | __global const unsigned char* b_in, int width, int num_width, int num_height, int num_count, |
| | | __global unsigned char* result) { |
| | | |
| | | int p = get_global_id(0); |
| | | int startIndex = p / width * width * 5 * 8 + p % 170 * 5; |
| | | int startIndex = p / width * width * num_width * num_height + p % (num_count * 10) * num_width; |
| | | unsigned char t = 0; |
| | | for (int r = 0;r < 8;r++) |
| | | for (int c = 0;c < 5;c++) { |
| | | int index = startIndex + 5 * width * r + c; |
| | | t += (a_in[index] ^ b_in[index]); |
| | | for (int r = 0;r < num_height;r++) |
| | | for (int c = 0;c < num_width;c++) { |
| | | int index = startIndex + num_width * width * r + c; |
| | | t += abs(a_in[index] - b_in[index]); |
| | | if (p == 0) { |
| | | //printf("ֵ:%d-%d \n", a_in[index], b_in[index]); |
| | | } |
| | | } |
| | | result[p] = t; |
| | | } |
| | | |
| | | |
| | | __kernel void test2(__global const unsigned char* a_in, |
| | | __kernel void recognition_numbers_2(__global const unsigned char* a_in, |
| | | __global unsigned char* result) { |
| | | |
| | | int index = get_global_id(0); |
| | | int startIndex = index * 10; |
| | | int endIndex = (index + 1) * 10; |
| | | |
| | | //获取最小值 |
| | | int min = 255; |
| | | int minIndex = 11; |
| | | |
| | | for (int i = startIndex;i < endIndex;i++) |
| | | { |
| | | if (a_in[i] == 0) { |
| | | result[index] = i - startIndex; |
| | | break; |
| | | if (a_in[i] < min) { |
| | | min = a_in[i]; |
| | | minIndex = i; |
| | | } |
| | | } |
| | | |
| | | //printf("最小值:%d - %d - %d \n", index, min, minIndex - startIndex); |
| | | |
| | | result[index] = minIndex - startIndex; |
| | | } |
| | | |
| | | int get_one_level_position(int width, int x, int y) { |
| | |
| | | unsigned char get_binary_value(unsigned char v) { |
| | | return v >= 64 ? 1 : 0; |
| | | } |
| | | __kernel void test5(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, int width, |
| | | __global unsigned char* result) { |
| | | |
| | | } |
| | | |
| | | |
| | | __kernel void test4(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, int width, |
| | | __kernel void split_num(__global const unsigned char* img_in, __global const int* pos_in, __global const unsigned char* zero, int width, int num_width, int num_height, int num_count, |
| | | __global unsigned char* result) { |
| | | |
| | | int index = get_global_id(0); |
| | |
| | | //开始填充数据 |
| | | for (i = 0;i < maxNumberCount;i++) { |
| | | |
| | | unsigned char numData[8][5]; |
| | | unsigned char numData[100 * 100]; |
| | | |
| | | if (fresult[i * 2] == -1) { |
| | | //填充0 |
| | | for (int r = 0;r < 8;r++) { |
| | | for (int c = 0;c < 5;c++) { |
| | | unsigned char value = get_binary_value(zero[r * 5 + c]); |
| | | for (int r = 0;r < num_height;r++) { |
| | | for (int c = 0;c < num_width;c++) { |
| | | unsigned char value = get_binary_value(zero[r * num_width + c]); |
| | | //设置输出坐标的值 |
| | | numData[r][c] = value; |
| | | numData[r * num_width + c] = value; |
| | | } |
| | | } |
| | | |
| | |
| | | int _startx = fresult[i * 2]; |
| | | int _endx = fresult[i * 2 + 1]; |
| | | for (int r = starty;r <= endy;r++) { |
| | | for (int c = 0;c < 5;c++) { |
| | | for (int c = 0;c < num_width;c++) { |
| | | unsigned char value = 0; |
| | | if (_startx + c <= _endx) { |
| | | //填充空白0 |
| | | value = get_binary_value(img_in[get_one_level_position(width, _startx + c, r)]); |
| | | //设置输出坐标的值 |
| | | numData[r - starty][c] = value; |
| | | numData[(r - starty) * num_width + c] = value; |
| | | } |
| | | else { |
| | | numData[r - starty][c] = 0; |
| | | numData[(r - starty) * num_width + c] = 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | int rowData = ROWS * COLS * 10 * 17; |
| | | int rowData = num_height * num_width * 10 * num_count; |
| | | int rowIndex = index / 3; |
| | | int index_0 = rowData * rowIndex; |
| | | //设置坐标值 |
| | | int index_2 = 0; |
| | | if (index % 3 == 0) { |
| | | index_2 += COLS * 10 * i; |
| | | index_2 += num_width * 10 * i; |
| | | } |
| | | else if (index % 3 == 1) { |
| | | index_2 += (COLS * 10) * (6 + i); |
| | | index_2 += (num_width * 10) * (6 + i); |
| | | } |
| | | else { |
| | | index_2 += (COLS * 10) * (6 + 6 + i); |
| | | index_2 += (num_width * 10) * (6 + 6 + i); |
| | | } |
| | | |
| | | for (int re = 0;re < 10;re++) { |
| | | int index_3 = re * COLS; |
| | | for (int r = 0;r < 8;r++) { |
| | | int index_1 = r * (COLS * 10 * 17); |
| | | for (int c = 0;c < COLS;c++) { |
| | | int index_3 = re * num_width; |
| | | for (int r = 0;r < num_height;r++) { |
| | | 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 \n",index, findex); |
| | | result[findex] = numData[r][c]; |
| | | result[findex] = numData[r * num_width + c]; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | |
| | | __kernel void createTemplateNumbers(__global unsigned char* numbers, int countPerLine, |
| | | __kernel void createTemplateNumbers(__global unsigned char* numbers, int num_width, int num_height, int countPerLine, |
| | | __global unsigned char* result) { |
| | | |
| | | int gid = get_global_id(0); |
| | | int LINE_NUMBER_COUNT = countPerLine; |
| | | int NUMBER_COUNT = 10; |
| | | //unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (ROWS * lines) *COLS * NUMBER_COUNT * LINE_NUMBER_COUNT); |
| | | int outLineDataCount = ROWS * COLS * NUMBER_COUNT * LINE_NUMBER_COUNT; |
| | | int inLineDataCount = COLS * NUMBER_COUNT * LINE_NUMBER_COUNT; |
| | | int outLineDataCount = num_height * num_width * NUMBER_COUNT * LINE_NUMBER_COUNT; |
| | | int inLineDataCount = num_width * NUMBER_COUNT * LINE_NUMBER_COUNT; |
| | | |
| | | int outLineCount = outLineDataCount * gid; |
| | | for (int re = 0;re < LINE_NUMBER_COUNT;re++) { |
| | | for (int n = 0;n < NUMBER_COUNT;n++) |
| | | { |
| | | int index_num_0 = n * ROWS * COLS; |
| | | for (int r = 0;r < ROWS;r++) { |
| | | int index_num_0 = n * num_width * num_height; |
| | | for (int r = 0;r < num_height;r++) { |
| | | int intLineCount = inLineDataCount * r; |
| | | |
| | | for (int c = 0;c < COLS;c++) { |
| | | int index_num = index_num_0 + r * COLS + c; |
| | | for (int c = 0;c < num_width;c++) { |
| | | int index_num = index_num_0 + r * num_width + c; |
| | | unsigned char value = numbers[index_num]; |
| | | int index = outLineCount; |
| | | index += intLineCount; |
| | | int x = re * NUMBER_COUNT * COLS + n * COLS + c; |
| | | int x = re * NUMBER_COUNT * num_width + n * num_width + c; |
| | | index += x; |
| | | result[index] = get_binary_value(value); |
| | | } |
| | |
| | | __kernel void rgb2GrayImg(__global unsigned char* imgs, int width, |
| | | __global unsigned char* result) { |
| | | |
| | | int rowIndex= get_global_id(0); |
| | | int rowIndex = get_global_id(0); |
| | | |
| | | for (int c = 0;c < width;c++) { |
| | | int index = rowIndex * width + c; |
| | | int start = index * 3; |
| | | unsigned char R = imgs[start]; |
| | | unsigned G = imgs[start + 1]; |
| | | unsigned B = imgs[start + 2]; |
| | | unsigned char G = imgs[start + 1]; |
| | | unsigned char B = imgs[start + 2]; |
| | | result[index] = (76 * R + 150 * G + 30 * B) >> 8; |
| | | } |
| | | } |
| | | |
| | | __kernel void rgba2GrayImg(__global unsigned char* imgs, int width, |
| | | __global unsigned char* result) { |
| | | |
| | | int rowIndex = get_global_id(0); |
| | | |
| | | for (int c = 0;c < width;c++) { |
| | | int index = rowIndex * width + c; |
| | | int start = index * 4; |
| | | unsigned char R = imgs[start]; |
| | | unsigned char G = imgs[start + 1]; |
| | | unsigned char B = imgs[start + 2]; |
| | | result[index] = (76 * R + 150 * G + 30 * B) >> 8; |
| | | } |
| | | } |
| | | |
| | | |
| | | //L2非数字识别 |
| | | __kernel void recognition_not_num(__global unsigned char* imgs, __global int* rowIndexs, int width, |
| | | __global int* result) { |
| | | |
| | | int index = get_global_id(0); |
| | | int row = index / 2; |
| | | int baseIndex = row * 4 * 7; |
| | | if (index % 2 == 0) { |
| | | //涨跌停价 |
| | | //获取数据坐标 |
| | | int startx = baseIndex + 3 * 4; |
| | | int starty = startx + 1; |
| | | int endx = startx + 2; |
| | | int endy = startx + 3; |
| | | if (rowIndexs[startx] <= 0 && rowIndexs[starty] <= 0 && rowIndexs[endx] <= 0 && rowIndexs[endy] <= 0) { |
| | | result[row * 2] = 0; |
| | | } |
| | | else { |
| | | startx = rowIndexs[startx]; |
| | | starty = rowIndexs[starty]; |
| | | endx = rowIndexs[endx]; |
| | | endy = rowIndexs[endy]; |
| | | |
| | | result[row * 2] = 1; |
| | | //去除上下的空白 |
| | | for (int r = starty;r <= endy;r++) |
| | | { |
| | | bool empty = true; |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | if (get_binary_value(value)) { |
| | | empty = 0; |
| | | break; |
| | | } |
| | | } |
| | | if (!empty) { |
| | | starty = r; |
| | | break; |
| | | } |
| | | } |
| | | for (int r = endy;r >= starty;r--) |
| | | { |
| | | bool empty = true; |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | if (get_binary_value(value)) { |
| | | empty = 0; |
| | | break; |
| | | } |
| | | } |
| | | if (!empty) { |
| | | endy = r; |
| | | break; |
| | | } |
| | | } |
| | | int my = (starty + endy) / 2; |
| | | //计算上半部分的值 |
| | | int topValue = 0; |
| | | for (int r = starty;r <= my;r++) |
| | | { |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | topValue += get_binary_value(value); |
| | | |
| | | } |
| | | } |
| | | //计算下半部分的值 |
| | | int bottomValue = 0; |
| | | for (int r = my;r <= endy;r++) |
| | | { |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char value = imgs[get_one_level_position(width, c, r)]; |
| | | bottomValue += get_binary_value(value); |
| | | |
| | | } |
| | | } |
| | | |
| | | if (topValue > bottomValue) { |
| | | //涨停 |
| | | result[row * 2] = 1; |
| | | } |
| | | else { |
| | | //跌停 |
| | | result[row * 2] = 2; |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | //操作类型 |
| | | //计算值 |
| | | int startx = baseIndex + 6 * 4; |
| | | int starty = startx + 1; |
| | | int endx = startx + 2; |
| | | int endy = startx + 3; |
| | | startx = rowIndexs[startx]; |
| | | starty = rowIndexs[starty]; |
| | | endx = rowIndexs[endx]; |
| | | endy = rowIndexs[endy]; |
| | | |
| | | //printf("%d: %d %d %d %d\n",row, startx, starty, endx, endy); |
| | | |
| | | unsigned int pixelCount = 0; |
| | | for (int r = starty;r <= endy;r++) |
| | | { |
| | | for (int c = startx;c <= endx;c++) { |
| | | unsigned char val = imgs[get_one_level_position(width, c, r)]; |
| | | pixelCount+=get_binary_value(val); |
| | | } |
| | | } |
| | | |
| | | //初始化错误复制 |
| | | int value = 4; |
| | | if (abs(pixelCount - 39) < 5) { |
| | | //买 |
| | | value = 0; |
| | | } |
| | | else if (abs(pixelCount - 51) < 5) { |
| | | //卖 |
| | | value = 2; |
| | | } |
| | | else if (abs(pixelCount - 105) < 5) { |
| | | //买撤 |
| | | value = 1; |
| | | } |
| | | else if (abs(pixelCount - 117) < 5) { |
| | | //卖撤 |
| | | value = 3; |
| | | } |
| | | result[row * 2 + 1] = value; |
| | | } |
| | | |
| | | } |
| | |
| | | CString operate; |
| | | switch (data.operateType) |
| | | { |
| | | case BUY: |
| | | case OPERATE_BUY: |
| | | operate = _T("买");break; |
| | | case BUY_CANCEL: |
| | | case OPERATE_BUY_CANCEL: |
| | | operate = _T("买撤");break; |
| | | case SELL: |
| | | case OPERATE_SELL: |
| | | operate = _T("卖");break; |
| | | case SELL_CANCEL: |
| | | case OPERATE_SELL_CANCEL: |
| | | operate = _T("卖撤");break; |
| | | default: |
| | | break; |
| | |
| | | #define IDC_BUTTON10 1011 |
| | | #define IDC_LIST1 1012 |
| | | #define IDC_BUTTON1 1013 |
| | | #define IDC_BUTTON20 1014 |
| | | #define IDC_STATIC3 1016 |
| | | |
| | | // Next default values for new objects |
| | | // |
| | |
| | | #ifndef APSTUDIO_READONLY_SYMBOLS |
| | | #define _APS_NEXT_RESOURCE_VALUE 132 |
| | | #define _APS_NEXT_COMMAND_VALUE 32771 |
| | | #define _APS_NEXT_CONTROL_VALUE 1014 |
| | | #define _APS_NEXT_CONTROL_VALUE 1017 |
| | | #define _APS_NEXT_SYMED_VALUE 101 |
| | | #endif |
| | | #endif |