From 8b06b1cbf112d55307ea8a6efe711db4e7506d89 Mon Sep 17 00:00:00 2001
From: admin <weikou2014>
Date: 星期二, 07 三月 2023 10:13:47 +0800
Subject: [PATCH] 'GPU内核方法优化'

---
 ConsoleApplication/LimitUpCapture.cpp |  433 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 363 insertions(+), 70 deletions(-)

diff --git a/ConsoleApplication/LimitUpCapture.cpp b/ConsoleApplication/LimitUpCapture.cpp
index 57aba35..16ea52a 100644
--- a/ConsoleApplication/LimitUpCapture.cpp
+++ b/ConsoleApplication/LimitUpCapture.cpp
@@ -4,6 +4,7 @@
 #include "Win32Util.h"
 #include "TaskChecker.h"
 #include "GPUtil.h"
+#include "OpenCLUtil.h"
 bool LimitUpCapture::tradeTimeCapture;
 OpenCLExcuter* LimitUpCapture::openCLExcuter;
 bool LimitUpCapture::inited;
@@ -13,9 +14,13 @@
 bool LimitUpCapture::kill;
 
 CallbackFun_Limit_Up LimitUpCapture::data_callback;
+CallbackFun_First_Limit_Up LimitUpCapture::first_data_callback;
+
 MatOcrFun  LimitUpCapture::ocr_fun;
 
-std::list<cv::Point> LimitUpCapture::pointList;
+cv::Point LimitUpCapture::limitUpPoint;
+
+cv::Point LimitUpCapture::firstCodePoint;
 
 void* LimitUpCapture::context;
 
