#include "RecognitionManager.h" RecognitionManager::RecognitionManager() { openCLExcuter = new OpenCLExcuter(); openCLExcuter->init(); } RecognitionManager::~RecognitionManager() { openCLExcuter->destory(); } TradeData RecognitionManager::recognition(cv::Mat img, int* rowData) { TradeData tradeData = {}; for (int index = 1;index < 8;index++) { switch (index) { //ʱ¼ä case 1: { /* int startX = *(*ele + 1); int startY = *(*ele); int endX = *(*ele + 3); int endY = *(*ele + 2); string time= recognitionTime(cv::Mat(img, cv::Rect(startX, startY, endX - startX + 1, endY - startY + 1))); tradeData.time = time; LogUtil::debug("ʶ±ðʱ¼ä£º%s", tradeData.time.c_str()); */ } break; //Âò³·Ê±¼ä case 2: { ; }break; //¼Û¸ñ case 3: { /* int startX = *(*ele + 1); int startY = *(*ele); int endX = *(*ele + 3); int endY = *(*ele + 2); (tradeData).price = recognitionPrice(cv::Mat(img, cv::Rect(startX, startY, endX - startX + 1, endY - startY + 1))); */ ; } break; //ÊÇ·ñÕÇÍ£¼Û case 4: { if (rowData[(index-1) * 4] > 0) { //ÕÇÍ£ (tradeData).limitPrice = LIMIT_PRICE_UP; } else { (tradeData).limitPrice = LIMIT_PRICE_NORMAL; } } break; //½ð¶î case 5: { ; }break; //ÊÖÊý case 6: { /* int startX = *(*ele + 1); int startY = *(*ele); int endX = *(*ele + 3); int endY = *(*ele + 2); string num = recognitionNum(cv::Mat(img, cv::Rect(startX, startY, endX - startX + 1, endY - startY + 1))); (tradeData).num = stoi(num); */ ; } break; //ÀàÐÍ case 7: { int startX = rowData[(index-1) * 4]; int startY = rowData[(index - 1) * 4 + 1]; int endX = rowData[(index - 1) * 4 + 2]; int endY = rowData[(index - 1) * 4 + 3]; (tradeData).operateType = recognitionOperate(cv::Mat(img, cv::Rect(startX, startY, endX - startX + 1, endY - startY + 1))); } break; default: break; } } return tradeData; } //ʶ±ðËùÓеÄÊý¾Ý list RecognitionManager::recognition(cv::Mat img, int* rowDataList, int lines) { list resultList; for (int i = 0;i < lines;i++) { int* rowData=(int*)malloc(sizeof(int)*4*7); for (int j = 0;j < 4 * 7;j++) { rowData[j] = rowDataList[i * 4 * 7 + j]; } TradeData result = recognition(img, rowData); free(rowData); resultList.push_back(result); } return resultList; } std::string RecognitionManager::recognitionTime(std::string cpath) { cv::Mat src = imread(cpath.c_str(), cv::IMREAD_GRAYSCALE); return recognitionTime(src); } std::string RecognitionManager::recognitionTime(cv::Mat src) { //´òÓ¡³öÊý¾Ý cv::Mat binary; //È¥³ýÉÏϵĿհ×ͼ threshold(src, binary, 20, 255, cv::THRESH_BINARY); int rows = src.rows; int cols = src.cols; //ÉÏϵİױßÈ¥³ý int startRow = -1; int endRow = -1; for (int r = 0;r < rows;r++) { if (!ImgDivider::isRowEmpty(binary, r)) { startRow = r; break; } } for (int r = rows - 1;r > -1;r--) { if (!ImgDivider::isRowEmpty(binary, r)) { endRow = r; break; } } //ðºÅµÄµäÐÍÌØÕ÷0001000 //-----------´ÓÖмäÍùÁ½±ß±éÀú²éÕÒðºÅ·Ö¸ô·û---------- int s = cols / 2; int i; //Íùǰ²éÕÒðºÅ int m1_s = -1, m1_e = -1, m2_s = -1, m2_e = -1; uchar* temp = (uchar*)malloc(sizeof(uchar) * 7); for (i = s;i > -1;i--) { if (i < 6) { break; } *temp = binary.ptr(endRow)[i]; *(temp + 1) = binary.ptr(endRow)[i - 1]; *(temp + 2) = binary.ptr(endRow)[i - 2]; *(temp + 3) = binary.ptr(endRow)[i - 3]; *(temp + 4) = binary.ptr(endRow)[i - 4]; *(temp + 5) = binary.ptr(endRow)[i - 5]; *(temp + 6) = binary.ptr(endRow)[i - 6]; if (*(temp + 3) > 0 && binary.ptr(endRow - 1)[i - 3] == 0) { int t = *temp + *(temp + 1) + *(temp + 2) + *(temp + 4) + *(temp + 5) + *(temp + 6); if (t == 0) { m1_s = i - 6; m1_e = i; break; } } } //Íùºó²éÕÒðºÅ for (i = s;i < cols;i++) { if (i > cols - 6) { break; } *temp = binary.ptr(endRow)[i]; *(temp + 1) = binary.ptr(endRow)[i + 1]; *(temp + 2) = binary.ptr(endRow)[i + 2]; *(temp + 3) = binary.ptr(endRow)[i + 3]; *(temp + 4) = binary.ptr(endRow)[i + 4]; *(temp + 5) = binary.ptr(endRow)[i + 5]; *(temp + 6) = binary.ptr(endRow)[i + 6]; if (*(temp + 3) > 0 && binary.ptr(endRow - 1)[i + 3] == 0) { int t = *temp + *(temp + 1) + *(temp + 2) + *(temp + 4) + *(temp + 5) + *(temp + 6); if (t == 0) { m2_s = i; m2_e = i + 6; break; } } } free(temp); if (m1_s < 0 || m1_e < 0 || m2_s < 0 || m2_e < 0) { //δ²éѯµ½·Ö¸ô·û return ""; } cv::Mat nums[3]; //»ñÈ¡·Ö¸ôÊý×Ö×ø±ê(ʱ£¬·Ö£¬Ãë) nums[0] = cv::Mat(binary, cv::Rect(0, startRow, m1_s - 1 - (0) + 1, endRow - startRow + 1)); nums[1] = cv::Mat(binary, cv::Rect(m1_e + 1, startRow, (m2_s - 1) - (m1_e + 1) + 1, endRow - startRow + 1)); nums[2] = cv::Mat(binary, cv::Rect(m2_e + 1, startRow, (cols - 1) - (m2_e + 1) + 1, endRow - startRow + 1)); //È¥³ýǰºóµÄ¿Õ°× for (int i = 0;i < 3;i++) { int cols = nums[i].cols; int rows = nums[i].rows; int start = 0; int end = cols - 1; int j; for (j = 0;j < cols;j++) { if (!ImgDivider::isColEmpty(nums[i], j, 1)) { start = j; break; } } for (j = cols - 1;j > -1;j--) { if (!ImgDivider::isColEmpty(nums[i], j, 1)) { end = j; break; } } nums[i] = cv::Mat(nums[i], cv::Rect(start, 0, end - start + 1, rows)); } LogUtil::debug("·Ö¸ô½áÊø", NULL); std::string time = ""; //¸ù¾ÝÏñËØÖµ±£´æ for (int i = 0;i < 3;i++) { int data = 0; for (int r = 0;r < nums[i].rows;r++) { for (int c = 0;c < nums[i].cols;c++) { data += nums[i].ptr(r)[c] > 0 ? 1 : 0; } } //ʶ±ðʱ¼ä std::string temp = recognitionNum(nums[i]); time = time.append(temp); if (i < 2) { time = time.append(":"); } /*std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\"; path = path.append(std::to_string(rand())); path = path.append(".jpg"); try { LogUtil::debug("±£´æÃû³Æ:%s\n",path.c_str() ); imwrite(path, nums[i]); }catch (...) { }*/ } //ʶ±ð return time; } std::string RecognitionManager::recognitionNum(std::string cpath) { cv::Mat src = cv::imread(cpath.c_str(), cv::IMREAD_GRAYSCALE); return recognitionNum(src); } std::string RecognitionManager::recognitionNum(cv::Mat src) { //´òÓ¡³öÊý¾Ý cv::Mat binary; LogUtil::debug("·Ö¸ô¿ªÊ¼", NULL); //È¥³ýÉÏϵĿհ×ͼ threshold(src, binary, 40, 255, cv::THRESH_BINARY); int rows = src.rows; int cols = src.cols; //ÉÏϵİױßÈ¥³ý int startRow = -1; int endRow = -1; for (int r = 0;r < rows;r++) { if (!ImgDivider::isRowEmpty(binary, r)) { startRow = r; break; } } for (int r = rows - 1;r > -1;r--) { if (!ImgDivider::isRowEmpty(binary, r)) { endRow = r; break; } } binary = cv::Mat(binary, cv::Rect(0, startRow, cols, endRow - startRow + 1)); rows = binary.rows; cols = binary.cols; //·Ö¸îÊý×Ö std::list numberCols; int c, startC = -1, endC = -1; for (c = 0;c < cols;c++) { if (ImgDivider::isColEmpty(binary, c, 1)) { if (startC > -1 && endC > -1) { int* data = (int*)malloc(sizeof(int) * 2); *data = startC; *(data + 1) = endC; numberCols.push_back(data); } startC = -1; endC = -1; } else { if (startC == -1) { startC = c; endC = c; } else { endC = c; } } } if (startC > -1 && endC > -1) { int* data = (int*)malloc(sizeof(int) * 2); *data = startC; *(data + 1) = endC; numberCols.push_back(data); } std::string numStr = ""; std::list::iterator ele; for (ele = numberCols.begin(); ele != numberCols.end();ele++) { int start = **ele; int end = *(*ele + 1); LogUtil::debug("start-%d end-%d", start, end); free(*ele); cv::Mat img = cv::Mat(binary, cv::Rect(start, 0, end - start + 1, rows)); //imshow("·Ö¸îͼ", img); std::string num = RecognitionUtil::getNumber(img); numStr.append(num); LogUtil::debug("ʶ±ð½á¹ûΪ:%s\n", num.c_str()); /*std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\"; path = path.append(std::to_string(rand())); path = path.append(".jpg"); try { LogUtil::debug("±£´æÃû³Æ:%s\n", path.c_str()); imwrite(path, img); } catch (...) { }*/ } //ʶ±ð return numStr; } //set pixelSet; OperateType RecognitionManager::recognitionOperate(std::string cpath) { cv::Mat src = cv::imread(cpath.c_str(), cv::IMREAD_GRAYSCALE); return recognitionOperate(src); } OperateType RecognitionManager::recognitionOperate(cv::Mat src) { //´òÓ¡³öÊý¾Ý cv::Mat binary; LogUtil::debug("·Ö¸ô¿ªÊ¼", NULL); //È¥³ýÉÏϵĿհ×ͼ threshold(src, binary, 64, 255, cv::THRESH_BINARY); int rows = src.rows; int cols = src.cols; //imshow("²Ù×÷ͼ", binary); //¼ÆËãÏñËØÖµ int pixelCount = 0; for (int i = 0;i < rows;i++) { for (int j = 0;j < cols;j++) { uchar data = binary.ptr(i)[j]; if (data > 0) { pixelCount++; } } } //39 51 105 117 //LogUtil::debug("ÏñËØÖµ£º%d\n", pixelCount); if (abs(pixelCount - 39) < 5) { return OPERATE_BUY; } else if (abs(pixelCount - 51) < 5) { return OPERATE_SELL; } else if (abs(pixelCount - 105) < 5) { return OPERATE_BUY_CANCEL; } else if (abs(pixelCount - 117) < 5) { return OPERATE_SELL_CANCEL; } //pixelSet.insert(pixelCount); //LogUtil::debug("ÏñËØÖÖÀà:"); //for (auto it = pixelSet.cbegin(); it != pixelSet.cend(); it++) //{ // LogUtil::debug("%d ", *it); //} //LogUtil::debug("\n"); //std::string path = "C:\\Users\\Administrator\\Desktop\\ocr\\"; //path = path.append(std::to_string(rand())); //path = path.append(".jpg"); //try { // LogUtil::debug("±£´æÃû³Æ:%s\n", path.c_str()); // imwrite(path, binary); //} //catch (...) { //} return OPERATE_OPERATE_ERROR; } std::string RecognitionManager::recognitionPrice(std::string cpath) { cv::Mat src = cv::imread(cpath.c_str(), cv::IMREAD_GRAYSCALE); return recognitionPrice(src); } std::string RecognitionManager::recognitionPrice(cv::Mat src) { //´òÓ¡³öÊý¾Ý cv::Mat binary; LogUtil::debug("·Ö¸ô¿ªÊ¼", NULL); //È¥³ýÉÏϵĿհ×ͼ threshold(src, binary, 40, 255, cv::THRESH_BINARY); int rows = src.rows; int cols = src.cols; //ÉÏϵİױßÈ¥³ý int startRow = -1; int endRow = -1; for (int r = 0;r < rows;r++) { if (!ImgDivider::isRowEmpty(binary, r)) { startRow = r; break; } } for (int r = rows - 1;r > -1;r--) { if (!ImgDivider::isRowEmpty(binary, r)) { endRow = r; break; } } binary = cv::Mat(binary, cv::Rect(0, startRow, cols, endRow - startRow + 1)); rows = binary.rows; cols = binary.cols; int i; //Íùǰ²éÕÒСÊýµã int m_s = -1, m_e = -1; uchar* temp = (uchar*)malloc(sizeof(uchar) * 6); for (i = 0;i < cols;i++) { if (i > cols - 5) { break; } *temp = binary.ptr(rows - 1)[i]; *(temp + 1) = binary.ptr(rows - 1)[i + 1]; *(temp + 2) = binary.ptr(rows - 1)[i + 2]; *(temp + 3) = binary.ptr(rows - 1)[i + 3]; *(temp + 4) = binary.ptr(rows - 1)[i + 4]; *(temp + 5) = binary.ptr(rows - 1)[i + 5]; if (*(temp + 2) > 0 && ImgDivider::isColEmpty(binary, i + 2, 0, rows - 2)) { int t = *temp + *(temp + 1) + *(temp + 3) + *(temp + 4) + *(temp + 5); if (t == 0) { m_s = i; m_e = i + 5; break; } } } cv::Mat dotBefore = cv::Mat(binary, cv::Rect(0, 0, m_s, rows)); cv::Mat dotAfter = cv::Mat(binary, cv::Rect(m_e + 1, 0, cols - (m_e + 1), rows)); std::string dotB = recognitionNum(dotBefore); std::string dotE = recognitionNum(dotAfter); std::string st = ""; st.append(dotB); st.append("."); st.append(dotE); LogUtil::debug("ʶ±ð½á¹û£º%s\n", st.c_str()); return st; } list RecognitionManager::recognitionGPCode(list imgList) { unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * imgList.size()); list::iterator ele; int i = 0; for (ele= imgList.begin();ele!= imgList.end();++ele) { int index_2 = i * 10 * _NUMBER_GP_CODE_WIDTH; for (int n = 0;n < 10;n++) { int index_3= n * _NUMBER_GP_CODE_WIDTH; cv::Mat img = ImgUtil::formatNumGPCode(*ele); for (int r = 0;r < _NUMBER_GP_CODE_HEIGHT;r++) { int index_1 = r * imgList.size()* 10 * _NUMBER_GP_CODE_WIDTH; for (int c = 0;c < _NUMBER_GP_CODE_WIDTH;c++) { int index = index_1 + index_2+index_3 + c; totalNumberData[index] = (img.ptr(r)[c] >= _IMG_BINARY_THRESHOLD) ? 1 : 0; } } } i++; } uchar* templateNums = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * imgList.size()); try { openCLExcuter->createNumberTemplates(1, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, imgList.size(), ImgUtil::numsOneLevel_gpcode, templateNums); } catch (string st) { free(totalNumberData); free(templateNums); throw st; } uchar** numberResult = openCLExcuter->recognition_numbers(totalNumberData, templateNums, 1 * _NUMBER_GP_CODE_HEIGHT, _NUMBER_GP_CODE_WIDTH * 10* imgList.size(), _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, imgList.size()); list resultList; for (int i = 0;i < imgList.size();i++) { uchar num= numberResult[0][i]; resultList.push_back(num); } free(templateNums); free(numberResult[0]); free(numberResult); free(totalNumberData); return resultList; }