1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327 |
- #include "pch.h"
- #include "CvxText.h"
- #include <json/json.h>
- #include "BaseUtility.h"
- #include <iostream>
- #include <fstream>
- #if QQM_ADD
- #include "cvUtil.h"
- #endif
- using namespace std;
- using namespace cv;
- #if defined(GNUC)
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored “-Wdeprecated-declarations”
- #elif defined(_MSC_VER)
- #pragma warning(disable : 4996)
- #endif
- void GetStringSize(HDC hDC, const char* str, int* w, int* h)
- {
- SIZE size;
- GetTextExtentPoint32A(hDC, str, strlen(str), &size);
- if (w != 0) *w = size.cx;
- if (h != 0) *h = size.cy;
- }
- cv::Size GetTextSize(const char* str, int fontSize, const char* fn, bool italic, bool underline)
- {
- HDC hDC = CreateCompatibleDC(0);
- LOGFONTA lf;
- lf.lfHeight = -fontSize;
- lf.lfWidth = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = 0;
- lf.lfWeight = 5;
- lf.lfItalic = italic; //斜体
- lf.lfUnderline = underline; //下划线
- lf.lfStrikeOut = 0;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfOutPrecision = 0;
- lf.lfClipPrecision = 0;
- lf.lfQuality = PROOF_QUALITY;
- lf.lfPitchAndFamily = 0;
- strcpy_s(lf.lfFaceName, fn);
- HFONT hf = CreateFontIndirectA(&lf);
- HFONT hOldFont = (HFONT)SelectObject(hDC, hf);
- int strBaseW = 0, strBaseH = 0;
- int singleRow = 0;
- char buf[1 << 12];
- strcpy_s(buf, str);
- char *bufT[1 << 12]; // 这个用于分隔字符串后剩余的字符,可能会超出。
- //处理多行
- {
- int nnh = 0;
- int cw, ch;
- const char* ln = strtok_s(buf, "\n", bufT);
- while (ln != 0)
- {
- GetStringSize(hDC, ln, &cw, &ch);
- strBaseW = max(strBaseW, cw);
- strBaseH = max(strBaseH, ch);
- ln = strtok_s(0, "\n", bufT);
- nnh++;
- }
- singleRow = strBaseH;
- strBaseH *= nnh;
- }
- SelectObject(hDC, hOldFont);
- DeleteObject(hf);
- DeleteDC(hDC);
- cv::Size size;
- size.width = strBaseW;
- size.height = strBaseH;
- return size;
- }
- void putTextZH(cv::Mat &dst, cv::Size & rSize, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline)
- {
- CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3));
- int x, y, r, b;
- if (org.x > dst.cols || org.y > dst.rows) return;
- x = org.x < 0 ? -org.x : 0;
- y = org.y < 0 ? -org.y : 0;
- LOGFONTA lf;
- lf.lfHeight = -fontSize;
- lf.lfWidth = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = 0;
- lf.lfWeight = 5;
- lf.lfItalic = italic; //斜体
- lf.lfUnderline = underline; //下划线
- lf.lfStrikeOut = 0;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfOutPrecision = 0;
- lf.lfClipPrecision = 0;
- lf.lfQuality = PROOF_QUALITY;
- lf.lfPitchAndFamily = 0;
- strcpy_s(lf.lfFaceName, fn);
- HFONT hf = CreateFontIndirectA(&lf);
- HDC hDC = CreateCompatibleDC(0);
- HFONT hOldFont = (HFONT)SelectObject(hDC, hf);
- int strBaseW = 0, strBaseH = 0;
- int singleRow = 0;
- char buf[1 << 12];
- strcpy_s(buf, str);
- char *bufT[1 << 12]; // 这个用于分隔字符串后剩余的字符,可能会超出。
- //处理多行
- {
- int nnh = 0;
- int cw, ch;
- const char* ln = strtok_s(buf, "\n", bufT);
- while (ln != 0)
- {
- GetStringSize(hDC, ln, &cw, &ch);
- strBaseW = max(strBaseW, cw);
- strBaseH = max(strBaseH, ch);
- ln = strtok_s(0, "\n", bufT);
- nnh++;
- }
- singleRow = strBaseH;
- strBaseH *= nnh;
- }
- rSize.width = strBaseW;
- rSize.height = strBaseH;
- if (org.x + strBaseW < 0 || org.y + strBaseH < 0)
- {
- SelectObject(hDC, hOldFont);
- DeleteObject(hf);
- DeleteObject(hDC);
- return;
- }
- r = org.x + strBaseW > dst.cols ? dst.cols - org.x - 1 : strBaseW - 1;
- b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1;
- org.x = org.x < 0 ? 0 : org.x;
- org.y = org.y < 0 ? 0 : org.y;
- BITMAPINFO bmp = { 0 };
- BITMAPINFOHEADER& bih = bmp.bmiHeader;
- int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4));
- bih.biSize = sizeof(BITMAPINFOHEADER);
- bih.biWidth = strBaseW;
- bih.biHeight = strBaseH;
- bih.biPlanes = 1;
- bih.biBitCount = 24;
- bih.biCompression = BI_RGB;
- bih.biSizeImage = strBaseH * strDrawLineStep;
- bih.biClrUsed = 0;
- bih.biClrImportant = 0;
- void* pDibData = 0;
- HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0);
- CV_Assert(pDibData != 0);
- HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);
- //color.val[2], color.val[1], color.val[0]
- SetTextColor(hDC, RGB(255, 255, 255));
- SetBkColor(hDC, 0);
- //SetStretchBltMode(hDC, COLORONCOLOR);
- strcpy_s(buf, str);
- const char* ln = strtok_s(buf, "\n", bufT);
- int outTextY = 0;
- while (ln != 0)
- {
- TextOutA(hDC, 0, outTextY, ln, strlen(ln));
- outTextY += singleRow;
- ln = strtok_s(0, "\n", bufT);
- }
- uchar* dstData = (uchar*)dst.data;
- int dstStep = dst.step / sizeof(dstData[0]);
- unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;
- unsigned char* pStr = (unsigned char*)pDibData + x * 3;
- for (int tty = y; tty <= b; ++tty)
- {
- unsigned char* subImg = pImg + (tty - y) * dstStep;
- unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep;
- for (int ttx = x; ttx <= r; ++ttx)
- {
- for (int n = 0; n < dst.channels(); ++n) {
- double vtxt = subStr[n] / 255.0;
- int cvv = vtxt * color.val[n] + (1 - vtxt) * subImg[n];
- subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv);
- }
- subStr += 3;
- subImg += dst.channels();
- }
- }
- SelectObject(hDC, hOldBmp);
- SelectObject(hDC, hOldFont);
- DeleteObject(hf);
- DeleteObject(hBmp);
- DeleteDC(hDC);
- }
- ///////////////////////////// 数据收集卡 ///////////////////////////////////////
- // 获取字符串的画布上的宽度
- int getLineStrWidth(string str, int fontSize, int ttBoxW, int tiSl, int backPix) {
- int iw = str.length()*fontSize*0.5;
- iw += ttBoxW;
- iw += tiSl;
- iw += backPix;
- iw += fontSize * 1.5; // 题号的宽度 最多不超过1.5个字体宽度 56.
- return iw;
- }
- // 转码 utf-8 2 ansi
- static void UTF82ANSI(LPCSTR lpBuff, int nLen, char* pData, int iMaxLen)
- {
- ZeroMemory(pData, sizeof(char)*iMaxLen);
- int nCont = MultiByteToWideChar(CP_UTF8, 0, lpBuff, nLen, NULL, 0);
- WCHAR* szTemp = new WCHAR[nCont + 1];
- ZeroMemory(szTemp, sizeof(WCHAR)*(nCont + 1));
- MultiByteToWideChar(CP_UTF8, 0, lpBuff, nLen, szTemp, nCont);
- //获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的
- int len = WideCharToMultiByte(CP_ACP, 0, szTemp, nCont, NULL, 0, NULL, NULL);
- if (len < iMaxLen) {
- WideCharToMultiByte(CP_ACP, 0, szTemp, nCont, pData, len, NULL, NULL);
- }
- else {
- char* buffer = new char[len + 1];
- //宽字节编码转换成多字节编码
- WideCharToMultiByte(CP_ACP, 0, szTemp, nCont, buffer, len, NULL, NULL);
- buffer[len] = '\0';
- //删除缓冲区并返回值
- strncpy(pData, buffer, iMaxLen - 1);
- delete[] buffer;
- buffer = NULL;
- }
- delete[]szTemp;
- szTemp = NULL;
- }
- // 二进制码生成获取
- void createBinString(Mat & img, int pageNum, int ptw, int pth, cv::Point ptStart, vector<cv::Rect>& vecBoxPages) {
- vector<int> vecBinStr; vecBinStr.resize(12);
- for (int i = 11; i >= 0; i--) {
- int ys = pageNum % 2;
- vecBinStr[i] = ys;
- pageNum = pageNum / 2;
- }
- vecBoxPages.clear();
- int ptPgW = ptw / 2; int ptPgH = pth / 2;
- for (int j = 0; j < 3; j++) {
- int _startY = ptStart.y + 15 + 50 * j;
- for (int i = 0; i < 4; i++) {
- int _startX = ptStart.x + 18 + i * 72;
- vecBoxPages.push_back(cv::Rect(_startX, _startY, ptPgW, ptPgH));
- if (vecBinStr[j * 4 + i])
- rectangle(img, vecBoxPages[vecBoxPages.size() - 1], cv::Scalar(0), -1);
- else
- rectangle(img, vecBoxPages[vecBoxPages.size() - 1], cv::Scalar(200, 200, 200), 2, 8, 0);
- }
- }
- return;
- }
- void generatePageJson(vector<cv::Rect>& vecPts, vector<cv::Rect>& vecBoxPages)
- {
- Json::Value imageSize;
- imageSize["width"] = 1654;
- imageSize["height"] = 2344;
- Json::Value location(Json::arrayValue);
- for (auto& iter : vecPts)
- {
- Json::Value item;
- item["x"] = iter.x;
- item["y"] = iter.y;
- item["width"] = iter.width;
- item["height"] = iter.height;
- location.append(item);
- }
- Json::Value pagenumber(Json::arrayValue);
- int nSubVecSize = 4;// 每个小vector的容量
- for (size_t i = 0, j = 1; i < vecBoxPages.size(); i += nSubVecSize)
- {
- vector<cv::Rect> vecSmall;
- auto last = std::min(vecBoxPages.size(), i + nSubVecSize);
- vecSmall.insert(vecSmall.begin(), vecBoxPages.begin() + i, vecBoxPages.begin() + last);
- Json::Value opt(Json::arrayValue);
- std::string choice[] = { "A", "B", "C", "D" };
- for (int h = 0; h < vecSmall.size(); h++)
- {
- Json::Value bin;
- bin["x"] = vecSmall[h].x;
- bin["y"] = vecSmall[h].y;
- bin["width"] = vecSmall[h].width;
- bin["height"] = vecSmall[h].height;
- bin["optName"] = choice[h];
- opt.append(bin);
- }
- Json::Value item;
- item["id"] = j;
- item["opt"] = opt;
- pagenumber.append(item);
- j++;
- }
- Json::Value itemRoot;
- itemRoot["imageSize"] = imageSize;
- itemRoot["location"] = location;
- itemRoot["pagenumber"] = pagenumber;
- Json::FastWriter writer;
- std::string strJson = writer.write(itemRoot);
- CFile zip;
- zip.Open(_T("D:\\page.json"), CFile::modeCreate | CFile::modeWrite);
- DWORD wide_string_len = MultiByteToWideChar(CP_ACP, 0, strJson.c_str(), -1, NULL, 0);
- WCHAR* wide_string = new WCHAR[wide_string_len];
- wide_string_len = MultiByteToWideChar(CP_ACP, 0, strJson.c_str(), -1, wide_string, wide_string_len);
- DWORD utf8_string_len = WideCharToMultiByte(CP_UTF8, 0, wide_string, -1, NULL, 0, NULL, NULL);
- CHAR* utf8_string = new CHAR[utf8_string_len];
- utf8_string_len = WideCharToMultiByte(CP_UTF8, 0, wide_string, -1, utf8_string, utf8_string_len, NULL, NULL);
- zip.Write((void*)utf8_string, utf8_string_len - 1);
- // LOG4CPLUS_INFO_FMT(pTestLogger, LOG4CPLUS_TEXT("%s"), CString(json_str.c_str()));
- delete wide_string;
- delete utf8_string;
- zip.Close();
- }
- std::string JsonToString(const Json::Value & root)
- {
- static Json::Value def = []{
- Json::Value def;
- Json::StreamWriterBuilder::setDefaults(&def);
- def["emitUTF8"] = true;
- return def;
- }();
- std::ostringstream stream;
- Json::StreamWriterBuilder stream_builder;
- stream_builder.settings_ = def;//Config emitUTF8
- std::unique_ptr<Json::StreamWriter> writer(stream_builder.newStreamWriter());
- writer->write(root, &stream);
- return stream.str();
- }
- int dataCollectionPaperPhysics(int cols, int index, int fontSize, int lineGrayPix, bool engShow,
- std::vector<tuple<string, string>>& vecLines, CString dir, std::string& strPngPath, std::string tips) {
- /* 这里要做一些栏数 和 vecLines的对应值确认 */
- if (2 == cols && 14 * 2 == vecLines.size())
- ; // ok
- if (3 == cols && 14 * 3 == vecLines.size())
- ; // ok
- if (4 == cols && 14 * 4 == vecLines.size())
- ; // ok
- // 生成画布图像
- cv::Mat img(cv::Size(1654, 2344), CV_8UC3, cv::Scalar(255, 255, 255));
- int ptw = 80; int pth = 40;
- cv::Size fSize(0, 0);
- int leftPos = 100, rightPos = 1450;
- int topPos = 90;
- int fontW = rightPos - leftPos + ptw;
- vector<cv::Rect> vecPts = {
- cv::Rect(100,90,ptw,pth),
- cv::Rect(580,90,ptw,pth),
- cv::Rect(1450,90,ptw,pth),
- cv::Rect(100,2176,ptw,pth),
- cv::Rect(1450,2176,ptw,pth),
- };
- // 画定位点
- for (size_t i = 0; i < vecPts.size(); i++)
- {
- rectangle(img, vecPts[i], cv::Scalar(0, 0, 0), -1);
- }
- // 画示例框
- topPos += pth; topPos += 30;
- rectangle(img, cv::Rect(leftPos, topPos, fontW, 200), cv::Scalar(0, 0, 0), 2, 8, 0);
- // 画页码框
- cv::Rect boxPageNumber(leftPos + fontW - 300, topPos, 300, 200);
- rectangle(img, boxPageNumber, cv::Scalar(0, 0, 0), 2, 8, 0);
- // 生成二进制码流
- /* 二进制码流的坐标在下面函数里面实现,需要用书写获取 */
- vector<cv::Rect> vecBoxPages;
- createBinString(img, index, ptw, pth, cv::Point(boxPageNumber.x, boxPageNumber.y), vecBoxPages);
- string strPageNumInfo = "关联ID: " + to_string(index);
- putTextZH(img, fSize, strPageNumInfo.c_str(), cv::Point(boxPageNumber.x + 100, boxPageNumber.y + 50 * 2 + 20 + 15 + 15 + 15), Scalar(0), 20, "宋体");
- // 生成page.json
- //generatePageJson(vecPts, vecBoxPages);
- // 画警示信息
- string strMesInfo = "1、请在对应的区域内临摹左侧电路图,每个方框内一个!\
- \n\n2、可以使用铅笔和黑色笔绘图。☆\
- \n\n3、如果本框内有绘画错误,进行了涂抹修改等操作,请将左上方的填涂框用任意笔进行填涂!☆☆\n";
- if (tips.length() > 0)
- {
- strMesInfo = tips;
- }
- putTextZH(img, fSize, strMesInfo.c_str(), cv::Point(leftPos + 20, topPos + 20), Scalar(0), 25, "宋体");
- int lineTop1 = topPos + 20 + fSize.height + 20;
- cv::line(img, cv::Point(leftPos, lineTop1), cv::Point(rightPos + ptw - 300, topPos + 20 + fSize.height + 20), Scalar(0), 2, 8, 0);
- // 正确示例
- string strEgInfo = "注\n意\n事\n项";
- putTextZH(img, fSize, strEgInfo.c_str(), cv::Point(leftPos + 20, topPos + 20 + fSize.height + 20 + 3), Scalar(0), 20, "宋体");
- cv::line(img, cv::Point(leftPos + 20 + fSize.width + 10, lineTop1), cv::Point(leftPos + 20 + fSize.width + 10, topPos + 200), Scalar(0, 0, 0), 2, 8, 0);
- // 填涂示例
- string strtt = "尽量保持手绘内容与示例图相对位置一致!即保持整体相对居中!";
- cv::Point ptEgInfo(leftPos + 70, topPos + 20 + fSize.height + 20 + 30);
- putTextZH(img, fSize, strtt.c_str(), ptEgInfo, Scalar(0), 20, "宋体");
-
- //cv::Rect rcttbox(ptEgInfo.x + 100, ptEgInfo.y - 5, 30, 30);
- //rectangle(img, rcttbox, cv::Scalar(0), -1);
- //rcttbox.x += 1;
- //rcttbox.y += 1;
- //rcttbox.width -= 2;
- //rcttbox.height -= 2;
- //rectangle(img, rcttbox, cv::Scalar(100, 100, 100), -1);
-
- // 贴图区域
- /* 暂不实现 */
- topPos += 200;
- ///////////////////////////////////////// 主干区域: y 起始坐标:360/////////////////////////////////////////////
- Json::Value root(Json::arrayValue);
- // +指定像素
- auto yhPadding = [&](cv::Rect & rcBox,int pd) {
- rcBox.x += pd;
- rcBox.y += pd;
- rcBox.width -= (pd * 2);
- rcBox.height -= (pd * 2);
- };
- // json valule
- auto addValueToJson = [&](Json::Value & root, cv::Rect rcbox, cv::Rect rcNum, cv::Rect rcQues, cv::Rect rcAns,
- int iQNum, std::string strTgInfo, std::string strSolution) {
- //生成识别信息
- Json::Value ttbox;
- ttbox["x"] = rcbox.x;
- ttbox["y"] = rcbox.y;
- ttbox["width"] = rcbox.width;
- ttbox["height"] = rcbox.height;
- Json::Value queNum;
- queNum["x"] = rcNum.x;
- queNum["y"] = rcNum.y;
- queNum["width"] = rcNum.width;
- queNum["height"] = rcNum.height;
- Json::Value queInfo;
- queInfo["x"] = rcQues.x;
- queInfo["y"] = rcQues.y;
- queInfo["width"] = rcQues.width;
- queInfo["height"] = rcQues.height;
- queInfo["info"] = strTgInfo.c_str();
- queInfo["solution"] = strSolution.c_str();
- Json::Value ansInfo;
- ansInfo["x"] = rcAns.x;
- ansInfo["y"] = rcAns.y;
- ansInfo["width"] = rcAns.width;
- ansInfo["height"] = rcAns.height;
- Json::Value item;
- item["id"] = iQNum;
- item["ttbox"] = ttbox;
- item["queNum"] = queNum;
- item["queInfo"] = queInfo;
- item["ansInfo"] = ansInfo;
- root.append(item);
- };
- #if QQM_ADD
- topPos += 50; // 间隔预留
- int pd = 3;
- cv::Size exampleSize(512+ pd *2, 512+ pd *2); // 示例图size
- int exdis = 20; // 示例图之间水平方向间隔
- int eydis = 50; //
- int bigDrawBoxNum = 2;
- int smlDrawBoxNum = 2 * 4;
- int iQNum = 1;
- /*
- ---------------------------------------------
- | | | |
- |示例大图1 |绘画区域1 |绘画区域2 |
- | | | |
- ---------------------------------------------
- | | | |
- |示例大图2 |... | |
- | | | |
- ---------------------------------------------
- | |1 |2 |1 |2 |
- |示例小图3 |-----------|-----------|
- | |3 |4 |3 |4 |
- ----------------------------------------------
- */
- int eleft = max(0, (img.cols - (exampleSize.width + 20) * max_line) / 2);
- for (auto ex = 0; ex < max_line; ex++) {
- //int _left = eleft + (exampleSize.width + 20)*ex;
- // 基础信息准备
- int _left = eleft;
- int _top = topPos + (exampleSize.height + eydis)*ex;
- cv::Rect box(_left, _top, exampleSize.width, exampleSize.height);
- rectangle(img, box, cv::Scalar(0), 2, 8, 0);
- string strTgInfo = std::get<0>(vecLines[ex]);
- string strSolution = std::get<1>(vecLines[ex]);
- int _type = atoi(strSolution.c_str()); // 1 big 0 small
- // 示例图贴图
- cv::Mat _img = cv::imread(strTgInfo, cv::IMREAD_ANYCOLOR);
- CV_Assert(!_img.empty());
- cv::Mat _rsImg;
- if (_type)
- _rsImg = paddingResize(_img, exampleSize.width, exampleSize.height);
- else {
- cv::Mat _rsImg4 = paddingNoResize(_img, exampleSize.width/2, exampleSize.height/2);
- _rsImg = cv::Mat(exampleSize, _img.type(), cv::Scalar(255, 255, 255));
- _rsImg = splitAndInsertImages(_rsImg4, _rsImg);
- cv::line(_rsImg, cv::Point(0, exampleSize.height / 2), cv::Point(exampleSize.width - 1, exampleSize.height / 2), cv::Scalar(0), 1, 8, 0);
- cv::line(_rsImg, cv::Point(exampleSize.width / 2, 0), cv::Point(exampleSize.width / 2, exampleSize.height - 1), cv::Scalar(0), 1, 8, 0);
- }
- cv::Mat _bin;
- cv::cvtColor(_rsImg, _bin, cv::COLOR_BGR2GRAY);
- cv::threshold(_bin, _bin, 200, 255, THRESH_BINARY);
- cv::cvtColor(_bin, _rsImg, cv::COLOR_GRAY2BGR);
- _rsImg.copyTo(img(box));
-
- // 绘图区域
- int ttW = 20; int ttH = 20; // 填涂框
- int __left = _left + box.width + exdis;
- int __top = _top;
- int __w = exampleSize.width * 2 + exdis;
- int __h = exampleSize.height;
- if (_type) {
- for (auto n = 0; n < bigDrawBoxNum; n++) {
- cv::Rect __box(__left+n*(exampleSize.width+exdis), __top, exampleSize.width, exampleSize.height);
- cv::rectangle(img, __box, cv::Scalar(0), 2, 8, 0);
- // 填涂框子
- cv::Rect __ttBox(__box.x, __box.y - ttH, ttW, ttH);
- cv::rectangle(img, __ttBox, cv::Scalar(0), 1, 8, 0);
- cv::Rect __thBox(__ttBox);
- cv::Rect __qBox(__ttBox);
- yhPadding(__box, pd);
- addValueToJson(root, __ttBox, __ttBox, __ttBox, __box, iQNum++, strTgInfo, strSolution);
- }
- }
- else {
- int __col = 4; int __row = 2;
- int ___disx = 20;
- int ___disy = 20;
- int ___w = (__w - ___disx * (__col - 1)) / __col;
- int ___h = (__h - ___disy * (__row - 1)) / __row;
- for (auto row = 0; row < __row; row++) {
- int ___top = __top + row*(___h + ___disy);
- for (auto col = 0; col < __col; col++) {
- int ___left = __left + col * (___w + ___disx);
- cv::Rect ___box(___left, ___top, ___w, ___h);
- cv::rectangle(img, ___box, cv::Scalar(0), 2, 8, 0);
- // 填涂框子
- cv::Rect __ttBox(___box.x, ___box.y - ttH, ttW, ttH);
- cv::rectangle(img, __ttBox, cv::Scalar(0), 1, 8, 0);
- cv::Rect __thBox(__ttBox);
- cv::Rect __qBox(__ttBox);
- yhPadding(___box, pd);
- addValueToJson(root, __ttBox, __ttBox, __ttBox, ___box, iQNum++, strTgInfo, strSolution);
- }
- }
- }
- // fuick
- int x = 0;
-
- }
- #else
- // 文字区域
- static int maxLineNum = 14; // 最大行数14
- static int ttBoxWidth = 30; // 填涂框的边长
- static int tiSl = 10; // 题号和题干间的距离
- static int lineDis = 20; // 两行之间的距离
- int colWidth = fontW / cols; // 单栏的宽度
- fSize.width = 0; fSize.height = 0;
- //RNG rng;
- for (int col = 0; col < cols; col++)
- { // 逐栏画题
- int colTopPos = topPos;
- int colLeftPos = leftPos + col * colWidth;
- for (size_t i = 0; i < maxLineNum; i++)
- {
- size_t vecIndex = i + col * maxLineNum;
- if (vecIndex >= vecLines.size())
- {
- break;
- }
- colTopPos += lineDis;
- int lineLen = ttBoxWidth + tiSl;
- // 画填涂框 30*30 大小
- cv::Rect rcbox(colLeftPos, colTopPos, ttBoxWidth, ttBoxWidth);
- rectangle(img, rcbox, cv::Scalar(0), 1, 8, 0);
- int iQNum = i + 1 + col * maxLineNum;
- string strStinfo = to_string(iQNum); strStinfo += ".";
- cv::Point ptNum(colLeftPos + ttBoxWidth + tiSl, colTopPos);
- putTextZH(img, fSize, strStinfo.c_str(), ptNum, Scalar(0, 0, 0), fontSize, "宋体"); // 跟填涂框保持10px距离
- lineLen += fSize.width;
- cv::Rect rcNum(ptNum.x, ptNum.y, fSize.width, fSize.height);
- strStinfo.clear();
- string strTgInfo = std::get<0>(vecLines[vecIndex]);
- string strSolution = std::get<1>(vecLines[vecIndex]);
- if (!engShow)
- ; /* 移除词性 */
- //char szTemp[2048];
- //memset(szTemp, 0, sizeof(char)*(2048));
- //UTF82ANSI(strTgInfo.c_str(), strTgInfo.length(), szTemp, 2048);
- //strTgInfo = szTemp;
- cv::Point ptQues(colLeftPos + ttBoxWidth + tiSl + fSize.width, colTopPos);
- putTextZH(img, fSize, strTgInfo.c_str(), ptQues, Scalar(0, 0, 0), fontSize, "宋体"); // 跟填涂框保持10px距离
- lineLen += fSize.width;
- cv::Rect rcQues(ptQues.x, ptQues.y, fSize.width, fSize.height);
- cv::Rect rcAns(colLeftPos + 30, colTopPos + fSize.height, colWidth - ttBoxWidth, 1);
- colTopPos = colTopPos + fSize.height * 3.5; //两行之间两倍的距离用于书写
- //lineGrayPix = rng.operator ()(220);
- line(img, cv::Point(colLeftPos + 30, colTopPos), cv::Point(colLeftPos + colWidth - 1, colTopPos), Scalar(lineGrayPix, lineGrayPix, lineGrayPix), 1, 8, 0);
- rcAns.height = colTopPos - rcAns.y + lineDis;
- //生成识别信息
- Json::Value ttbox;
- ttbox["x"] = rcbox.x;
- ttbox["y"] = rcbox.y;
- ttbox["width"] = rcbox.width;
- ttbox["height"] = rcbox.height;
- #if QQM_ADD
- cv::rectangle(img, rcbox, cv::Scalar(0, 0, 244), 1, 8, 0);
- #endif // QQM_ADD
- Json::Value queNum;
- queNum["x"] = rcNum.x;
- queNum["y"] = rcNum.y;
- queNum["width"] = rcNum.width;
- queNum["height"] = rcNum.height;
- #if QQM_ADD
- cv::rectangle(img, rcNum, cv::Scalar(0, 255, 244), 1, 8, 0);
- #endif // QQM_ADD
- Json::Value queInfo;
- queInfo["x"] = rcQues.x;
- queInfo["y"] = rcQues.y;
- queInfo["width"] = rcQues.width;
- queInfo["height"] = rcQues.height;
- queInfo["info"] = strTgInfo.c_str();
- queInfo["solution"] = strSolution.c_str();
- #if QQM_ADD
- cv::rectangle(img, rcQues, cv::Scalar(215, 0, 244), 1, 8, 0);
- #endif // QQM_ADD
- Json::Value ansInfo;
- ansInfo["x"] = rcAns.x;
- ansInfo["y"] = rcAns.y;
- ansInfo["width"] = rcAns.width;
- ansInfo["height"] = rcAns.height;
- #if QQM_ADD
- cv::rectangle(img, rcAns, cv::Scalar(225, 120, 244), 1, 8, 0);
- #endif // QQM_ADD
- Json::Value item;
- item["id"] = iQNum;
- item["ttbox"] = ttbox;
- item["queNum"] = queNum;
- item["queInfo"] = queInfo;
- item["ansInfo"] = ansInfo;
- root.append(item);
- // test
- /*rectangle(img, rcbox, cv::Scalar(0, 0, 200), 1, 8, 0);
- rectangle(img, rcNum, cv::Scalar(0, 200, 0), 1, 8, 0);
- rectangle(img, rcQues, cv::Scalar(100, 0, 0), 1, 8, 0);
- rectangle(img, rcAns, cv::Scalar(200, 0, 0), 1, 8, 0);*/
- }
- }
- #endif // QQM_ADD
-
- std::string strJson = JsonToString(root);
-
- CString strTemplatePath;
- strTemplatePath.Format(L"%s/json/%d.json", dir, index);
- CFile zip;
- zip.Open(strTemplatePath, CFile::modeCreate | CFile::modeWrite);
- zip.Write((void*)strJson.c_str(), strJson.length());
- zip.Close();
- wchar_t tempPath[MAX_PATH];
- DWORD dwSize = MAX_PATH;
- GetTempPath(dwSize, tempPath);//获取临时文件夹路径
- static int tmp_index = 1;
- wchar_t szPath[MAX_PATH];
- _stprintf(szPath, L"%stmp_%d.png", tempPath, tmp_index);
- tmp_index++;
- if (tmp_index > 10)
- {
- tmp_index = 1;
- }
-
- strPngPath = TstringToGB2312(szPath);
- cv::imwrite(strPngPath, img);
-
- /*cv::namedWindow("fuck", 1);
- cv::imshow("fuck", img);
- cv::waitKey(0);*/
-
- return 0;
- }
- int dataCollectionPaper(int cols, int index, int fontSize, int lineGrayPix, bool engShow, std::vector<tuple<string, string>>& vecLines, CString dir, std::string& strPngPath, std::string tips) {
- /* 这里要做一些栏数 和 vecLines的对应值确认 */
- if (2 == cols && 14 * 2 == vecLines.size())
- ; // ok
- if (3 == cols && 14 * 3 == vecLines.size())
- ; // ok
- if (4 == cols && 14 * 4 == vecLines.size())
- ; // ok
- // 生成画布图像
- cv::Mat img(cv::Size(1654, 2344), CV_8UC3, cv::Scalar(255, 255, 255));
- int ptw = 80; int pth = 40;
- cv::Size fSize(0, 0);
- int leftPos = 100, rightPos = 1450;
- int topPos = 90;
- int fontW = rightPos - leftPos + ptw;
- vector<cv::Rect> vecPts = {
- cv::Rect(100,90,ptw,pth),
- cv::Rect(580,90,ptw,pth),
- cv::Rect(1450,90,ptw,pth),
- cv::Rect(100,2176,ptw,pth),
- cv::Rect(1450,2176,ptw,pth),
- };
- // 画定位点
- for (size_t i = 0; i < vecPts.size(); i++)
- {
- rectangle(img, vecPts[i], cv::Scalar(0, 0, 0), -1);
- }
- // 画示例框
- topPos += pth; topPos += 30;
- rectangle(img, cv::Rect(leftPos, topPos, fontW, 200), cv::Scalar(0, 0, 0), 2, 8, 0);
- // 画页码框
- cv::Rect boxPageNumber(leftPos + fontW - 300, topPos, 300, 200);
- rectangle(img, boxPageNumber, cv::Scalar(0, 0, 0), 2, 8, 0);
- // 生成二进制码流
- /* 二进制码流的坐标在下面函数里面实现,需要用书写获取 */
- vector<cv::Rect> vecBoxPages;
- createBinString(img, index, ptw, pth, cv::Point(boxPageNumber.x, boxPageNumber.y), vecBoxPages);
- string strPageNumInfo = "关联ID: " + to_string(index);
- putTextZH(img, fSize, strPageNumInfo.c_str(), cv::Point(boxPageNumber.x + 100, boxPageNumber.y + 50 * 2 + 20 + 15 + 15 + 15), Scalar(0), 20, "宋体");
- // 生成page.json
- //generatePageJson(vecPts, vecBoxPages);
- // 画警示信息
- string strMesInfo = "1、请将各题结果书写于横线上,勿写到线下!\
- \n\n2、请用黑色笔书写。☆\
- \n\n3、如果本题书写有误,进行了涂抹修改等操作,请将题号前矩形框用任意笔进行填涂!☆☆\n";
- if (tips.length() > 0)
- {
- strMesInfo = tips;
- }
- putTextZH(img, fSize, strMesInfo.c_str(), cv::Point(leftPos + 20, topPos + 20), Scalar(0), 25, "宋体");
- int lineTop1 = topPos + 20 + fSize.height + 20;
- cv::line(img, cv::Point(leftPos, lineTop1), cv::Point(rightPos + ptw - 300, topPos + 20 + fSize.height + 20), Scalar(0), 2, 8, 0);
- // 正确示例
- string strEgInfo = "正\n确\n示\n例";
- putTextZH(img, fSize, strEgInfo.c_str(), cv::Point(leftPos + 20, topPos + 20 + fSize.height + 20 + 3), Scalar(0), 20, "宋体");
- cv::line(img, cv::Point(leftPos + 20 + fSize.width + 10, lineTop1), cv::Point(leftPos + 20 + fSize.width + 10, topPos + 200), Scalar(0, 0, 0), 2, 8, 0);
- // 填涂示例
- string strtt = "正确填涂";
- cv::Point ptEgInfo(leftPos + 70, topPos + 20 + fSize.height + 20 + 30);
- putTextZH(img, fSize, strtt.c_str(), ptEgInfo, Scalar(0), 20, "宋体");
- cv::Rect rcttbox(ptEgInfo.x + 100, ptEgInfo.y - 5, 30, 30);
- rectangle(img, rcttbox, cv::Scalar(0), -1);
- rcttbox.x += 1;
- rcttbox.y += 1;
- rcttbox.width -= 2;
- rcttbox.height -= 2;
- rectangle(img, rcttbox, cv::Scalar(100, 100, 100), -1);
- // 贴图区域
- /* 暂不实现 */
- topPos += 200;
- // 文字区域
- static int maxLineNum = 14; // 最大行数14
- static int ttBoxWidth = 30; // 填涂框的边长
- static int tiSl = 10; // 题号和题干间的距离
- static int lineDis = 20; // 两行之间的距离
- int colWidth = fontW / cols; // 单栏的宽度
- fSize.width = 0; fSize.height = 0;
- Json::Value root(Json::arrayValue);
- //RNG rng;
- for (int col = 0; col < cols; col++)
- { // 逐栏画题
- int colTopPos = topPos;
- int colLeftPos = leftPos + col * colWidth;
- for (size_t i = 0; i < maxLineNum; i++)
- {
- size_t vecIndex = i + col * maxLineNum;
- if (vecIndex >= vecLines.size())
- {
- break;
- }
- colTopPos += lineDis;
- int lineLen = ttBoxWidth + tiSl;
- // 画填涂框 30*30 大小
- cv::Rect rcbox(colLeftPos, colTopPos, ttBoxWidth, ttBoxWidth);
- rectangle(img, rcbox, cv::Scalar(0), 1, 8, 0);
- int iQNum = i + 1 + col * maxLineNum;
- string strStinfo = to_string(iQNum); strStinfo += ".";
- cv::Point ptNum(colLeftPos + ttBoxWidth + tiSl, colTopPos);
- putTextZH(img, fSize, strStinfo.c_str(), ptNum, Scalar(0, 0, 0), fontSize, "宋体"); // 跟填涂框保持10px距离
- lineLen += fSize.width;
- cv::Rect rcNum(ptNum.x, ptNum.y, fSize.width, fSize.height);
- strStinfo.clear();
- string strTgInfo = std::get<0>(vecLines[vecIndex]);
- string strSolution = std::get<1>(vecLines[vecIndex]);
- if (!engShow)
- ; /* 移除词性 */
- //char szTemp[2048];
- //memset(szTemp, 0, sizeof(char)*(2048));
- //UTF82ANSI(strTgInfo.c_str(), strTgInfo.length(), szTemp, 2048);
- //strTgInfo = szTemp;
- cv::Point ptQues(colLeftPos + ttBoxWidth + tiSl + fSize.width, colTopPos);
- putTextZH(img, fSize, strTgInfo.c_str(), ptQues, Scalar(0, 0, 0), fontSize, "宋体"); // 跟填涂框保持10px距离
- lineLen += fSize.width;
- cv::Rect rcQues(ptQues.x, ptQues.y, fSize.width, fSize.height);
- cv::Rect rcAns(colLeftPos + 30, colTopPos + fSize.height, colWidth - ttBoxWidth, 1);
- colTopPos = colTopPos + fSize.height * 3.5; //两行之间两倍的距离用于书写
- //lineGrayPix = rng.operator ()(220);
- line(img, cv::Point(colLeftPos + 30, colTopPos), cv::Point(colLeftPos + colWidth - 1, colTopPos), Scalar(lineGrayPix, lineGrayPix, lineGrayPix), 1, 8, 0);
- rcAns.height = colTopPos - rcAns.y + lineDis;
- //生成识别信息
- Json::Value ttbox;
- ttbox["x"] = rcbox.x;
- ttbox["y"] = rcbox.y;
- ttbox["width"] = rcbox.width;
- ttbox["height"] = rcbox.height;
- Json::Value queNum;
- queNum["x"] = rcNum.x;
- queNum["y"] = rcNum.y;
- queNum["width"] = rcNum.width;
- queNum["height"] = rcNum.height;
- Json::Value queInfo;
- queInfo["x"] = rcQues.x;
- queInfo["y"] = rcQues.y;
- queInfo["width"] = rcQues.width;
- queInfo["height"] = rcQues.height;
- queInfo["info"] = strTgInfo.c_str();
- queInfo["solution"] = strSolution.c_str();
- Json::Value ansInfo;
- ansInfo["x"] = rcAns.x;
- ansInfo["y"] = rcAns.y;
- ansInfo["width"] = rcAns.width;
- ansInfo["height"] = rcAns.height;
- Json::Value item;
- item["id"] = iQNum;
- item["ttbox"] = ttbox;
- item["queNum"] = queNum;
- item["queInfo"] = queInfo;
- item["ansInfo"] = ansInfo;
- root.append(item);
- // test
- /*rectangle(img, rcbox, cv::Scalar(0, 0, 200), 1, 8, 0);
- rectangle(img, rcNum, cv::Scalar(0, 200, 0), 1, 8, 0);
- rectangle(img, rcQues, cv::Scalar(100, 0, 0), 1, 8, 0);
- rectangle(img, rcAns, cv::Scalar(200, 0, 0), 1, 8, 0);*/
- }
- }
- std::string strJson = JsonToString(root);
- CString strTemplatePath;
- strTemplatePath.Format(L"%s/json/%d.json", dir, index);
- CFile zip;
- zip.Open(strTemplatePath, CFile::modeCreate | CFile::modeWrite);
- zip.Write((void*)strJson.c_str(), strJson.length());
- zip.Close();
- wchar_t tempPath[MAX_PATH];
- DWORD dwSize = MAX_PATH;
- GetTempPath(dwSize, tempPath);//获取临时文件夹路径
- static int tmp_index = 1;
- wchar_t szPath[MAX_PATH];
- _stprintf(szPath, L"%stmp_%d.png", tempPath, tmp_index);
- tmp_index++;
- if (tmp_index > 10)
- {
- tmp_index = 1;
- }
- strPngPath = TstringToGB2312(szPath);
- cv::imwrite(strPngPath, img);
- /*cv::namedWindow("fuck", 1);
- cv::imshow("fuck", img);
- cv::waitKey(0);*/
- return 0;
- }
- // rect_label : 模板的切割区域 rect_ocr :检测到的手写区域
- double math_iou(cv::Rect rect_label, cv::Rect rect_ocr)
- {
- int endx = max(rect_label.x + rect_label.width, rect_ocr.x + rect_ocr.width);
- int startx = min(rect_label.x, rect_ocr.x);
- int width = rect_label.width + rect_ocr.width - (endx - startx);
- int endy = max(rect_label.y + rect_label.height, rect_ocr.y + rect_ocr.height);
- int starty = min(rect_label.y, rect_ocr.y);
- int height = rect_label.height + rect_ocr.height - (endy - starty);
- double area = 0.0, iou = 0.0;
- if (width <= 0 || height <= 0)
- return 0.0;
- area = width * height*1.0;
- iou = area / double(rect_ocr.area());
- return iou;
- }
- int get_gray_num(cv::Mat & img, cv::Rect & box, int &meanGray, int threshold) {
- uchar * ptr;
- int count = 0;
- long long totalGrayNum = 0;
- for (int h = box.y; h < box.y + box.height; h++) {
- ptr = img.ptr<uchar>(h);
- for (int w = box.x; w < box.x + box.width; w++) {
- int pix = static_cast<int>(ptr[w]);
- totalGrayNum += pix;
- if (pix < threshold)
- count++;
- }
- }
- meanGray = totalGrayNum / box.area();
- return count;
- }
- int get_around_box_gray(cv::Mat & img, cv::Rect & box) {
- int left = (box.x - box.width / 2) > 0 ? (box.x - box.width / 2) : 0;
- int top = (box.y - box.height / 2) > 0 ? (box.y - box.height / 2) : 0;
- int right = (box.x + box.width * 3 / 2) < (img.cols - 1) ? (box.x + box.width * 3 / 2) : (img.cols - 1);
- int bottom = (box.y + box.height * 3 / 2) < (img.rows - 1) ? (box.y + box.height * 3 / 2) : (img.rows - 1);
- uchar * ptr;
- std::int64_t total = 0;
- int number = 0;
- for (int h = top; h < bottom; h++) {
- ptr = img.ptr<uchar>(h);
- for (int w = left; w < right; w++) {
- if (w > box.x && w<(box.x + box.width) && h>box.y&&h < (box.y + box.height))
- continue;
- total += static_cast<std::int64_t>(ptr[w]);
- number++;
- }
- }
- return static_cast<int>(total / number);
- }
- #define USE_THRESHOLD_VAL 200
- bool analysis_ttbox_mark(cv::Mat & imgSrc, cv::Rect & rc) {
- int thre = min(200, max(get_around_box_gray(imgSrc, rc), 160));
- int gray = get_gray_num(imgSrc, rc, thre, USE_THRESHOLD_VAL);
- double ds = gray * 1.0 / rc.area()*1.0;
- if (ds > 0.50)
- return true;
- return false;
- }
- int cutPaper(int pageNum, std::string strJsonPath, std::string strPaperPath, std::string strSavePath, vector<std::tuple<cv::Rect, std::string>>& vecTranslate)
- {
- ifstream in(strJsonPath, ios::binary);
- if (!in.is_open())
- {
- return 1;
- }
- Json::Features features;
- Json::Reader reader(features);
- Json::Value root;
- if (!reader.parse(in, root))
- {
- return 1;
- }
- if (!root.isArray())
- {
- return 1;
- }
- cv::Mat src = cv::imread(strPaperPath);
- if (src.empty())
- {
- return 1;
- }
- auto pfGetPos = [](const Json::Value & value, cv::Rect& rc) {
- int x = 0, y = 0, w = 0, h = 0;
- if (value.isMember("x"))
- {
- x = value["x"].asInt();
- }
- if (value.isMember("y"))
- {
- y = value["y"].asInt();
- }
- if (value.isMember("width"))
- {
- w = value["width"].asInt();
- }
- if (value.isMember("height"))
- {
- h = value["height"].asInt();
- }
- rc = cv::Rect(x, y, w, h);
- };
- for (int i = 0; i < root.size(); i++)
- {
- Json::Value row = root[i];
-
- std::string id = row["id"].asString();
- std::string info = row["queInfo"]["info"].asString();
- std::string solution = row["queInfo"]["solution"].asString();
- info = ConvertGB2312toUTF8(info.c_str());
- solution = ConvertGB2312toUTF8(solution.c_str());
- Json::Value ttbox = row["ttbox"];
- Json::Value ansInfo = row["ansInfo"];
-
- cv::Rect rc_ttbox;
- cv::Rect rc_ansInfo;
- pfGetPos(ttbox, rc_ttbox);
- pfGetPos(ansInfo, rc_ansInfo);
-
- // 选择框灰度判断
- cv::Mat gray_src;
- cv::cvtColor(src, gray_src, COLOR_BGR2GRAY);
- bool ret = analysis_ttbox_mark(gray_src, rc_ttbox);
-
- char szTxtPath[MAX_PATH] = { 0 };
- char szStdPath[MAX_PATH] = { 0 };
- char szJpgPath[MAX_PATH] = { 0 };
- DWORD dwCount = GetTickCount();
- sprintf(szTxtPath, "%s\\%s\\%d_%s_%ld_yy.txt", strSavePath.c_str(), ret ? "abnormal" : "normal", pageNum, id.c_str(), dwCount);
- sprintf(szStdPath, "%s\\%s\\%d_%s_%ld_zz.txt", strSavePath.c_str(), ret ? "abnormal" : "normal", pageNum, id.c_str(), dwCount);
- sprintf(szJpgPath, "%s\\%s\\%d_%s_%ld.jpg", strSavePath.c_str(), ret ? "abnormal" : "normal", pageNum, id.c_str(), dwCount);
- CFile zip1;
- zip1.Open(CA2T(szTxtPath), CFile::modeCreate | CFile::modeWrite);
- zip1.Write((void*)info.c_str(), info.length());
- zip1.Close();
- CFile zip2;
- zip2.Open(CA2T(szStdPath), CFile::modeCreate | CFile::modeWrite);
- zip2.Write((void*)solution.c_str(), solution.length());
- zip2.Close();
- cv::Mat cut = src(rc_ansInfo);
- cv::imwrite(szJpgPath, cut);
- int index = 1;
- for (auto& iter : vecTranslate)
- {
- cv::Rect rcOcr = std::get<0>(iter);
- std::string words = ConvertGB2312toUTF8(std::get<1>(iter).c_str());
- if (math_iou(rc_ansInfo, rcOcr) > 0.5)
- {
- char szOcrJpgPath[MAX_PATH] = { 0 };
- char szOcrJpgText[MAX_PATH] = { 0 };
- sprintf(szOcrJpgPath, "%s\\%s\\%d_%s_%ld_%d_%d_%d_%d_%d.jpg", strSavePath.c_str(), ret ? "abnormal_small" : "normal_small", pageNum, id.c_str(), dwCount,
- rcOcr.x - rc_ansInfo.x, rcOcr.y - rc_ansInfo.y, rcOcr.width, rcOcr.height, index);
- sprintf(szOcrJpgText, "%s\\%s\\%d_%s_%ld_%d_%d_%d_%d_%d.txt", strSavePath.c_str(), ret ? "abnormal_small" : "normal_small", pageNum, id.c_str(), dwCount,
- rcOcr.x - rc_ansInfo.x, rcOcr.y - rc_ansInfo.y, rcOcr.width, rcOcr.height, index);
- CFile zip3;
- zip3.Open(CA2T(szOcrJpgText), CFile::modeCreate | CFile::modeWrite);
- zip3.Write((void*)words.c_str(), words.length());
- zip3.Close();
- cv::Mat cut = src(rcOcr);
- cv::imwrite(szOcrJpgPath, cut);
- index++;
- }
- }
- }
- return 0;
- }
- int PareseModeJson(preinfo::templatesInfo& temeplatInfo)
- {
- ifstream in("./page.json", ios::binary);
- if (!in.is_open())
- {
- return 1;
- }
- int uuid = 100000; /// 每个框子的一个独立ID 不会有重复的
- Json::Features features;
- Json::Reader reader(features);
- Json::Value root;
- if (!reader.parse(in, root))
- {
- return 1;
- }
- if (!root.isObject())
- {
- return 1;
- }
- //1.获取模板大小信息
- preinfo::PaperTemplateInfo page;
- Json::Value imageSize = root["imageSize"];
- page.height = imageSize["height"].asInt();
- page.width = imageSize["width"].asInt();
-
- //2.获取定位点信息
- Json::Value loction = root["location"];
- auto funGetPos = [&](Json::Value item) {
- preinfo::PaperRect<double> pb;
- int x = item["x"].asInt();
- int y = item["y"].asInt();
- int h = item["height"].asInt();
- int w = item["width"].asInt();
- pb.centerx = x + w / 2.0;
- pb.centery = y + h / 2.0;
- pb.width = w;
- pb.height = h;
- return pb;
- };
- double offsetx = page.width; double offsety = page.height;
- for (int i = 0; i < loction.size(); i++)
- {
- Json::Value row = loction[i];
- preinfo::LocationPoint lc;
- lc.id = uuid++;
- auto tm = funGetPos(row);
- lc.centerx = tm.centerx;
- lc.centery = tm.centery;
- lc.width = tm.width;
- lc.height = tm.height;
- if (offsetx > lc.centerx) offsetx = lc.getX();
- if (offsety > lc.centery) offsety = lc.getY();
- page.vecLocaltionPoints.push_back(lc);
-
- }
- //3.获取客观题信息
- Json::Value pagenumber = root["pagenumber"];
- for (int i = 0; i < pagenumber.size(); i++)
- {
- Json::Value item = pagenumber[i];
- string strId = item["id"].asString();
- preinfo::_QuestionChoice _qstc;
- _qstc.id = uuid++;
- _qstc.vecTiHao.push_back(atoi(strId.c_str()));
- double dBoundBox[4] = { 100000,100000,0,0 };
- _qstc.type = preinfo::BOX_QUESTION_CHOICE_M;
- auto itOpts = item["opt"];
- _qstc.number = itOpts.size();
- std::vector<preinfo::TtItem> _vctOpt;
- for (int i = 0; i < itOpts.size(); i++)
- {
- preinfo::TtItem opt;
- auto tm = funGetPos(itOpts[i]);
- opt.centerx = tm.centerx;
- opt.centery = tm.centery;
- opt.width = tm.width;
- opt.height = tm.height;
- _qstc.itemSize.width = opt.width;
- _qstc.itemSize.height = opt.height;
- dBoundBox[0] = dBoundBox[0] > opt.getX() ? opt.getX() : dBoundBox[0];
- dBoundBox[1] = dBoundBox[1] > opt.getY() ? opt.getY() : dBoundBox[1];
- dBoundBox[2] = dBoundBox[2] < (opt.centerx + opt.width / 2.0) ? (opt.centerx + opt.width / 2.0) : dBoundBox[2];
- dBoundBox[3] = dBoundBox[3] < (opt.centery + opt.height / 2.0) ? (opt.centery + opt.height / 2.0) : dBoundBox[3];
-
- auto subItem = itOpts[i];
- opt.optName = subItem["optName"].asString();
- _vctOpt.push_back(opt);
- }
- _qstc.width = (dBoundBox[2] - dBoundBox[0]);
- _qstc.height = (dBoundBox[3] - dBoundBox[1]);
- _qstc.centerx = dBoundBox[0] + _qstc.width / 2.0;
- _qstc.centery = dBoundBox[1] + _qstc.height / 2.0;
- _qstc.groups = _vctOpt;
- page._vecQtChoices.push_back(_qstc);
- }
- temeplatInfo.push_back(page);
- return 0;
- }
- int cutPaper(std::string strImagePath, std::string strCurDir, vector<std::tuple<cv::Rect, std::string>>& vecTranslate)
- {
- cv::Mat src = cv::imread(strImagePath);
- if (src.empty())
- {
- return 1;
- }
- int index = 1;
- for (auto& iter : vecTranslate)
- {
- cv::Rect rcOcr = std::get<0>(iter);
- std::string words = ConvertGB2312toUTF8(std::get<1>(iter).c_str());
-
- DWORD dwCount = GetTickCount();
- time_t tt = std::time(0);
- char szOcrJpgPath[MAX_PATH] = { 0 };
- char szOcrJpgText[MAX_PATH] = { 0 };
- sprintf(szOcrJpgPath, "%s\\%lld_%ld_%d.jpg", strCurDir.c_str(), tt, dwCount, index);
- sprintf(szOcrJpgText, "%s\\%lld_%ld_%d.txt", strCurDir.c_str(), tt, dwCount, index);
- CFile zip3;
- zip3.Open(CA2T(szOcrJpgText), CFile::modeCreate | CFile::modeWrite);
- zip3.Write((void*)words.c_str(), words.length());
- zip3.Close();
- cv::Mat cut = src(rcOcr);
- cv::imwrite(szOcrJpgPath, cut);
- index++;
- }
- return 0;
- }
|