@@ -45,15 +50,17 @@
 		if (running && inited) {
 			clock_t start = clock();
 			try {
-				list<LimitUpData> codes = captureLimitUpCodes();
-				//cout << "耗时:" << clock() - start << "  数量:" << codes.size() << endl;
-				data_callback(codes, context);
-				codes.clear();
+				LimitUpFinalData finalData = captureLimitUpCodes();
+				cout << "涨停识别耗时:" << clock() - start  << endl;
+				data_callback(finalData.limitUpDatas, context);
+				first_data_callback(finalData.firstLimitUpDatas, context);
+				finalData.limitUpDatas.clear();
+				finalData.firstLimitUpDatas.clear();
 			}
 			catch (...) {
 			
 			}
-			Sleep(3000);
+			Sleep(50);
 		}
 		else {
 			Sleep(1000);
@@ -63,8 +70,9 @@
 
 bool LimitUpCapture::pause;
 
-void LimitUpCapture::init(CallbackFun_Limit_Up callback, MatOcrFun matMcrFun, void* contex) {
+void LimitUpCapture::init(CallbackFun_Limit_Up callback, CallbackFun_First_Limit_Up first_callback, MatOcrFun matMcrFun, void* contex) {
 	data_callback = callback;
+	first_data_callback = first_callback;
 	ocr_fun = matMcrFun;
 	context = contex;
 	running = false;
@@ -75,6 +83,7 @@
 	rt.detach();
 	inited = true;
 	try {
+		if(matMcrFun!=NULL)
 		refreshHWND();
 	}
 	catch (...) {
@@ -92,7 +101,7 @@
 void LimitUpCapture::refreshHWND() {
 	HWND hwnd = getWindow();
 	if (hwnd <= 0)
-		throw string("同花顺副屏2未打开");
+		throw string("同花顺副屏1未打开");
 	//输入快捷键51定位到我的版块
 	Win32Util::showWindow(hwnd);
 	Win32Util::focus(hwnd);
@@ -115,24 +124,30 @@
 	do {
 		maxCount++;
 		child = FindWindowExA(content, child, "AfxWnd100s", NULL);
+		
+		if (!Win32Util::isWindowShow(child)) {
+			continue;
+		}
 		GetWindowRect(child, &tempRect);
-	} while ((!IsWindowVisible(child) || tempRect.right - tempRect.left > tempRect.bottom - tempRect.top) && maxCount < 10);//没显示或者宽大于高
-
-	HWND temp= FindWindowExA(child, NULL, NULL, NULL);
-	for (int i = 0;i < 10;i++) {
-		GetWindowRect(temp, &tempRect);
-		if (!IsWindowVisible(temp) || tempRect.bottom - tempRect.top < 100) {
-			temp= FindWindowExA(child, temp, NULL, NULL);
+		if (tempRect.right- tempRect.left>1000) {
+			continue;
 		}
-		else {
-			break;
+
+		if (tempRect.right - tempRect.left > tempRect.bottom - tempRect.top) {
+			continue;
 		}
-	}
-	temp= FindWindowExA(temp, NULL, "block_list_page", NULL);
 
+		HWND temp =	FindWindowExA(child, NULL, "#32770", NULL);
+		if (temp > 0) {
+			temp =	FindWindowExA(temp, NULL, "block_list_page", NULL);
+			if (temp > 0) {
+				menuWin = temp;
+				break;
+			}
+		
+		}
 
-
-	menuWin = temp;
+	} while (maxCount < 20);
 
 	if (menuWin <= 0)
 		throw string("未获取到内容窗口的菜单句柄");
@@ -140,15 +155,27 @@
 	//查找菜单的位置
 	cv::Mat grayImg = ImgUtil::grayImage(CaptureUtil::capture(menuWin));
 
-	pointList.clear();
+	// 获取涨停的坐标位置
 	list<OCRResult> ocrResultList = ocr_fun("今日", grayImg);
 	if (ocrResultList.size() > 0) {
 		for (list<OCRResult>::iterator ele = ocrResultList.begin(); ele != ocrResultList.end(); ele++) {
 			OCRResult result = *ele;
-			pointList.push_back(cv::Point((result.rect.left+result.rect.right)/2, (result.rect.top + result.rect.bottom) / 2));
+			limitUpPoint = (cv::Point((result.rect.left+result.rect.right)/2, (result.rect.top + result.rect.bottom) / 2));
 			ImgUtil::markMat(grayImg, cv::Rect(result.rect.left, result.rect.top, result.rect.right - result.rect.left +1, result.rect.bottom - result.rect.top + 1), 255, 1);
+			break;
 		}
 	}
+	//获取首板的坐标位置
+	ocrResultList = ocr_fun("首板", grayImg);
+	if (ocrResultList.size() > 0) {
+		for (list<OCRResult>::iterator ele = ocrResultList.begin(); ele != ocrResultList.end(); ele++) {
+			OCRResult result = *ele;
+			firstCodePoint=(cv::Point((result.rect.left + result.rect.right) / 2, (result.rect.top + result.rect.bottom) / 2));
+			ImgUtil::markMat(grayImg, cv::Rect(result.rect.left, result.rect.top, result.rect.right - result.rect.left + 1, result.rect.bottom - result.rect.top + 1), 255, 1);
+			break;
+		}
+	}
+
 	//保存临时图片 
 	//cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\menu.jpg", grayImg);
 }
@@ -158,28 +185,18 @@
 }
 
 list<LimitUpData> LimitUpCapture::captureLimitUpCodes(cv::Mat oimg) {
-	cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);//ImgUtil::grayImage(oimg);
+	cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
 
-	uchar* imgData = (uchar*)malloc(sizeof(uchar) * oimg.rows * oimg.cols);
 	try {
-		if (oimg.channels() == 3)
-		{
-			openCLExcuter->rgb2Gray(oimg, imgData);
-		}
-		else {
-			openCLExcuter->rgba2Gray(oimg, imgData);
-		}
+		grayImg = OpenCLUtil::grayImg(openCLExcuter, oimg);
 	}
 	catch (...) {
 		//保存原始图片
 		//string path = "D:\\imgs\\img.png";
 		//cv::imwrite(path, oimg);
 		oimg.release();
-		free(imgData);
-		imgData = NULL;
 		throw string("灰度出错");
 	}
-	grayImg.data = imgData;
 
 
 
@@ -189,7 +206,6 @@
 		rowData = THSActionUtil::splitPlateRowArea(grayImg);
 	}
 	catch (string st) {
-		free(imgData);
 		throw st;
 	}
 
@@ -382,46 +398,306 @@
 	free(splitResult);
 	free(zeroData);
 	free(templateNums);
-
-	free(imgData);
-
 	grayImg.release();
 	return dataList;
 }
 
-list<LimitUpData> LimitUpCapture::captureLimitUpCodes() {
+list<FirstLimitUpCodeData> LimitUpCapture::captureLimitUpFirstCodes(cv::Mat oimg)
+{
+	cv::Mat grayImg = cv::Mat::zeros(oimg.rows, oimg.cols, CV_8UC1);
+
+	try {
+		grayImg = OpenCLUtil::grayImg(openCLExcuter, oimg);
+	}
+	catch (...) {
+		//保存原始图片
+		//string path = "D:\\imgs\\img.png";
+		//cv::imwrite(path, oimg);
+		oimg.release();
+		throw string("灰度出错");
+	}
+
+
+
+	list<int*> rowData;
+
+	try {
+		rowData = THSActionUtil::splitPlateRowArea(grayImg);
+	}
+	catch (string st) {
+		throw st;
+	}
+
+	//每行的元素个数
+	int ele_count_per_line = 6;
+	int num_length_per_ele = 6;
+	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 * num_length_per_ele;
+
+	openCLExcuter->splitPlateContentRowData(grayImg.data, grayImg.cols, grayImg.rows, rowIndex, rowData.size(), ele_count_per_line, 1, ele_count_per_line, splitResult);
+
+
+	//测试
+	set<int> excudeIndexs;
+	for (int i = 0; i < rowData.size(); i++) {
+		for (int j = 0; j < ele_count_per_line; j++) {
+			int sx = splitResult[(ele_count_per_line * i + j) * 4 + 0];
+			int sy = splitResult[(ele_count_per_line * i + j) * 4 + 1];
+			int ex = splitResult[(ele_count_per_line * i + j) * 4 + 2];
+			int ey = splitResult[(ele_count_per_line * i + j) * 4 + 3];
+			string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
+			path.append(to_string(i)).append("_").append(to_string(j)).append(".jpg");
+			//cv::imwrite(path, cv::Mat(grayImg, cv::Rect(sx, sy, ex - sx + 1, ey - sy + 1)));
+		}
+		int sx = splitResult[(ele_count_per_line * i + 1) * 4 + 0];
+		int ex = splitResult[(ele_count_per_line * i + 1) * 4 + 2];
+		if (ex - sx < 20) {
+			//噪点数据
+			excudeIndexs.insert(i);
+		}
+
+	}
+
+
+
+
+	int start = 4 * 4 * 1 + 4 * 1;
+
+	string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
+	path.append(to_string(start)).append(".jpg");
+
+	//cv::imwrite(path, cv::Mat(grayImg,cv::Rect(splitResult[start], splitResult[start+1], splitResult[start+2]- splitResult[start]+1, splitResult[start+3]- splitResult[start+1]+1)));
+
+	//cv::imwrite(path, cv::Mat(grayImg, cv::Rect(447, 102, 454-447+1,111-102+1 )));
+
+	//分割数字
+	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);
+	unsigned char types[] = { NUM_TYPE_MONEY,NUM_TYPE_MONEY,NUM_TYPE_CODE,NUM_TYPE_TIME, NUM_TYPE_PRICE,NUM_TYPE_PERCENT };
+	UcharDataInfo typesData = UcharDataInfo();
+	typesData.length = 6;
+	typesData.data = types;
+
+	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, num_length_per_ele);
+
+	//识别数字
+	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);
+	free(totalNumberData);
+
+	list<FirstLimitUpCodeData> dataList;
+	for (int i = 0; i < rowData.size(); i++) {
+		if (excudeIndexs.count(i) > 0) {
+			continue;
+		}
+		FirstLimitUpCodeData limitUpData = FirstLimitUpCodeData();
+
+		string money = "";
+		for (int j = 0; j < num_length_per_ele; j++)
+		{
+			if (j == 4) {
+				money.append(".");
+			}
+			money.append(to_string(numberResult[i][num_length_per_ele * 0 + j]));
+		}
+
+		string volume = "";
+		for (int j = 0; j < num_length_per_ele; j++)
+		{
+			if (j == 4) {
+				volume.append(".");
+			}
+			volume.append(to_string(numberResult[i][num_length_per_ele * 1 + j]));
+		}
+
+
+		string code = "";
+		for (int j = 0; j < num_length_per_ele; j++)
+		{
+			code.append(to_string(numberResult[i][num_length_per_ele * 2 + j]));
+		}
+		string time = "";
+		for (int j = 0; j < num_length_per_ele; j++)
+		{
+			if (j == 2 || j == 4) {
+				time.append(":");
+			}
+			time.append(to_string(numberResult[i][num_length_per_ele * 3 + j]));
+		}
+
+		string price = "";
+		for (int j = 0; j < num_length_per_ele; j++)
+		{
+			if (j == 4) {
+				price.append(".");
+			}
+			price.append(to_string(numberResult[i][num_length_per_ele * 4 + j]));
+		}
+
+
+
+		string percent = "";
+		for (int j = 0; j < num_length_per_ele; j++)
+		{
+			if (j == 4) {
+				percent.append(".");
+			}
+			percent.append(to_string(numberResult[i][num_length_per_ele * 5 + j]));
+		}
+		/*
+		if (percent == "0000.00") {
+			int sx = splitResult[(ele_count_per_line * i + 4) * 4 + 0];
+			int sy = splitResult[(ele_count_per_line * i + 4) * 4 + 1];
+			int ex = splitResult[(ele_count_per_line * i + 4) * 4 + 2];
+			int ey = splitResult[(ele_count_per_line * i + 4) * 4 + 3];
+			string path = "C:\\Users\\Administrator\\Desktop\\ocr\\limit_up\\";
+			path.append(to_string(i)).append("_").append(".jpg");
+			cv::imwrite(path, cv::Mat(grayImg, cv::Rect(sx, sy, ex - sx + 1, ey - sy + 1)));
+		}
+		*/
+
+		limitUpData.index = i;
+		limitUpData.code = code;
+		limitUpData.time = time;
+		limitUpData.price = price;
+		limitUpData.limitUpPercent = percent;
+		limitUpData.zyltMoney = money;
+		limitUpData.volume = volume;
+		if (limitUpData.code != "000000" && limitUpData.limitUpPercent != "0000.00") {
+			dataList.push_back(limitUpData);
+		}
+		else {
+			cout <<"出错"<< endl;
+		}
+		free(numberResult[i]);
+	}
+	free(numberResult);
+
+	if (dataList.size() > 0)
+	{
+		int* unitData = (int*)malloc(sizeof(int) * 4 * dataList.size() * 2 );
+		//识别金额单位
+		int index = 0;
+		for (list<FirstLimitUpCodeData>::iterator ele = dataList.begin(); ele != dataList.end(); ele++) {
+			unitData[index * 4 * 2 + 0] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 0];
+			unitData[index * 4 * 2 + 1] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 1];
+			unitData[index * 4 * 2 + 2] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 2];
+			unitData[index * 4 * 2 + 3] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 0 + 3];
+
+			unitData[index * 4 * 2 + 4] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 0];
+			unitData[index * 4 * 2 + 5] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 1];
+			unitData[index * 4 * 2 + 6] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 2];
+			unitData[index * 4 * 2 + 7] = splitResult[(*ele).index * 4 * ele_count_per_line + 4 * 1 + 3];
+
+			index++;
+		}
+		int* unitResult = (int*)malloc(sizeof(int) * dataList.size() * 2);
+		openCLExcuter->recognitionPlateMoneyUnit(grayImg.data, grayImg.cols, grayImg.rows, unitData, 2, dataList.size(), unitResult);
+		index = 0;
+		for (list<FirstLimitUpCodeData>::iterator ele = dataList.begin(); ele != dataList.end(); ele++) {
+			switch (unitResult[index*2])
+			{
+			case 0:
+				(*ele).zyltMoneyUnit = MONEY_UNIT_Y;
+				break;
+			case 1:
+				(*ele).zyltMoneyUnit = MONEY_UNIT_W;
+				break;
+			default:
+				break;
+			}
+
+			switch (unitResult[index * 2 + 1])
+			{
+			case 0:
+				(*ele).volumeUnit = MONEY_UNIT_Y;
+				break;
+			case 1:
+				(*ele).volumeUnit = MONEY_UNIT_W;
+				break;
+			case 2:
+				(*ele).volumeUnit = MONEY_UNIT_NO;
+				(*ele).volume = to_string((int)(stof((*ele).volume) * 100));
+				break;
+			default:
+				break;
+			}
+
+			index++;
+		}
+		free(unitData);
+		free(unitResult);
+	}
+	free(rowIndex);
+	free(splitResult);
+	free(zeroData);
+	free(templateNums);
+	grayImg.release();
+	return dataList;
+}
+
+LimitUpFinalData LimitUpCapture::captureLimitUpCodes() {
 	cout << "开始运行" << endl;
 	HWND hwnd = getWindow();
 	cout << "同花顺句柄:"<< hwnd << endl;
 
 	RECT wrect;
 	GetWindowRect(win, &wrect);
-	list<LimitUpData> flist;
-	set<string> codesSet;
-	string codestr = "";
-
 	RECT menuRect;
 	GetWindowRect(menuWin, &menuRect);
 
-	list<cv::Point>::iterator ele;
-	for (ele = pointList.begin();ele != pointList.end();ele++) {
+	LimitUpFinalData finalDatas;
+	list<LimitUpData> limitUpList;
+	list<FirstLimitUpCodeData> firstLimitUpList;
+	for (int n = 0; n < 2;n++) {
+		set<string> codesSet;
 		if (kill) {
 			break;
 		}
-		//暂停 暂时注释掉
-		//while (pause) {
-		//	cout <<"涨停识别暂停"<< endl;
-		//	Sleep(100);
-		//}
-		int x = (*ele).x;//+ menuRect.left;
-		int y = (*ele).y;//+ menuRect.top;
+
+		
+
+		int x = 0;
+		int y = 0;
+		if (n == 0) {
+			x =	limitUpPoint.x;
+			y = limitUpPoint.y;
+		}
+		else {
+			x = firstCodePoint.x;
+			y = firstCodePoint.y;
+		}
+
 		printf("x:%d y:%d\n", x, y);
 	    PostMessage(menuWin, WM_LBUTTONDOWN, 0, MAKELONG(x, y));
 		Sleep(10);
 		PostMessage(menuWin, WM_LBUTTONUP, 0, MAKELONG(x, y));
 		Sleep(50);
+
+
 		
-		for (int i = 0;i < 2;i++)
+		for (int i = 0;i < 3;i++)
 		{
 			if (kill) {
 				break;
@@ -431,29 +707,46 @@
 			PostMessage(win, WM_MOUSEWHEEL, 0, MAKEWORD(x, y));
 			Sleep(200);
 			cv::Mat oimg = CaptureUtil::capture(win);
-			try {
-				list<LimitUpData> codes = captureLimitUpCodes(oimg);
-				for (list<LimitUpData>::iterator e = codes.begin();e != codes.end();e++) {
-					string code = (*e).code;
-					if (codesSet.count(code) == 0) {
-						codesSet.insert(code);
-						flist.push_back(*e);
+			if (n == 0)
+			{
+				try {
+					list<LimitUpData> codes = captureLimitUpCodes(oimg);
+					for (list<LimitUpData>::iterator e = codes.begin(); e != codes.end(); e++) {
+						string code = (*e).code;
+						if (codesSet.count(code) == 0) {
+							codesSet.insert(code);
+							limitUpList.push_back(*e);
+						}
 					}
+					codes.clear();
 				}
-				codes.clear();
+				catch (string e) {
+					cout << e << endl;
+				}
 			}
-			catch (string e) {
-				cout << e << endl;
-			}
+			else {
+				try {
+					list<FirstLimitUpCodeData> codes = captureLimitUpFirstCodes(oimg);
+					for (list<FirstLimitUpCodeData>::iterator e = codes.begin(); e != codes.end(); e++) {
+						string code = (*e).code;
+						if (codesSet.count(code) == 0) {
+							codesSet.insert(code);
+							firstLimitUpList.push_back(*e);
+						}
+					}
+					codes.clear();
+				}
+				catch (string e) {
+					cout << e << endl;
+				}
 			
+			}	
 			Sleep(50);
 		}
 	}
-
-
-	
-	return flist;
-
+	finalDatas.limitUpDatas = limitUpList;
+	finalDatas.firstLimitUpDatas = firstLimitUpList;
+	return finalDatas;
 }
 
 //全部开始

--
Gitblit v1.8.0