#include "THSDXJLCapture.h" #include "GPUtil.h" #include "OpenCLUtil.h" #include "THSActionUtil.h" #include "CaptureUtil.h" #include #include "MD5.h" #include OpenCLExcuter* THSDXJLCapture::openCLExcuter; bool THSDXJLCapture::tradeTimeCapture; bool THSDXJLCapture::running; CallbackFun_DXJL_OCR THSDXJLCapture::ocr_fun; void THSDXJLCapture::_run() { while (TRUE) { if (tradeTimeCapture) { if (!GPUtil::isTradeTime()) { Sleep(2); continue; } } if (GPUtil::isBeforeTradeTime()) { Sleep(1000); } if (running) { try { DXJLResult result = capture(); map md5CodeNameMap; int count = 0; // API for (std::list::iterator ele = result.contentList.begin(); ele != result.contentList.end(); ele++) { DXJLOCRContent content = *ele; if (md5CodeNameMap.find(content.codeNameMD5) == md5CodeNameMap.end()) { //mgUtil::markMat(grayImg, rect, 255, 1); cv::Rect rect = content.codeNamePos; rect.x = rect.x - 2; rect.y = rect.y - 2; rect.width = rect.width + 4; rect.height = rect.height + 4; //cv::imwrite(string("C:\\Users\\Administrator\\Desktop\\ocr\\dxjl\\code_name_").append(to_string(count)).append(".png"), cv::Mat(result.grayImg, rect)); count++; cv::Mat mat = cv::Mat::zeros(rect.height, rect.width, CV_8UC1); for (int r = rect.y; r < rect.y + rect.height; r++) { for (int c = rect.x; c < rect.x + rect.width; c++) { mat.ptr(r - rect.y)[c - rect.x] = result.grayImg.ptr(r)[c]; } } string code = ocr_fun(mat); mat.release(); md5CodeNameMap[content.codeNameMD5] = code; } } list eventList; for (std::list::iterator ele = result.contentList.begin(); ele != result.contentList.end(); ele++) { DXJLOCRContent content = *ele; DXJLEvent event; event.time = content.time; event.code = md5CodeNameMap[content.codeNameMD5]; eventList.push_back(event); } } catch (...) { } } Sleep(5); } } std::list THSDXJLCapture::splitRows(cv::Mat img, int contentStartRow, std::list dataColIndexs) { //·Ö¸ôÿһÐеÄÊý¾Ý std::list dataItemList; int startf = 0; int endf = 0; std::list::iterator ele; for (ele = dataColIndexs.begin(); ele != dataColIndexs.end(); ele++) { //LogUtil::debug("µØÖ·£º%d \n",*ele); int startCol = **ele; int endCol = *(*ele + 1); free(*ele); //×ܹ²µÄÊý¾ÝÊýÁ¿ int dataCount = 0; for (int i = contentStartRow; i < img.rows; i++) { bool empty = ImgDivider::isRowEmpty(img, i, startCol, endCol, 2, 64); if (empty) { if (startf > -1 && endf > -1) { //ÄÚÈÝ×ø±ê //LogUtil::debug("ÄÚÈݵĸ߶ÈΪ£º%d \n", endf - startf); //ÐÐÊý¾Ý¸ß´óÓÚ6²ÅΪÓÐЧµÄÐÐ¸ß if (endf - startf > 6) { int* dd = (int*)malloc(sizeof(int) * 4); *dd = startCol; *(dd + 1) = startf; *(dd + 2) = endCol; *(dd + 3) = endf; dataItemList.push_back(dd); } dataCount++; } startf = -1; endf = -1; } else { //Êý¾Ý¿ªÊ¼ if (startf == -1) { startf = i; endf = i; } else { endf = i; } //Êý¾Ý½áÊø } } } return dataItemList; } std::list THSDXJLCapture::split(cv::Mat mat) { bool empty = false; int startRow = -1; for (int r =10; r < mat.rows; r++) { if (ImgDivider::isRowEmpty(mat, r, 0, mat.cols-50, 1)) { empty = TRUE; } else { if (empty) { startRow = r; break; } } } cout << "ÆðʼÐУº" << startRow << endl; int last_col = -1; std::list colsIndex; for (int c = 0; c < mat.cols; c++) { //·Ö¸îÁÐ int endRow = startRow + 100; if (endRow >= mat.rows) { endRow = mat.rows - 1; } if (ImgDivider::isColFull(mat, c, startRow, endRow, 2)) { if (c - last_col > 20) { int* pos = (int*)malloc(sizeof(int) * 2); pos[0] = last_col + 1; pos[1] = c - 1; colsIndex.push_back(pos); } last_col = c; } } if (mat.cols - last_col > 20) { int* pos = (int*)malloc(sizeof(int) * 2); pos[0] = last_col + 1; pos[1] = mat.cols - 1; colsIndex.push_back(pos); } return splitRows(mat, startRow, colsIndex); } string THSDXJLCapture::md5Mat(cv::Mat grayImg) { string st=""; for (int r = 0; r < grayImg.rows; r++) { for (int c = 0; c < grayImg.cols; c++) { uchar val = grayImg.ptr(r)[c]; if (val >= _IMG_BINARY_THRESHOLD) { val = 1; } else { val = 0; } st.append(to_string(val)).append(","); } st.append("#"); } return MD5(st).toStr(); } DXJLResult THSDXJLCapture::capture() { HWND hwnd = THSActionUtil::getDXJLWindow(); if (hwnd <= 0) { throw string("ÉÐδ»ñÈ¡µ½¶ÌÏß¾«Áé´°¿Ú"); } return capture(hwnd); } DXJLResult THSDXJLCapture::capture(HWND hwnd) { cv::Mat img = CaptureUtil::capture(hwnd); return capture(img, openCLExcuter); } void THSDXJLCapture::init(CallbackFun_DXJL_OCR matOcrFun) { ocr_fun = matOcrFun; openCLExcuter = new OpenCLExcuter(); openCLExcuter->init(); thread rt(&(_run)); rt.detach(); inited = TRUE; } bool THSDXJLCapture::is_inited() { return inited; } void THSDXJLCapture::start() { running = TRUE; } void THSDXJLCapture::stop() { running = FALSE; } bool THSDXJLCapture::is_running() { return running; } DXJLResult THSDXJLCapture::capture(cv::Mat img, OpenCLExcuter* openCLExcuter) { cv::Mat grayImg = OpenCLUtil::grayImg(openCLExcuter, img); std::list contentList = captureGray(grayImg, openCLExcuter); for (std::list::iterator ele = contentList.begin(); ele != contentList.end(); ele++) { cv::Rect rect = (*ele).codeNamePos; string md5 = md5Mat(cv::Mat(grayImg,rect)); (*ele).codeNameMD5 = md5; //ImgUtil::markMat(grayImg, rect, 255, 1); } //¹¹Ôìʶ±ðͼÐÎ //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\dxjl\\mark1.png",grayImg); return DXJLResult({ contentList ,grayImg }); } std::list THSDXJLCapture::captureGray(cv::Mat grayImg, OpenCLExcuter* openCLExcuter) { std::list rowDataList = split(grayImg); int* rowDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4); int index = 0; for (list::iterator e = rowDataList.begin(); e != rowDataList.end(); e++) { int* indexs = *e; rowDataOneLevel[index * 4 + 0] = indexs[0]; rowDataOneLevel[index * 4 + 1] = indexs[1]; rowDataOneLevel[index * 4 + 2] = indexs[2]; rowDataOneLevel[index * 4 + 3] = indexs[3]; index++; free(indexs); } //·Ö¸ôÔªËØ int line_ele_count = 4; int* rowSplitResultDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4 * line_ele_count); std::list timeRectList; std::list contentList; try { openCLExcuter->splitRowData(grayImg, rowDataOneLevel, rowDataList.size(), line_ele_count, rowSplitResultDataOneLevel); free(rowDataOneLevel); //Êý¾ÝÊÕ¼¯ for (int i = 0; i < rowDataList.size(); i++) { DXJLOCRContent content; for (int p = 0; p < line_ele_count; p++) { int start_index = i * line_ele_count * 4 + p * 4; int start_x = rowSplitResultDataOneLevel[start_index + 0]; int start_y = rowSplitResultDataOneLevel[start_index + 1]; int end_x = rowSplitResultDataOneLevel[start_index + 2]; int end_y = rowSplitResultDataOneLevel[start_index + 3]; cv::Rect rect = cv::Rect(start_x, start_y, end_x - start_x + 1, end_y - start_y + 1); //ImgUtil::markMat(grayImg, rect, 255, 1); switch (p) { case 0: timeRectList.push_back(rect); break; case 1: { content.codeNamePos = rect; } break; case 2: content.eventNamePos = rect; break; case 3: content.eventParamsPos = rect; break; default: break; } } contentList.push_back(content); } free(rowSplitResultDataOneLevel); } catch (string st) { cout << "³ö´í£º" << st << endl; } catch (...) { grayImg.release(); grayImg = NULL; free(rowDataOneLevel); free(rowSplitResultDataOneLevel); throw string("ͼÏñϸ·Ö³ö´í"); } //±£´æ·Ö¸ôÄÚÈÝ //cv::imwrite("C:\\Users\\Administrator\\Desktop\\ocr\\dxjl\\mark1.png",grayImg); //------------ʱ¼äʶ±ð-------------- //ÿÐеÄÔªËØ¸öÊý int ele_count_per_line = 1; int num_length_per_ele = 6; int lines = timeRectList.size(); int* rowIndex = (int*)malloc(sizeof(int) * 4 * lines * ele_count_per_line); int count = 0; for (std::list::iterator ele = timeRectList.begin(); ele != timeRectList.end(); ele++) { cv::Rect rect = *ele; rowIndex[4 * count + 0] = rect.x; rowIndex[4 * count + 1] = rect.y; rowIndex[4 * count + 2] = rect.x + rect.width - 1; rowIndex[4 * count + 3] = rect.y + rect.height - 1; count++; } int line_number_count = ele_count_per_line * num_length_per_ele; //·Ö¸îÊý×Ö unsigned char* zeroData = (unsigned char*)malloc(sizeof(unsigned char) * _NUMBER_L2_WIDTH * _NUMBER_L2_HEIGHT); for (int r = 0; r < _NUMBER_L2_HEIGHT; r++) { for (int c = 0; c < _NUMBER_L2_WIDTH; c++) { zeroData[r * _NUMBER_L2_WIDTH + c] = ImgUtil::NUMS_LEVEL2[0].data.ptr(r)[c]; } } unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * lines) * _NUMBER_L2_WIDTH * 10 * line_number_count); unsigned char types[] = { NUM_TYPE_TIME }; UcharDataInfo typesData = UcharDataInfo(); typesData.length = 1; typesData.data = types; openCLExcuter->splitL2NumNew(grayImg, IntDataInfo({ rowIndex,(int)(ele_count_per_line * lines) }), UcharDataInfo({ totalNumberData, -1 }), typesData, zeroData, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, ele_count_per_line, num_length_per_ele); free(rowIndex); //ʶ±ðÊý×Ö uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_L2_HEIGHT * lines) * _NUMBER_L2_WIDTH * 10 * line_number_count); openCLExcuter->createNumberTemplates(lines, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count, ImgUtil::numsOneLevel_level2, templateNums); uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, lines * _NUMBER_L2_HEIGHT, _NUMBER_L2_WIDTH * 10 * line_number_count, _NUMBER_L2_WIDTH, _NUMBER_L2_HEIGHT, line_number_count); free(totalNumberData); free(templateNums); index = 0; for (std::list::iterator ele = contentList.begin(); ele != contentList.end(); ele++) { DXJLOCRContent content = *ele; string time = ""; for (int j = 0; j < num_length_per_ele; j++) { if (j == 2 || j == 4) { time.append(":"); } time.append(to_string(numberResult[index][j])); } free(numberResult[index]); (*ele).time = time; index++; if (time == "00:00:00") { cout << "´íÎóʶ±ð£º" << index << endl; } } free(numberResult); cout << "×ÜÊý£º" << contentList.size() << endl; return contentList; }