#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<TradeData> RecognitionManager::recognition(cv::Mat img, int* rowDataList, int lines) {
|
list<TradeData> 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;
|
LogUtil::debug("·Ö¸ô¿ªÊ¼", NULL);
|
//È¥³ýÉÏϵĿհ×ͼ
|
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<uchar>(endRow)[i];
|
|
*(temp + 1) = binary.ptr<uchar>(endRow)[i - 1];
|
*(temp + 2) = binary.ptr<uchar>(endRow)[i - 2];
|
*(temp + 3) = binary.ptr<uchar>(endRow)[i - 3];
|
*(temp + 4) = binary.ptr<uchar>(endRow)[i - 4];
|
*(temp + 5) = binary.ptr<uchar>(endRow)[i - 5];
|
*(temp + 6) = binary.ptr<uchar>(endRow)[i - 6];
|
if (*(temp + 3) > 0 && binary.ptr<uchar>(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<uchar>(endRow)[i];
|
*(temp + 1) = binary.ptr<uchar>(endRow)[i + 1];
|
*(temp + 2) = binary.ptr<uchar>(endRow)[i + 2];
|
*(temp + 3) = binary.ptr<uchar>(endRow)[i + 3];
|
*(temp + 4) = binary.ptr<uchar>(endRow)[i + 4];
|
*(temp + 5) = binary.ptr<uchar>(endRow)[i + 5];
|
*(temp + 6) = binary.ptr<uchar>(endRow)[i + 6];
|
if (*(temp + 3) > 0 && binary.ptr<uchar>(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<uchar>(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<int*> 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<int*>::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<int> 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<uchar>(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<uchar>(rows - 1)[i];
|
|
*(temp + 1) = binary.ptr<uchar>(rows - 1)[i + 1];
|
*(temp + 2) = binary.ptr<uchar>(rows - 1)[i + 2];
|
*(temp + 3) = binary.ptr<uchar>(rows - 1)[i + 3];
|
*(temp + 4) = binary.ptr<uchar>(rows - 1)[i + 4];
|
*(temp + 5) = binary.ptr<uchar>(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<uchar> RecognitionManager::recognitionGPCode(list<cv::Mat> imgList) {
|
|
unsigned char* totalNumberData = (unsigned char*)malloc(sizeof(unsigned char) * (_NUMBER_GP_CODE_HEIGHT * 1) * _NUMBER_GP_CODE_WIDTH * 10 * imgList.size());
|
list<cv::Mat>::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<uchar>(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());
|
openCLExcuter->createNumberTemplates(1, _NUMBER_GP_CODE_WIDTH, _NUMBER_GP_CODE_HEIGHT, imgList.size(),ImgUtil::numsOneLevel_gpcode, templateNums);
|
|
|
|
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<uchar> 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;
|
}
|