#include "THSDXJLCapture.h"
|
#include "GPUtil.h"
|
#include "OpenCLUtil.h"
|
#include "THSActionUtil.h"
|
#include "CaptureUtil.h"
|
#include <math.h>
|
#include "MD5.h"
|
#include <map>
|
|
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<string, string> md5CodeNameMap;
|
int count = 0;
|
// API
|
for (std::list<DXJLOCRContent>::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<uchar>(r - rect.y)[c - rect.x] = result.grayImg.ptr<uchar>(r)[c];
|
}
|
}
|
string code = ocr_fun(mat);
|
mat.release();
|
md5CodeNameMap[content.codeNameMD5] = code;
|
}
|
}
|
|
list<DXJLEvent> eventList;
|
for (std::list<DXJLOCRContent>::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<int*> THSDXJLCapture::splitRows(cv::Mat img, int contentStartRow, std::list<int*> dataColIndexs)
|
{
|
//·Ö¸ôÿһÐеÄÊý¾Ý
|
std::list<int*> dataItemList;
|
int startf = 0;
|
int endf = 0;
|
std::list<int*>::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<int*> 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<int*> 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<uchar>(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<DXJLOCRContent> contentList = captureGray(grayImg, openCLExcuter);
|
for (std::list<DXJLOCRContent>::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<DXJLOCRContent> THSDXJLCapture::captureGray(cv::Mat grayImg, OpenCLExcuter* openCLExcuter)
|
{
|
|
std::list<int*> rowDataList = split(grayImg);
|
|
int* rowDataOneLevel = (int*)malloc(sizeof(int) * rowDataList.size() * 4);
|
int index = 0;
|
for (list<int*>::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<cv::Rect> timeRectList;
|
std::list<DXJLOCRContent> 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<cv::Rect>::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<uchar>(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<DXJLOCRContent>::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;
|
}
|