From 29c309b0355e202a774d82a1b560224e8e309a16 Mon Sep 17 00:00:00 2001 From: "bob.pan" Date: Fri, 8 Oct 2021 16:14:45 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=A2=9E=E5=8A=A0=E8=8B=B1=E8=AF=AD?= =?UTF-8?q?=E7=BF=BB=E8=AF=91=202=E3=80=81=E5=A2=9E=E5=8A=A0PLC=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E9=80=9A=E8=AE=AF=E7=8A=B6=E6=80=81=203=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8A=A0=E5=9B=BE=E7=AE=97=E6=B3=95=E5=9C=86?= =?UTF-8?q?=E5=BF=83=E6=89=BE=E4=B8=8D=E5=88=B0=E5=AF=BC=E8=87=B4=E6=89=BE?= =?UTF-8?q?=E5=9C=86=E5=81=8F=E7=A7=BB=E5=A4=A7=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/偏距数据.png | Bin 0 -> 85279 bytes doc/旧抠图算法.txt | 574 +++++++ runner17/language/English/lpmain_en.qm | Bin 46112 -> 48863 bytes src/algorithm/ImageProcess.cpp | 4 + src/tpMain/DetectState.cpp | 1 - src/tpMain/WheelModel.cpp | 10 +- src/tpMain/WheelNet.cpp | 30 +- src/tpMain/cryptokey/QCryptokeyUI.cpp | 8 +- src/tpMain/qaddchanneldlg.cpp | 8 + src/tpMain/qaddchanneldlg.h | 6 +- src/tpMain/qaddmodel.cpp | 8 +- src/tpMain/qaddmodel.h | 2 + src/tpMain/qaddtimedlg.cpp | 8 + src/tpMain/qaddtimedlg.h | 5 +- src/tpMain/qchannelmanager.cpp | 10 +- src/tpMain/qchannelmanager.h | 2 + src/tpMain/qdia2thsetting.cpp | 7 + src/tpMain/qdia2thsetting.h | 2 + src/tpMain/qipconfigdlg.cpp | 8 + src/tpMain/qipconfigdlg.h | 2 + src/tpMain/qshowimg.cpp | 8 + src/tpMain/qshowimg.h | 3 + src/tpMain/qworkItemdlg.cpp | 9 + src/tpMain/qworkItemdlg.h | 3 +- src/tpMain/qworkmgrui.cpp | 8 +- src/tpMain/qworkmgrui.h | 2 + tpvs17/lpReport/lpreport_en.ts | 897 +++++++++++ tpvs17/lpReport/lpreport_zh.ts | 897 +++++++++++ tpvs17/tpMain/QAlgParamDlg.cpp | 8 +- tpvs17/tpMain/QAlgParamDlg.h | 2 +- tpvs17/tpMain/QModelMgrDlg.cpp | 4 +- tpvs17/tpMain/lpGlobalData.h | 2 +- tpvs17/tpMain/lpMainWin.cpp | 253 +-- tpvs17/tpMain/lpMainWin.h | 5 +- tpvs17/tpMain/lpmain_en.ts | 1224 +++++++++------ tpvs17/tpMain/lpmain_zh.ts | 1953 +++++++++++++----------- tpvs17/wheel.sln | 12 +- 37 files changed, 4494 insertions(+), 1491 deletions(-) create mode 100644 doc/偏距数据.png create mode 100644 doc/旧抠图算法.txt create mode 100644 tpvs17/lpReport/lpreport_en.ts create mode 100644 tpvs17/lpReport/lpreport_zh.ts diff --git a/doc/偏距数据.png b/doc/偏距数据.png new file mode 100644 index 0000000000000000000000000000000000000000..10d1fa39f94490fc926993e2f7223bdd57e5a6c9 GIT binary patch literal 85279 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 Y`1AA>KC9}{AK;7R; EDCircle = edcircles.getCircles(); + double maxR = 0; + int nIndex = -1; + for (int i = 0; i < EDCircle.size(); i++) + { + int startX = EDCircle[i].center.x - EDCircle[i].r; + int startY = EDCircle[i].center.y - EDCircle[i].r; + if (startX < 0 || startY < 0) + continue; + if (EDCircle[i].center.x + EDCircle[i].r > bBaseX || EDCircle[i].center.y + EDCircle[i].r > bBaseY) + continue; + if (EDCircle[i].r > maxR) + { + maxR = EDCircle[i].r; + nIndex = i; + } + } + if (nIndex != -1) + { + int startX = EDCircle[nIndex].center.x * REAIZE - EDCircle[nIndex].r * REAIZE; + int startY = EDCircle[nIndex].center.y * REAIZE - EDCircle[nIndex].r* REAIZE; + double radius = EDCircle[nIndex].r; + int hight = 2 * radius * REAIZE; + + if (startX > 0 && startY > 0 && hight > 0 \ + && startX < src.cols &&startY < src.rows \ + &&hight < src.cols&&hight < src.rows \ + && startX + hight < src.cols && startY + hight < src.rows) + { + Mat cutMat = src(Rect(startX, startY, hight, hight)); + if (cutMat.data != NULL) + { + //Mat dst; + //double rate = src.cols*1.0 / ALG_RESIZE_IMAGE_WIDTH; + //const cv::Size cSize = cv::Size(cutMat.cols*1.0 / rate, cutMat.rows*1.0 / rate); + //cv::resize(cutMat, dst, cSize); + if (hight < 50) + return Mat(); + cv::Point2d center; + center.x = EDCircle[nIndex].center.x * REAIZE; + center.y = EDCircle[nIndex].center.y * REAIZE; + pCircle->ptCenter = center; + + //float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + //pCircle->fRadius = hight*1.0 / fScale; + pCircle->fRadius = radius * REAIZE; + + //2021-05-10 增加图像大小判断 对超过900像素的图像进行再一次压缩 + if (cutMat.cols >= 900 || cutMat.rows >= 900) + { + Mat newCutImg; + cv::resize(cutMat, newCutImg, cv::Size(cutMat.cols / REAIZE, cutMat.rows / REAIZE)); + pCircle->fRadius = pCircle->fRadius / REAIZE; + return newCutImg; + } + return cutMat; + } + } + } + return Mat(); + } + else + { + if (src.empty() || backgroundImg.empty() || src.rows < 500) { + return Mat(); + } + + assert(backgroundImg.type() == CV_8UC1); + + Mat imgTmp, imgBinary; + const cv::Size cSize = cv::Size(ALG_RESIZE_IMAGE_WIDTH, floorf(ALG_RESIZE_IMAGE_WIDTH / (float)src.cols*(float)src.rows)); + cv::resize(src, imgTmp, cSize); + Mat foregroundImg = getForeImage(imgTmp, backgroundImg);// 0421 + + cv::resize(foregroundImg, foregroundImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); + + using namespace luffy_base; + luffy_threshold::Threshold(foregroundImg, imgBinary, nThres);//0421 + + Mat dilatedImgBin; + dilate(imgBinary, dilatedImgBin, Mat::ones(21, 21, CV_32FC1)); + erode(dilatedImgBin, imgBinary, Mat::ones(21, 21, CV_32FC1)); + openOper(imgBinary, Mat::ones(1, 11, CV_32FC1)); + + vector> conts; + cv::findContours(imgBinary, conts, RETR_EXTERNAL, CHAIN_APPROX_NONE); + imgBinary.setTo(0); + + for (int i = 0; i < conts.size(); i++) { + const vector &pt = conts.at(i); + if (pt.size() < 20) { + continue; + } + Rect rt = boundingRect(pt); + if (rt.width < 5 || rt.height < 5) { + continue; + } + drawContours(imgBinary, conts, i, Scalar::all(255), -1); + } + + Mat hit; vector pts; + luffy_hit::firstHit4Circle(imgBinary, hit, pts, Point(cSize.width / 2, cSize.height / 2), 0, cSize.width / 2, 360, luffy_hit::emHitOut2In); + + int nMinFitNum = 100; + luffy_imageProc::RansacParam rs(0.01, 3, 150, nMinFitNum, 240); + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); + + float fRadius; + Point2f ptCenter; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); + + if (!bFind) { + return Mat(); + } + Mat dst; + const int nOffset = 1; + fRadius += nOffset; + Rect rt(ptCenter.x - fRadius + nOffset, ptCenter.y - fRadius + nOffset, 2 * fRadius, 2 * fRadius); + rt &= Rect(0, 0, imgTmp.cols, imgTmp.rows); + imgTmp(rt).copyTo(dst); + static int nCount = cv::getTickCount(); + if (pCircle) { + /*float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + Mat matBig = src - backgroundImg; + pCircle->fRadius = fRadius * fScale; + pCircle->ptCenter = Point(ptCenter.x * fScale, ptCenter.y * fScale); + Rect rt(pCircle->ptCenter.x - pCircle->fRadius + nOffset, pCircle->ptCenter.y - pCircle->fRadius + nOffset, 2 * pCircle->fRadius, 2 * pCircle->fRadius); + rt &= Rect(0, 0, matBig.cols, matBig.rows); + src(rt).copyTo(dst);*/ + float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + Mat matBig = src - backgroundImg; + pCircle->fRadius = fRadius * fScale; + pCircle->ptCenter = Point(ptCenter.x * fScale, ptCenter.y * fScale); + + Mat matBinary; + luffy_threshold::Threshold(matBig, matBinary, nThres); + // add + openOper(matBinary, Mat::ones(3, 3, CV_32FC1)); + Mat hit; vector pts; + luffy_hit::firstHit4Circle(matBinary, hit, pts, pCircle->ptCenter, 0, pCircle->fRadius + 20, 360, luffy_hit::emHitOut2In);//luffy_hit::emHitOut2In + std::map mp; + std::for_each(pts.begin(), pts.end(), [&](Point p) { + double dis = fabs(luffy_math::disofPoints(pCircle->ptCenter, p)); + mp[dis] = p; + }); + + const int bound = 200; + //int startIndex = mp.size() - bound; + std::map::iterator it = mp.begin(); + //std::advance(it, startIndex); + std::vector ppts; + int i = 0; + for (it; it != mp.end(); ++it, ++i) + { + if (i == bound) break; + ppts.push_back(it->second); + } + luffy_imageProc::RansacParam rs(0.01, 5.0, 300, 70, 120); + vector pts2 = luffy_imageProc::fitModelbyRansac(ppts, luffy_imageProc::emModelCircle, &rs); + float fRadius2; + Point2f ptCenter2; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius2, ptCenter2); + if (bFind) { + pCircle->fRadius = fRadius2; + pCircle->ptCenter = ptCenter2; + Rect rt(ptCenter2.x - fRadius2 + nOffset, ptCenter2.y - fRadius2 + nOffset, 2 * fRadius2, 2 * fRadius2); + + if (rt.x < 0 || rt.y < 0 || rt.x + rt.width > matBinary.cols || rt.y + rt.height > matBinary.rows) { + return Mat(); + } + rt &= Rect(0, 0, matBinary.cols, matBinary.rows); + src(rt).copyTo(dst); + } + else + { + return Mat(); + } + } + return dst; + } + + +#else//汽轮型号识别抠图算法 +/* +2020-06-19 使用三种预防措施找圆 +第一阶梯 使用EDCircle算法,图像经过2.5倍增亮找圆 +如若在第一阶梯没有找到圆(找到的圆不符合条件),进入第二阶梯 +第二阶梯 使用EDCircle算法,图像改为原图 +如若在第二阶梯还没找到圆,进入第三阶梯使用传统找圆算法(结合监测背景图) +第三阶梯不管怎样都会找出一个最佳圆 +*/ + + if (src.empty() || backgroundImg.empty() || src.rows < 500) { + return Mat(); + } + bool findFlag = false; + /*第一阶梯找圆*/ + assert(backgroundImg.type() == CV_8UC1); + Mat detectImg; + cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); + int bBaseX = detectImg.cols; + int bBaseY = detectImg.rows; + Mat upLight_Img = detectImg + 1.5 * detectImg;//20200423 修改 对图像进行叠加,增强目标亮度 + blur(upLight_Img, upLight_Img, Size(3, 3)); + EDCircles edcircles(upLight_Img); + vector EDCircle = edcircles.getCircles(); + double maxR = 0; + int nIndex = -1; + for (int i = 0; i < EDCircle.size(); i++) + { + int startX = EDCircle[i].center.x - EDCircle[i].r; + int startY = EDCircle[i].center.y - EDCircle[i].r; + if (startX < 0 || startY <0) + continue; + if (EDCircle[i].center.x + EDCircle[i].r> bBaseX || EDCircle[i].center.y + EDCircle[i].r>bBaseY) + continue; + if (EDCircle[i].r > maxR) + { + maxR = EDCircle[i].r; + nIndex = i; + } + } + if (nIndex != -1) + { + int startX = EDCircle[nIndex].center.x * REAIZE - EDCircle[nIndex].r * REAIZE; + int startY = EDCircle[nIndex].center.y * REAIZE - EDCircle[nIndex].r* REAIZE; + double centerX = EDCircle[nIndex].center.x * REAIZE; + double centerY = EDCircle[nIndex].center.y * REAIZE; + double radius = EDCircle[nIndex].r; + + + if (radius < 50)//小于阈值 进行二次查找 radius一般大于100,小于50像素的基本是其他小圆 + {/*第二阶梯找圆 2020 - 06 - 19 添加 原图查找圆*/ + blur(detectImg, detectImg, Size(3,3)); + EDCircles edcircles2(detectImg); + vector EDCircle2 = edcircles2.getCircles(); + double maxR = 0; + int mIndex = -1; + for (int i = 0; i < EDCircle2.size(); i++) + { + int startX = EDCircle2[i].center.x - EDCircle2[i].r; + int startY = EDCircle2[i].center.y - EDCircle2[i].r; + if (startX < 0 || startY < 0) + continue; + if (EDCircle2[i].center.x + EDCircle2[i].r > bBaseX || EDCircle2[i].center.y + EDCircle2[i].r > bBaseY) + continue; + if (EDCircle2[i].r > maxR) + { + maxR = EDCircle2[i].r; + mIndex = i; + } + } + if (mIndex == -1) + return Mat(); + startX = EDCircle2[nIndex].center.x * REAIZE - EDCircle2[nIndex].r * REAIZE; + startY = EDCircle2[nIndex].center.y * REAIZE - EDCircle2[nIndex].r* REAIZE; + centerX = EDCircle2[nIndex].center.x * REAIZE; + centerY = EDCircle2[nIndex].center.y * REAIZE; + radius = EDCircle2[nIndex].r; + + if (radius < 50)/*第三阶梯找圆*/ + { + if (src.empty() || backgroundImg.empty() || src.rows < 500) { + return Mat(); + } + assert(backgroundImg.type() == CV_8UC1); + Mat imgTmp, imgBinary; + const cv::Size cSize = cv::Size(ALG_RESIZE_IMAGE_WIDTH, floorf(ALG_RESIZE_IMAGE_WIDTH / (float)src.cols*(float)src.rows)); + cv::resize(src, imgTmp, cSize); + Mat foregroundImg = getForeImage(imgTmp, backgroundImg);// 0421 + using namespace luffy_base; //nThres = 90; + luffy_threshold::Threshold(foregroundImg, imgBinary, nThres);//0421 + + Mat dilatedImgBin; + closeOper(imgBinary, 7); + vector> conts; + cv::findContours(imgBinary, conts, RETR_EXTERNAL, CHAIN_APPROX_NONE); + imgBinary.setTo(0); + //筛选最大轮廓的作为圆拟合区域 + int maxsize = 0; + int nbestIndex = 0; + for (int i = 0; i < conts.size(); i++) + { + if (conts.at(i).size()>maxsize) + { + maxsize = conts.at(i).size(); + nbestIndex = i; + } + } + if (conts.size() > 0) + { + drawContours(imgBinary, vector>(1, conts.at(nbestIndex)), -1, Scalar::all(255), -1); + } + Mat hit; vector pts; + luffy_hit::firstHit4Circle(imgBinary, hit, pts, Point(cSize.width / 2, cSize.height / 2), 0, cSize.width / 2, 360, luffy_hit::emHitOut2In); + int nMinFitNum = 150; + if (pts.size() < nMinFitNum)//解决检测目标在图像边缘导致的抠图识别问题 + { + if (conts.size()>0) + pts = conts.at(nbestIndex); + } + + luffy_imageProc::RansacParam rs(0.01, 2, 150, nMinFitNum, 240); + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); + float fRadius; + Point2f ptCenter; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); + + if (!bFind) { + return Mat(); + } + Mat dst; + const int nOffset = 1; + fRadius += nOffset; + Rect rt(ptCenter.x - fRadius + nOffset, ptCenter.y - fRadius + nOffset, 2 * fRadius, 2 * fRadius); + rt &= Rect(0, 0, imgTmp.cols, imgTmp.rows); + imgTmp(rt).copyTo(dst); + static int nCount = cv::getTickCount(); + if (pCircle) { + float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + Mat matBig = src - backgroundImg; + pCircle->fRadius = fRadius * fScale; + pCircle->ptCenter = Point(ptCenter.x * fScale, ptCenter.y * fScale); + + Mat matBinary; + luffy_threshold::Threshold(matBig, matBinary, nThres); + Mat hit; vector pts; + luffy_hit::firstHit4Circle(matBinary, hit, pts, pCircle->ptCenter, 0, pCircle->fRadius + 10, 360, luffy_hit::emHitOut2In);//luffy_hit::emHitOut2In + luffy_imageProc::RansacParam rs(0.01, 2.5, 200, 150, 220); + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); + float fRadius2; + Point2f ptCenter2; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius2, ptCenter2); + if (bFind) { + pCircle->fRadius = fRadius2; + pCircle->ptCenter = ptCenter2; + Rect rt(ptCenter2.x - fRadius2 + nOffset, ptCenter2.y - fRadius2 + nOffset, 2 * fRadius2, 2 * fRadius2); + + if (rt.x < 0 || rt.y < 0 || rt.x + rt.width > matBinary.cols || rt.y + rt.height > matBinary.rows) { + return Mat(); + } + rt &= Rect(0, 0, matBinary.cols, matBinary.rows); + src(rt).copyTo(dst); + int nWidth = ((int)((double)dst.cols / fScale / 4)) * 4; + cv::resize(dst, dst, cv::Size(nWidth, nWidth)); + } + } + + return dst; + } + } + + + int hight = 2 * radius * REAIZE; + + if (startX > 0 && startY > 0 && hight > 0 \ + && startX < src.cols &&startY < src.rows \ + &&hight < src.cols&&hight < src.rows \ + && startX+hightptCenter = center; + pCircle->fRadius = radius * REAIZE / rate; + return dst; + } + } + } + return Mat(); + + /*以下为旧代码 目前不使用*/ + if (src.empty() || backgroundImg.empty() || src.rows < 500) { + return Mat(); + } + + assert(backgroundImg.type() == CV_8UC1); + + Mat imgTmp, imgBinary; + const cv::Size cSize = cv::Size(ALG_RESIZE_IMAGE_WIDTH, floorf(ALG_RESIZE_IMAGE_WIDTH / (float)src.cols*(float)src.rows)); + cv::resize(src, imgTmp, cSize); + + Mat foregroundImg = getForeImage(imgTmp, backgroundImg);// 0421 + + using namespace luffy_base; //nThres = 90; + luffy_threshold::Threshold(foregroundImg, imgBinary, nThres);//0421 + + Mat dilatedImgBin; + closeOper(imgBinary, 7); + //dilate(imgBinary, dilatedImgBin, Mat::ones(7, 7, CV_32FC1));// + //erode(dilatedImgBin, imgBinary, Mat::ones(7, 7, CV_32FC1)); + //openOper(imgBinary, Mat::ones(1, 13, CV_32FC1));//集智抠图问题修改 20190329 + + vector> conts; + cv::findContours(imgBinary, conts, RETR_EXTERNAL, CHAIN_APPROX_NONE); + imgBinary.setTo(0); + + /* + for (int i = 0; i < conts.size(); i++) { + const vector &pt = conts.at(i); + if (pt.size() < 20) { + continue; + } + Rect rt = boundingRect(pt); + if (rt.width < 5 || rt.height < 5) { + continue; + } + drawContours(imgBinary, conts, i, Scalar::all(255), -1); + } + */ + +//筛选最大轮廓的作为圆拟合区域 + int maxsize = 0; + int nbestIndex = 0; + for (int i = 0; i < conts.size(); i++) + { + if (conts.at(i).size()>maxsize) + { + maxsize = conts.at(i).size(); + nbestIndex = i; + } + } + if (conts.size() > 0) + { + drawContours(imgBinary, vector>(1,conts.at(nbestIndex)), -1, Scalar::all(255), -1); + } + //openOper(imgBinary, 17);//集智抠图问题修改 20190329 + + + Mat hit; vector pts; + luffy_hit::firstHit4Circle(imgBinary, hit, pts, Point(cSize.width / 2, cSize.height / 2), 0, cSize.width/ 2, 360, luffy_hit::emHitOut2In); + + //luffy_imageProc::RansacParam rs(0.02, 2.5, 70, 100, 220); + //luffy_imageProc::RansacParam rs(0.01, 2, 150, 150, 240);//20190117 + + int nMinFitNum = 150; + + if (pts.size() < nMinFitNum)//解决检测目标在图像边缘导致的抠图识别问题 + { + if (conts.size()>0) + pts = conts.at(nbestIndex); + } + + luffy_imageProc::RansacParam rs(0.01, 2, 150, nMinFitNum, 240); + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); +#ifdef _DEBUG + Mat imgColor; + cv::cvtColor(imgTmp, imgColor, CV_GRAY2BGR); + for (int i = 0; i < pts.size(); i++) { + imgColor.at(pts.at(i))[0] = 255;//B + imgColor.at< cv::Vec3b >(pts.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts.at(i))[2] = 0;//R + } + for (int i = 0; i < pts2.size(); i++) { + imgColor.at(pts2.at(i))[0] = 0;//B + imgColor.at< cv::Vec3b >(pts2.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts2.at(i))[2] = 255;//R + } +#endif + + float fRadius; + Point2f ptCenter; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); + + if (!bFind) { + return Mat(); + } + Mat dst; + const int nOffset = 1; + fRadius += nOffset; + Rect rt(ptCenter.x - fRadius + nOffset, ptCenter.y - fRadius + nOffset, 2 * fRadius, 2 * fRadius); + rt &= Rect(0, 0, imgTmp.cols, imgTmp.rows); + imgTmp(rt).copyTo(dst); + static int nCount = cv::getTickCount(); + if (pCircle) { + float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + Mat matBig = src - backgroundImg; + pCircle->fRadius = fRadius * fScale; + pCircle->ptCenter = Point(ptCenter.x * fScale, ptCenter.y * fScale); + + Mat matBinary; + luffy_threshold::Threshold(matBig, matBinary, nThres); + Mat hit; vector pts; + luffy_hit::firstHit4Circle(matBinary, hit, pts, pCircle->ptCenter, 0, pCircle->fRadius + 10, 360, luffy_hit::emHitOut2In);//luffy_hit::emHitOut2In + luffy_imageProc::RansacParam rs(0.01, 2.5, 200, 150, 220); + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); + float fRadius2; + Point2f ptCenter2; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius2, ptCenter2); + if (bFind) { + pCircle->fRadius = fRadius2; + pCircle->ptCenter = ptCenter2; + Rect rt(ptCenter2.x - fRadius2 + nOffset, ptCenter2.y - fRadius2 + nOffset, 2 * fRadius2, 2 * fRadius2); + + if (rt.x < 0 || rt.y < 0 || rt.x + rt.width > matBinary.cols || rt.y + rt.height > matBinary.rows ) { + return Mat(); + } + rt &= Rect(0, 0, matBinary.cols, matBinary.rows); + src(rt).copyTo(dst); + int nWidth = ((int)((double)dst.cols / fScale / 4)) * 4; + cv::resize(dst, dst, cv::Size(nWidth, nWidth)); + } + } + +return dst; + +#endif +} + + + +// CircleDetector cd; +// cd.setAlgoType(CircleDetector::PeakCircle); +// cd.setEdgeWidth(cParam.CircleEdgeWidth); +// +// if (cParam.CirclePolarity == 0) +// cd.setPolarity(Polarity::Black2White); +// else +// cd.setPolarity(Polarity::White2Black); +// +// cd.setFindBy(FindBy::Best); +// double difRadiusMin = 0; +// double difRadiusMax = (foregroundImg.cols>foregroundImg.rows? foregroundImg.rows/2 : foregroundImg.cols/2)-50; +// cd.setRadii(difRadiusMin, difRadiusMax); +// cd.setACThres(cParam.CircleACThres); +// vector allScores; +// Vec3f bestCircle; +// float bestScore = cd.detectBest(foregroundImg, Point2f(imgTmp.cols/2, imgTmp.rows/2), bestCircle, &allScores); +// if (abs(bestScore) <= FLT_EPSILON || bestCircle == Vec3f::zeros()) { +// return Mat(); +// } +// +// Point2f cen(bestCircle[0], bestCircle[1]); +// double r = bestCircle[2]; +// Rect rect; +// rect.x = cen.x - r; +// rect.y = cen.y - r; +// if (rect.x < 0) +// rect.x = 0; +// if (rect.y < 0) +// rect.y = 0; +// rect.width = 2 * r; +// rect.height = 2 * r; +// Mat rltMat = src(rect); +// if (pCircle) +// { +// pCircle->fRadius = r; +// pCircle->ptCenter = cen; +// } +// return rltMat; diff --git a/runner17/language/English/lpmain_en.qm b/runner17/language/English/lpmain_en.qm index 72aaea6f2905afb14e43f3e98892427caf468728..33a4b0dfda4e211ac3830fe66b4e03b4ef7e31e7 100644 GIT binary patch delta 8714 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 TrXR*++Z#dh^FkK%?au!KB{t#X diff --git a/src/algorithm/ImageProcess.cpp b/src/algorithm/ImageProcess.cpp index 00c8bd0..843ad12 100644 --- a/src/algorithm/ImageProcess.cpp +++ b/src/algorithm/ImageProcess.cpp @@ -77,6 +77,8 @@ cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center, double &rad { int startX = EDCircle[i].center.x - EDCircle[i].r; int startY = EDCircle[i].center.y - EDCircle[i].r; + centerX = EDCircle[i].center.x * REAIZE; + centerY = EDCircle[i].center.y * REAIZE; if (startX < 0 || startY < 0) continue; if (EDCircle[i].center.x + EDCircle[i].r > bBaseX || EDCircle[i].center.y + EDCircle[i].r > bBaseY) @@ -209,6 +211,8 @@ cv::Mat ImageProcess::findCircleByBackground(const Mat &srcImg, const Mat& backg float centerY = 0; for (int i = 0; i < EDCircle.size(); i++) { + centerX = EDCircle[i].center.x * REAIZE; + centerY = EDCircle[i].center.y * REAIZE; int startX = EDCircle[i].center.x - EDCircle[i].r; int startY = EDCircle[i].center.y - EDCircle[i].r; if (startX < 0 || startY < 0) diff --git a/src/tpMain/DetectState.cpp b/src/tpMain/DetectState.cpp index 1418fb2..84433a3 100644 --- a/src/tpMain/DetectState.cpp +++ b/src/tpMain/DetectState.cpp @@ -31,7 +31,6 @@ DetectState::DetectState() DetectState::~DetectState() { - //save(); } void DetectState::init(QString strPath) diff --git a/src/tpMain/WheelModel.cpp b/src/tpMain/WheelModel.cpp index 2454dcc..3b28118 100644 --- a/src/tpMain/WheelModel.cpp +++ b/src/tpMain/WheelModel.cpp @@ -70,12 +70,11 @@ bool WheelModel::initComModel(const QString&strBase) m_pDetectModel = new ImageCompareModel; } QString str = strBase + "template\\" + m_strModelID + "\\model.yml"; - //QString str = strBase + "模板\\" + m_strModelID + "\\model.yml"; std::string strs = str.toLocal8Bit().toStdString(); - bool bFlags = m_pDetectModel->readFromFile(strs/*str.toLatin1().data()*/); + bool bFlags = m_pDetectModel->readFromFile(strs); if (!bFlags) { m_pDetectModel->train(m_pTempImage->getImgVector()); - bFlags = m_pDetectModel->save2file(strs/*string((const char *)str.toLocal8Bit())*/); + bFlags = m_pDetectModel->save2file(strs); } return bFlags; } @@ -161,15 +160,10 @@ void WheelModel::setRepeatNum(int nValue) int WheelModel::getRepeatNum() const { return m_pDetectModel->getRepeatNum(); - //return m_nRotate; } ICompareModel * WheelModel::getImageComModel() const { -// if (!m_pDetectModel) -// { -// m_pDetectModel = new ImageCompareModel; -// } return m_pDetectModel; } diff --git a/src/tpMain/WheelNet.cpp b/src/tpMain/WheelNet.cpp index 8aae5f7..5786f83 100644 --- a/src/tpMain/WheelNet.cpp +++ b/src/tpMain/WheelNet.cpp @@ -2,15 +2,15 @@ #include "InfoFile.h" #include "..\NetWheel\net4wheel_global.h" #include "QZkJsonParser.h" -#include "qlibrary.h" -#include "qhostaddress.h" -#include "QDebug" +#include +#include +#include #include "qipconfigdlg.h" -#include "qdebug.h" +#include "lpGlobalData.h" + #define JSONG_MYSELF_FILE "\\user\\selfdefine.json" #pragma execution_character_set("utf-8") - //emTypeResultChannel 结果通道 0x16 //emTypeTriger 设置触发延时相关参数 CWheelNet::CWheelNet(QString strRoot) @@ -99,11 +99,8 @@ bool CWheelNet::loadNet() #endif if (lib.load()){ _Net4WheelCreate func = (_Net4WheelCreate)lib.resolve("Net4WheelCreate"); - //QHostAddress *pAdd = new QHostAddress; - QHostAddress pAdd;// = new QHostAddress; + QHostAddress pAdd; pAdd.setAddress(m_pIpConfig->m_TcpAddress); - //pAdd->setAddress(m_pIpConfig->m_TcpAddress); - //m_pNet4Wheel = func(*pAdd, m_pIpConfig->m_TcpPort); m_pNet4Wheel = func(pAdd, m_pIpConfig->m_TcpPort); connect(m_pNet4Wheel, SIGNAL(RecvDatas(QByteArray)), this, SLOT(DataRecvByte(QByteArray))); connect(m_pNet4Wheel, SIGNAL(SignalConnect(QVariantMap)), this, SLOT(onConnect(QVariantMap))); @@ -121,7 +118,6 @@ void CWheelNet::sendData(QString strData) arr.append(strData); if (m_pIpConfig){ QString strTarget = genAddressPort(m_pIpConfig->m_ClientAddress, QString::number(m_pIpConfig->m_ClientPort)); - //m_pNet4Wheel->sendDatas(strTarget, arr); emit sgSendData2Dv(strTarget, arr); } } @@ -129,7 +125,6 @@ void CWheelNet::sendData(QString strData) bool CWheelNet::sendDataFrame(QString strData) { /*调用框架接口 发送网络数据*/ - //m_pCallBack return true; } @@ -318,6 +313,19 @@ Q_SLOT void CWheelNet::onConnect(QVariantMap vMap) if (client_State == "Disconnect" || client_State == "close listen ") { bConnect = false; } + + if (m_type == "client") + { + QString state = vMap.value("client_state").toString(); + if (state == "connect") + { + lpGlobalData::instance()->m_plcConnect = true; + } + else { + lpGlobalData::instance()->m_plcConnect = false; + } + } + QString str = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); str.append(":\n"); str.append("type=" + m_type + " " + "address:" + address + " sourcePort:" + port + " is " + client_State); diff --git a/src/tpMain/cryptokey/QCryptokeyUI.cpp b/src/tpMain/cryptokey/QCryptokeyUI.cpp index 00c274b..6d00f64 100644 --- a/src/tpMain/cryptokey/QCryptokeyUI.cpp +++ b/src/tpMain/cryptokey/QCryptokeyUI.cpp @@ -38,7 +38,7 @@ Q_SLOT void QCryptokeyUI::onButtonClicked() QString strKey = ui.textEdit->toPlainText(); if (strKey.isEmpty()) { - QMessageBox::information(this, tr("提示"), "请输入注册码"); + QMessageBox::information(this, tr("提示"), tr("请输入注册码")); return; } QString strSerialNo = ui.m_lineEdit_Serial->text(); @@ -46,15 +46,15 @@ Q_SLOT void QCryptokeyUI::onButtonClicked() if (check == false) { - QMessageBox::information(this, tr("提示"), "注册码不匹配,请重新输入"); + QMessageBox::information(this, tr("提示"), tr("注册码不匹配,请重新输入")); return; } else { - ui.m_label_Active->setText("已激活"); + ui.m_label_Active->setText(tr("已激活")); ui.m_label_Active->setStyleSheet("color:rgb(10, 201, 10)"); emit sgRegisterFinish(true); - QMessageBox::information(this, tr("提示"), "系统激活完成"); + QMessageBox::information(this, tr("提示"), tr("系统激活完成")); } } else if (strObj == "pushButton_2") diff --git a/src/tpMain/qaddchanneldlg.cpp b/src/tpMain/qaddchanneldlg.cpp index 61d7556..764ca02 100644 --- a/src/tpMain/qaddchanneldlg.cpp +++ b/src/tpMain/qaddchanneldlg.cpp @@ -44,3 +44,11 @@ Q_SLOT void QAddChannelDlg::SlotFunc() QDialog::close(); } } + +void QAddChannelDlg::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} \ No newline at end of file diff --git a/src/tpMain/qaddchanneldlg.h b/src/tpMain/qaddchanneldlg.h index d055d85..63ebe20 100644 --- a/src/tpMain/qaddchanneldlg.h +++ b/src/tpMain/qaddchanneldlg.h @@ -11,8 +11,10 @@ public: QAddChannelDlg(QWidget *parent = 0); ~QAddChannelDlg(); Q_SLOT void SlotFunc(); - QString GetData(QString &Channelname,int &m_value); - + + QString GetData(QString &Channelname, int &m_value); +protected: + virtual void changeEvent(QEvent *event); private: Ui::QAddChannelDlg ui; QString m_Channelname; diff --git a/src/tpMain/qaddmodel.cpp b/src/tpMain/qaddmodel.cpp index 00388d0..620f060 100644 --- a/src/tpMain/qaddmodel.cpp +++ b/src/tpMain/qaddmodel.cpp @@ -56,4 +56,10 @@ void QAddModel::SetClearData() ui.wf_model_edit_ply->setText(""); } - +void QAddModel::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} diff --git a/src/tpMain/qaddmodel.h b/src/tpMain/qaddmodel.h index 9c75b99..530aeef 100644 --- a/src/tpMain/qaddmodel.h +++ b/src/tpMain/qaddmodel.h @@ -25,6 +25,8 @@ public: QMap getData(); void SetClearData(); +protected: + virtual void changeEvent(QEvent *event); }; #endif // QADDMODEL_H diff --git a/src/tpMain/qaddtimedlg.cpp b/src/tpMain/qaddtimedlg.cpp index 60f8e5d..1a8ed96 100644 --- a/src/tpMain/qaddtimedlg.cpp +++ b/src/tpMain/qaddtimedlg.cpp @@ -59,3 +59,11 @@ Q_SLOT void QAddTimeDlg::SlotCancle() { QDialog::close(); } + +void QAddTimeDlg::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} diff --git a/src/tpMain/qaddtimedlg.h b/src/tpMain/qaddtimedlg.h index 7aedc73..689eb48 100644 --- a/src/tpMain/qaddtimedlg.h +++ b/src/tpMain/qaddtimedlg.h @@ -13,8 +13,11 @@ public: ~QAddTimeDlg(); Q_SLOT void SlotOK(); Q_SLOT void SlotCancle(); - void SetInfo(TimeStruct m_timeStruct, int model=0); + + void SetInfo(TimeStruct m_timeStruct, int model = 0); void GetInfo(TimeStruct &m_timeStruct); +protected: + virtual void changeEvent(QEvent *event); private: Ui::QAddTimeDlg ui; }; diff --git a/src/tpMain/qchannelmanager.cpp b/src/tpMain/qchannelmanager.cpp index ed0a4bc..e24ac5d 100644 --- a/src/tpMain/qchannelmanager.cpp +++ b/src/tpMain/qchannelmanager.cpp @@ -136,4 +136,12 @@ void QChannelManager::updateShow() nIndex++; } } -} \ No newline at end of file +} + +void QChannelManager::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} diff --git a/src/tpMain/qchannelmanager.h b/src/tpMain/qchannelmanager.h index fbefa9e..ae5504e 100644 --- a/src/tpMain/qchannelmanager.h +++ b/src/tpMain/qchannelmanager.h @@ -16,6 +16,8 @@ public: Q_SLOT void SlotcellClicked(const QModelIndex & index); Q_SLOT void onOkMody(); void updateShow(); +protected: + virtual void changeEvent(QEvent *event); private: Ui::QChannelManager ui; class QTableView *channelMgr_tableView; diff --git a/src/tpMain/qdia2thsetting.cpp b/src/tpMain/qdia2thsetting.cpp index dff00c8..848a2ec 100644 --- a/src/tpMain/qdia2thsetting.cpp +++ b/src/tpMain/qdia2thsetting.cpp @@ -33,3 +33,10 @@ Q_SLOT void QDia2ThSetting::onChangeValue() infobox.exec(); emit sgSavePara(); } +void QDia2ThSetting::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} \ No newline at end of file diff --git a/src/tpMain/qdia2thsetting.h b/src/tpMain/qdia2thsetting.h index a3db031..acaafe8 100644 --- a/src/tpMain/qdia2thsetting.h +++ b/src/tpMain/qdia2thsetting.h @@ -13,6 +13,8 @@ public: ~QDia2ThSetting(); void SetValue(float *m_B, float *m_K); Q_SLOT void onChangeValue(); +protected: + virtual void changeEvent(QEvent *event); signals: void sgSavePara(); private: diff --git a/src/tpMain/qipconfigdlg.cpp b/src/tpMain/qipconfigdlg.cpp index c706338..d8e5802 100644 --- a/src/tpMain/qipconfigdlg.cpp +++ b/src/tpMain/qipconfigdlg.cpp @@ -71,3 +71,11 @@ Q_SLOT void QIPConfigDlg::SlotOK() { QDialog::accept(); } + +void QIPConfigDlg::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} diff --git a/src/tpMain/qipconfigdlg.h b/src/tpMain/qipconfigdlg.h index 7b381eb..fedd11a 100644 --- a/src/tpMain/qipconfigdlg.h +++ b/src/tpMain/qipconfigdlg.h @@ -30,6 +30,8 @@ public: Q_SLOT void SlotCloseServer(); Q_SLOT void SlotOpenServer(); Q_SLOT void SlotOK(); +protected: + virtual void changeEvent(QEvent *event); private: Ui::QIPConfigDlg ui; signals: diff --git a/src/tpMain/qshowimg.cpp b/src/tpMain/qshowimg.cpp index 783e8aa..cf70e58 100644 --- a/src/tpMain/qshowimg.cpp +++ b/src/tpMain/qshowimg.cpp @@ -31,3 +31,11 @@ void QShowImg::setPicPath(QString m_filePath /*= QString()*/) ui.label->setPixmap(m_pix.scaled(nwidth,370)); } } + +void QShowImg::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} diff --git a/src/tpMain/qshowimg.h b/src/tpMain/qshowimg.h index f656a62..4945ed8 100644 --- a/src/tpMain/qshowimg.h +++ b/src/tpMain/qshowimg.h @@ -12,7 +12,10 @@ public: QShowImg(QWidget *parent = 0); ~QShowImg(); Q_SLOT void setPicPath(QString m_filePath); + Q_SLOT void showImg(); +protected: + virtual void changeEvent(QEvent *event); signals: void sgChangeImg(); private: diff --git a/src/tpMain/qworkItemdlg.cpp b/src/tpMain/qworkItemdlg.cpp index dc67f34..dbe037f 100644 --- a/src/tpMain/qworkItemdlg.cpp +++ b/src/tpMain/qworkItemdlg.cpp @@ -50,3 +50,12 @@ Q_SLOT void QWorkItemDlg::onOk() QDialog::accept(); } +void QWorkItemDlg::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} + + diff --git a/src/tpMain/qworkItemdlg.h b/src/tpMain/qworkItemdlg.h index 94bd5f7..3f3f739 100644 --- a/src/tpMain/qworkItemdlg.h +++ b/src/tpMain/qworkItemdlg.h @@ -19,7 +19,8 @@ public: }; private: Q_SLOT void onOk(); - +protected: + virtual void changeEvent(QEvent *event); private: Ui::QWorkItemUI ui; diff --git a/src/tpMain/qworkmgrui.cpp b/src/tpMain/qworkmgrui.cpp index 0e01a55..d76fac8 100644 --- a/src/tpMain/qworkmgrui.cpp +++ b/src/tpMain/qworkmgrui.cpp @@ -683,4 +683,10 @@ void QWorkMgrUI::UpdateTabView(QString strName, TypeSelect enTymodel) } } - +void QWorkMgrUI::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} diff --git a/src/tpMain/qworkmgrui.h b/src/tpMain/qworkmgrui.h index f48b16a..0080f59 100644 --- a/src/tpMain/qworkmgrui.h +++ b/src/tpMain/qworkmgrui.h @@ -47,6 +47,8 @@ public: void UpTableModel(); void UpdateTableView(QString str); void UpdateTabView(QString strName, TypeSelect enTymodel); +protected: + virtual void changeEvent(QEvent *event); protected: virtual void closeEvent(QCloseEvent *event); signals: diff --git a/tpvs17/lpReport/lpreport_en.ts b/tpvs17/lpReport/lpreport_en.ts new file mode 100644 index 0000000..f65da97 --- /dev/null +++ b/tpvs17/lpReport/lpreport_en.ts @@ -0,0 +1,897 @@ + + + + + QReportWidget + + + + 型号 + + + + + + 数量 + + + + + 编号 + + + + + 请选择对应时间并查询数据! + + + + + QTimeDlg + + + 时间设置 + + + + + + 0 + + + + + + 1 + + + + + + 2 + + + + + + 3 + + + + + + 4 + + + + + + 5 + + + + + + 6 + + + + + + 7 + + + + + + 8 + + + + + + 9 + + + + + + 10 + + + + + + 11 + + + + + + 12 + + + + + + 13 + + + + + + 14 + + + + + + 15 + + + + + + 16 + + + + + + 17 + + + + + + 18 + + + + + + 19 + + + + + + 20 + + + + + + 21 + + + + + + 22 + + + + + + 23 + + + + + 24 + + + + + 25 + + + + + 26 + + + + + 27 + + + + + 28 + + + + + 29 + + + + + 30 + + + + + 31 + + + + + 32 + + + + + 33 + + + + + 34 + + + + + 35 + + + + + 36 + + + + + 37 + + + + + 38 + + + + + 39 + + + + + 40 + + + + + 41 + + + + + 42 + + + + + 43 + + + + + 44 + + + + + 45 + + + + + 46 + + + + + 47 + + + + + 48 + + + + + 49 + + + + + 50 + + + + + 51 + + + + + 52 + + + + + 53 + + + + + 54 + + + + + 55 + + + + + 56 + + + + + 57 + + + + + 58 + + + + + 59 + + + + + 小时 + + + + + 分钟 + + + + + 2017/00/00 00:00 + + + + + 确定 + + + + + TestWidget + + + TestWidget + + + + + lpReport + + + 数据记录查看 + + + + + + + + + + + 共显示%1条记录 + + + + + + + + + + + + + + 第%1页 共%2页 + + + + + + + + + + + + + + + + + + + + + 提示 + + + + + + 您选择的班次时间是隔夜的,请您重新选择一下当前查询的日期,再查询 + + + + + + + 您选择的日期不合理,请您重新选择一下当前查询的日期,再查询 + + + + + 查询了%1-%2的生产数据 + + + + + + 起始时间:%1 到 结束时间:%2 的历史记录 + + + + + + + 全部 + + + + + + + 正在查询数据,请稍后 + + + + + + + + 没有数据,请重新查询 + + + + + + + 请选择保存文件的路径 + + + + + + 正在导出数据,请稍等 + + + + + 导出了%1-%2的生产数据 + + + + + + + 数据导出完成 + + + + + 查询了%1-%2的日志数据 + + + + + + + 使用记录查询 + + + + + + + 报警记录查询 + + + + + + + 运行状态查询 + + + + + 导出了%1-%2的日志数据 + + + + + 您选择的日期不合理,请您重新起始日期,再查询 + + + + + 查询了%1-%2的统计数据 + + + + + 导出了%1-%2的统计数据 + + + + + 确认 + + + + + 取消 + + + + + 从%1到%2统计的数据如下 + + + + + 序号 + + + + + 型号 + + + + + 数量 + + + + + + 总数 + + + + + 时间: + + + + + 用户: + + + + + 查询进度 + + + + + 数据查询中,请稍后..... + + + + + 系统自动进行清理完成 + + + + + 正在查询数据 + + + + + 起始时间:%1 到 结束时间:%2 的历史记录 共%3条 + + + + + 数据查询完成 + + + + + 操作已生效 + + + + + 统计结果 + + + + + 统计完成 + + + + + 日期时间 + + + + + 匹配型号 + + + + + 相似度 + + + + + 消耗时间s + + + + + 直径mm + + + + + 厚度mm + + + + + 缩略图 + + + + + uid + + + + + 正在查询记录,请稍等 + + + + + 从%1 到 %2 的记录 共%3条 + + + + + 时间 + + + + + 信息 + + + + + + + + 全天 + + + + + 生产数据查询 + + + + + NG + + + + + lpReportClass + + + lpReport + + + + + + 生产数据查询 + + + + + 生产数据统计 + + + + + 日志记录 + + + + + + 显示数据数(条) + + + + + + 50 + + + + + + 上一页 + + + + + + + + TextLabel + + + + + + 下一页 + + + + + 标题 + + + + + 双击单条记录显示图片 + + + + + + 开始日期时间: + + + + + + + + + + 2017-11-11 11:11:11 + + + + + + 设置开始时间 + + + + + + + 结束日期时间: + + + + + + + 设置结束时间 + + + + + 筛选型号 + + + + + + 所有 + + + + + + 生产班次 + + + + + 全天 + + + + + 查询数量 + + + + + 0 + + + + + + + 查询 + + + + + + + 导出CSV + + + + + 数据类型查询 + + + + + 起始日期时间: + + + + + 设置起始时间 + + + + + 报警记录查询 + + + + diff --git a/tpvs17/lpReport/lpreport_zh.ts b/tpvs17/lpReport/lpreport_zh.ts new file mode 100644 index 0000000..1ab3e4e --- /dev/null +++ b/tpvs17/lpReport/lpreport_zh.ts @@ -0,0 +1,897 @@ + + + + + QReportWidget + + + + 型号 + + + + + + 数量 + + + + + 编号 + + + + + 请选择对应时间并查询数据! + + + + + QTimeDlg + + + 时间设置 + + + + + + 0 + + + + + + 1 + + + + + + 2 + + + + + + 3 + + + + + + 4 + + + + + + 5 + + + + + + 6 + + + + + + 7 + + + + + + 8 + + + + + + 9 + + + + + + 10 + + + + + + 11 + + + + + + 12 + + + + + + 13 + + + + + + 14 + + + + + + 15 + + + + + + 16 + + + + + + 17 + + + + + + 18 + + + + + + 19 + + + + + + 20 + + + + + + 21 + + + + + + 22 + + + + + + 23 + + + + + 24 + + + + + 25 + + + + + 26 + + + + + 27 + + + + + 28 + + + + + 29 + + + + + 30 + + + + + 31 + + + + + 32 + + + + + 33 + + + + + 34 + + + + + 35 + + + + + 36 + + + + + 37 + + + + + 38 + + + + + 39 + + + + + 40 + + + + + 41 + + + + + 42 + + + + + 43 + + + + + 44 + + + + + 45 + + + + + 46 + + + + + 47 + + + + + 48 + + + + + 49 + + + + + 50 + + + + + 51 + + + + + 52 + + + + + 53 + + + + + 54 + + + + + 55 + + + + + 56 + + + + + 57 + + + + + 58 + + + + + 59 + + + + + 小时 + + + + + 分钟 + + + + + 2017/00/00 00:00 + + + + + 确定 + + + + + TestWidget + + + TestWidget + + + + + lpReport + + + 数据记录查看 + + + + + + + + + + + 共显示%1条记录 + + + + + + + + + + + + + + 第%1页 共%2页 + + + + + + + + + + + + + + + + + + + + + 提示 + + + + + + 您选择的班次时间是隔夜的,请您重新选择一下当前查询的日期,再查询 + + + + + + + 您选择的日期不合理,请您重新选择一下当前查询的日期,再查询 + + + + + 查询了%1-%2的生产数据 + + + + + + 起始时间:%1 到 结束时间:%2 的历史记录 + + + + + + + 全部 + + + + + + + 正在查询数据,请稍后 + + + + + + + + 没有数据,请重新查询 + + + + + + + 请选择保存文件的路径 + + + + + + 正在导出数据,请稍等 + + + + + 导出了%1-%2的生产数据 + + + + + + + 数据导出完成 + + + + + 查询了%1-%2的日志数据 + + + + + + + 使用记录查询 + + + + + + + 报警记录查询 + + + + + + + 运行状态查询 + + + + + 导出了%1-%2的日志数据 + + + + + 您选择的日期不合理,请您重新起始日期,再查询 + + + + + 查询了%1-%2的统计数据 + + + + + 导出了%1-%2的统计数据 + + + + + 确认 + + + + + 取消 + + + + + 从%1到%2统计的数据如下 + + + + + 序号 + + + + + 型号 + + + + + 数量 + + + + + + 总数 + + + + + 时间: + + + + + 用户: + + + + + 查询进度 + + + + + 数据查询中,请稍后..... + + + + + 系统自动进行清理完成 + + + + + 正在查询数据 + + + + + 起始时间:%1 到 结束时间:%2 的历史记录 共%3条 + + + + + 数据查询完成 + + + + + 操作已生效 + + + + + 统计结果 + + + + + 统计完成 + + + + + 日期时间 + + + + + 匹配型号 + + + + + 相似度 + + + + + 消耗时间s + + + + + 直径mm + + + + + 厚度mm + + + + + 缩略图 + + + + + uid + + + + + 正在查询记录,请稍等 + + + + + 从%1 到 %2 的记录 共%3条 + + + + + 时间 + + + + + 信息 + + + + + + + + 全天 + + + + + 生产数据查询 + + + + + NG + + + + + lpReportClass + + + lpReport + + + + + + 生产数据查询 + + + + + 生产数据统计 + + + + + 日志记录 + + + + + + 显示数据数(条) + + + + + + 50 + + + + + + 上一页 + + + + + + + + TextLabel + + + + + + 下一页 + + + + + 标题 + + + + + 双击单条记录显示图片 + + + + + + 开始日期时间: + + + + + + + + + + 2017-11-11 11:11:11 + + + + + + 设置开始时间 + + + + + + + 结束日期时间: + + + + + + + 设置结束时间 + + + + + 筛选型号 + + + + + + 所有 + + + + + + 生产班次 + + + + + 全天 + + + + + 查询数量 + + + + + 0 + + + + + + + 查询 + + + + + + + 导出CSV + + + + + 数据类型查询 + + + + + 起始日期时间: + + + + + 设置起始时间 + + + + + 报警记录查询 + + + + diff --git a/tpvs17/tpMain/QAlgParamDlg.cpp b/tpvs17/tpMain/QAlgParamDlg.cpp index 7d36047..05ad981 100644 --- a/tpvs17/tpMain/QAlgParamDlg.cpp +++ b/tpvs17/tpMain/QAlgParamDlg.cpp @@ -1,4 +1,4 @@ -#include "QAlgParamDlg.h" +#include "QAlgParamDlg.h" #include "DetectState.h" #include "qshowimg.h" #include @@ -94,7 +94,7 @@ void QAlgParamDlg::getParam() Q_SLOT void QAlgParamDlg::onChangeBG() { QFileDialog fileDialog; - fileDialog.setWindowTitle(tr("ѡıͼ")); + fileDialog.setWindowTitle(tr("请选择您的背景图")); fileDialog.setNameFilter("Picture(*.bmp *.jpg *.png)"); fileDialog.setFileMode(QFileDialog::ExistingFiles); if (fileDialog.exec() == QDialog::Accepted) @@ -123,9 +123,9 @@ Q_SLOT void QAlgParamDlg::onChangeBG() //return false; } //emit sgChangeBG(DstPath); - QMessageBox infobox(QMessageBox::Information, tr("ʾ"), tr("ͼɣ."), QMessageBox::Yes, NULL); + QMessageBox infobox(QMessageBox::Information, tr("提示"), tr("背景图更新完成,请重启本软件."), QMessageBox::Yes, NULL); infobox.setWindowIcon(QIcon(":/image/leaper")); - infobox.setButtonText(QMessageBox::Yes, tr("ȷ")); + infobox.setButtonText(QMessageBox::Yes, tr("确认")); infobox.exec(); } } diff --git a/tpvs17/tpMain/QAlgParamDlg.h b/tpvs17/tpMain/QAlgParamDlg.h index 9f75a2c..da91588 100644 --- a/tpvs17/tpMain/QAlgParamDlg.h +++ b/tpvs17/tpMain/QAlgParamDlg.h @@ -1,4 +1,4 @@ -#ifndef _QALGPARAMDLG_H_ +#ifndef _QALGPARAMDLG_H_ #define _QALGPARAMDLG_H_ #include diff --git a/tpvs17/tpMain/QModelMgrDlg.cpp b/tpvs17/tpMain/QModelMgrDlg.cpp index 8f5f381..60fdc3d 100644 --- a/tpvs17/tpMain/QModelMgrDlg.cpp +++ b/tpvs17/tpMain/QModelMgrDlg.cpp @@ -509,7 +509,7 @@ Q_SLOT void QModelMgrDlg::onTextChanged(const QString& str) else { QStringList strFilter = models.filter(str); m_pModelLists->setModelList(strFilter); - QString m_str = QString("%1 %2 个型号").arg(tr("共")).arg(strFilter.size()).arg(tr("个型号")); + QString m_str = QString("%1 %2 %3").arg(tr("共")).arg(strFilter.size()).arg(tr("个型号")); ui.ModelMgr_label_Model_number->setText(m_str); } } @@ -1070,7 +1070,7 @@ void QModelMgrDlg::showEvent(QShowEvent *event) strModels.removeAll("NG"); m_pModelLists->setModelList(strModels); - QString m_str = QString("%1 %2 个型号").arg(tr("共")).arg(strModels.size()).arg(tr("个型号")); + QString m_str = QString("%1 %2 %3").arg(tr("共")).arg(strModels.size()).arg(tr("个型号")); ui.ModelMgr_label_Model_number->setText(m_str); } } diff --git a/tpvs17/tpMain/lpGlobalData.h b/tpvs17/tpMain/lpGlobalData.h index aff2305..75ebbb1 100644 --- a/tpvs17/tpMain/lpGlobalData.h +++ b/tpvs17/tpMain/lpGlobalData.h @@ -22,7 +22,7 @@ public: int m_level{ 0 }; QString m_curUser{ "" }; bool m_bCheckLinese{ false };//ע֤ true ʾעᣬfalse ʾδע - + bool m_plcConnect{ false }; }; #endif diff --git a/tpvs17/tpMain/lpMainWin.cpp b/tpvs17/tpMain/lpMainWin.cpp index 7f552cc..b92ef60 100644 --- a/tpvs17/tpMain/lpMainWin.cpp +++ b/tpvs17/tpMain/lpMainWin.cpp @@ -23,14 +23,15 @@ #include #include "lpCryptokey.h" -#define VERSION_HUB "3.0.1.5" +#define VERSION_HUB "3.0.1.6" #define VERSION_ALG "3.0.1.4" -#define UPDATE_TIME "2021-09-28" +#define UPDATE_TIME "2021-10-08" #pragma execution_character_set("utf-8") lpMainWin::lpMainWin(QWidget *parent) : QMainWindow(parent) { + ui.setupUi(this); {//加载语言设置 QSettings languageSetting("hubdetect.ini", QSettings::IniFormat); QString strLanguage = languageSetting.value("language", "Chinese").toString(); @@ -42,7 +43,7 @@ lpMainWin::lpMainWin(QWidget *parent) qRegisterMetaType("TimeStruct"); m_screen.ShowMsg(tr("加载必要模块.....")); onInitCoreCtrl(); - ui.setupUi(this); + onInitAbout(); { QGridLayout *pLayout = new QGridLayout(ui.cam_win_1); @@ -52,38 +53,34 @@ lpMainWin::lpMainWin(QWidget *parent) ui.cam_win_1->setLayout(pLayout); } { - connect(ui.action_userManager, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_Login, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_about, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_setting_ip, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_cali_raster, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_setting_ban, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_debug, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_connect_mode, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_checkdata, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_modelmgr, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_algParam, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.action_register, SIGNAL(triggered()), this, SLOT(onActionClicked())); - - connect(ui.actionSystemSeting, SIGNAL(triggered()), this, SLOT(onActionClicked())); - connect(ui.actioncamSetting, SIGNAL(triggered()), this, SLOT(onActionClicked())); - - connect(ui.btn_start_detect, SIGNAL(clicked()), this, SLOT(onButtonClicked())); - connect(ui.btn_clear_data, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + connect(ui.action_userManager, SIGNAL(triggered()), this, SLOT(onActionClicked()));//用户管理 + connect(ui.action_Login, SIGNAL(triggered()), this, SLOT(onActionClicked()));//用户登录 + connect(ui.action_about, SIGNAL(triggered()), this, SLOT(onActionClicked()));//关于 + connect(ui.action_setting_ip, SIGNAL(triggered()), this, SLOT(onActionClicked()));//IP设置 + connect(ui.action_cali_raster, SIGNAL(triggered()), this, SLOT(onActionClicked()));//光栅尺 + connect(ui.action_setting_ban, SIGNAL(triggered()), this, SLOT(onActionClicked()));//班次设置 + connect(ui.action_debug, SIGNAL(triggered()), this, SLOT(onActionClicked()));//调试助手 + connect(ui.action_connect_mode, SIGNAL(triggered()), this, SLOT(onActionClicked()));//连接模式 + connect(ui.action_checkdata, SIGNAL(triggered()), this, SLOT(onActionClicked()));//历史数据查看页面 + connect(ui.action_modelmgr, SIGNAL(triggered()), this, SLOT(onActionClicked()));//模板管理 + connect(ui.action_algParam, SIGNAL(triggered()), this, SLOT(onActionClicked()));//算法参数设置 + connect(ui.action_register, SIGNAL(triggered()), this, SLOT(onActionClicked()));//注册页面 + connect(ui.actionSystemSeting, SIGNAL(triggered()), this, SLOT(onActionClicked()));//系统参数设置 + connect(ui.actioncamSetting, SIGNAL(triggered()), this, SLOT(onActionClicked()));//相机设置 + + connect(ui.btn_start_detect, SIGNAL(clicked()), this, SLOT(onButtonClicked()));//开始检测 停止检测 + connect(ui.btn_clear_data, SIGNAL(clicked()), this, SLOT(onButtonClicked()));//清空统计 - ui.action_userManager->setVisible(false); + ui.action_userManager->setVisible(false);//默认用户管理菜单隐藏 只有相应权限才能显示 + //下拉菜单 布局 工具菜单 配置相关系统设置菜单 QMenu *pToolMenu = new QMenu(this); -// QFont font; -// font.setPixelSize(24); -// pToolMenu->setFont(font); - pToolMenu->addAction(ui.action_cali_raster); pToolMenu->addAction(ui.action_setting_ban); pToolMenu->addAction(ui.action_setting_ip); - pToolMenu->addAction(ui.action_debug); - pToolMenu->addAction(ui.actionSystemSeting); pToolMenu->addAction(ui.actioncamSetting); + pToolMenu->addAction(ui.actionSystemSeting); pToolMenu->addAction(ui.action_algParam); + pToolMenu->addAction(ui.action_debug); QToolButton* pbutton = new QToolButton(this); pbutton->setMenu(pToolMenu); @@ -93,6 +90,8 @@ lpMainWin::lpMainWin(QWidget *parent) pbutton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); pbutton->setPopupMode(QToolButton::InstantPopup); ui.mainToolBar->addWidget(pbutton); + + //帮助 下拉菜单 QMenu *pHelpMenu = new QMenu(this); pHelpMenu->addAction(ui.action_about); pHelpMenu->addAction(ui.action_register); @@ -106,17 +105,19 @@ lpMainWin::lpMainWin(QWidget *parent) pHelptool->setPopupMode(QToolButton::InstantPopup); ui.mainToolBar->addWidget(pHelptool); ui.mainToolBar->addSeparator(); + m_pLabelInfo = new QLabel(this); m_pLabelInfo->setText(tr("本系统未注册激活")); m_pLabelInfo->setStyleSheet("font: bold 14px; color: red;"); - ui.mainToolBar->addWidget(m_pLabelInfo);; + ui.mainToolBar->addWidget(m_pLabelInfo); } - { + {//状态栏初始化配置 m_pLbCurrentTime = new QLabel(tr("系统时间")); m_pLbBanci = new QLabel(tr("班次信息")); m_pLbDetectState = new QLabel(tr("检测状态")); - m_pLbUser = new QLabel(tr("用户:")); + m_pLbUser = new QLabel(tr("用户:")); + m_pLbPLCConnect = new QLabel(tr("PLC连接")); QFont m_font; m_font.setBold(true); @@ -135,13 +136,15 @@ lpMainWin::lpMainWin(QWidget *parent) m_pLbDetectState->setFont(m_font); m_pLbDetectState->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - //m_pLbOnLine = new class QLabel("模式:"); - //m_pLbOnLine->setMinimumWidth(c_nWidth); + m_pLbPLCConnect->setMinimumWidth(200); + m_pLbPLCConnect->setFont(m_font); + m_pLbPLCConnect->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_pLbUser->setFont(m_font); m_pLbUser->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); ui.statusBar->addWidget(m_pLbDetectState, 1); + ui.statusBar->addWidget(m_pLbPLCConnect, 1); ui.statusBar->addWidget(m_pLbUser, 1); ui.statusBar->addWidget(m_pLbBanci,1); ui.statusBar->addPermanentWidget(m_pLbCurrentTime); @@ -149,15 +152,15 @@ lpMainWin::lpMainWin(QWidget *parent) //加载用户管理模块 loadUserModel(); //初始化模型管理模块 - { + {//总逻辑处理模块 核心管理 m_pCtrl = new WheelCtrl(QCoreApplication::applicationDirPath(), &m_screen); - pWorkCtrl = new QWorkMgrCtlr(m_pCtrl); + pWorkCtrl = new QWorkMgrCtlr(m_pCtrl);//工单管理模块 pWorkCtrl->readManageFile(); - m_pworkUI = new QWorkMgrUI(pWorkCtrl, m_pCtrl); + m_pworkUI = new QWorkMgrUI(pWorkCtrl, m_pCtrl);//工单管理UI模块 m_pworkUI->InitUI(); connect(m_pworkUI, SIGNAL(sgUpdatedefect()), this, SLOT(onUpdateDefect())); - m_pModelMgrDlg = new QModelMgrDlg(m_pCtrl);//模板管理 + m_pModelMgrDlg = new QModelMgrDlg(m_pCtrl);//模板管理UI //当某个模板加入训练或者不加入训练时修改原来工作单中的模板信息 connect(m_pModelMgrDlg, SIGNAL(sgModifyModel(QString)), this, SLOT(modWorkMgr(QString))); connect(m_pModelMgrDlg, SIGNAL(sgUpdatedefect()), this, SLOT(onUpdateDefect())); @@ -174,11 +177,12 @@ lpMainWin::lpMainWin(QWidget *parent) connect(m_pSystemSettingDlg, SIGNAL(sgChangeLanguage(QString)), this, SLOT(onLanguageChange(QString))); connect(m_pSystemSettingDlg, SIGNAL(sgChangePLCParam()), this, SLOT(onChangePLCParam())); connect(m_pSystemSettingDlg, SIGNAL(sgParamChange()), this, SLOT(onUpdateUI())); + //历史检测图像缩略图 m_pixMapList = new QPixmapListBar(ui.tp_main_tabWidget); ui.tp_main_tabWidget->insertTab(0, m_pixMapList, tr("历史")); ui.tp_main_tabWidget->setCurrentIndex(0); - m_pAlgParamDlg = new QAlgParamDlg(); + m_pAlgParamDlg = new QAlgParamDlg();//算法参数设置页面 connect(m_pAlgParamDlg, SIGNAL(sgParamChange()), this, SLOT(onUpdateUI())); } { @@ -191,9 +195,7 @@ lpMainWin::lpMainWin(QWidget *parent) SendTiskTsk = new QMyThread(); TaskFunc TickFunc = std::bind(&lpMainWin::SendTickTskFun, this); SendTiskTsk->loadfunc(TickFunc); - m_screen.ShowMsg(tr("系统初始化完成...")); - } { onSetModel(); @@ -216,8 +218,6 @@ lpMainWin::lpMainWin(QWidget *parent) connect(m_pNet, SIGNAL(sgLibRev(bool)), SendModelLibTask, SLOT(WaitSingleIn(bool)));//xy lib // connect(m_pNet, SIGNAL(sgChangeOnlineState(int)), m_pUi, SLOT(onSwitchOnlineModel(int)));//强制在线 离线 - - QTimer::singleShot(500, m_pNet, SLOT(onOpenServer()));//延迟2s打开网络TCP服务 } { connect(&m_PulseTimer, SIGNAL(timeout()), this, SLOT(onPulseTimer()));//心跳包 @@ -239,25 +239,7 @@ lpMainWin::lpMainWin(QWidget *parent) connect(this, SIGNAL(sgShowChannelRes(QString)), this, SLOT(onShowChannel(QString))); } { - /*启动之后就一直发送心跳包和厚度查询*/ - if (DetectState::instance()->m_AutoSendTick2Net) - { - SendTiskTsk->setSleepTime(1000); - SendTiskTsk->start(); - } - - //if (DetectState::instance()->m_StartAndDetect == 1)//m_sysType 表示万丰科技的 - { - QTimer::singleShot(3000, [&](){ - ui.btn_start_detect->setText(tr("停止检测")); - DetectState::instance()->IsDetect = true; - m_pCtrl->onStart(); - }); - } - if (DetectState::instance()->m_AutoSendTick2COM) - m_wfPulseTimer.start(1000); - - + //???做什么用的 pTickThread = new QThread(this); QNetTickThread *pNetTick = new QNetTickThread; pNetTick->setNetPtr(m_pNet); @@ -277,21 +259,40 @@ lpMainWin::lpMainWin(QWidget *parent) m_pTableCheck->setModelList(strList); } - m_timerID = startTimer(1000); //m_PulseTimer.start(1000); - connect(this, SIGNAL(sgAutoExposure()), this, SLOT(onAutoExposure())); connect(this, SIGNAL(sgShowRatioVal(double)), this, SLOT(onShowRatioVal(double))); + //自动曝光参数 QString strPath = QApplication::applicationDirPath(); readExposureTimeConfig(strPath); - onUpdateUI(); + //注册码相关 lpGlobalData::instance()->m_bCheckLinese = lpCheckKey::instance()->checkLinese(); m_pCheckLineseUI = new QCryptokeyUI(); connect(m_pCheckLineseUI, SIGNAL(sgRegisterFinish(bool)), this, SLOT(onLineseCheck(bool))); - onLineseCheck(lpGlobalData::instance()->m_bCheckLinese); + + + /*启动之后就一直发送心跳包和厚度查询*/ + if (DetectState::instance()->m_AutoSendTick2Net) + { + SendTiskTsk->setSleepTime(1000); + SendTiskTsk->start(); + } + //if (DetectState::instance()->m_StartAndDetect == 1)//m_sysType 表示万丰科技的 + { + QTimer::singleShot(3000, [&]() { + ui.btn_start_detect->setText(tr("停止检测")); + DetectState::instance()->IsDetect = true; + m_pCtrl->onStart(); + }); + } + + if (DetectState::instance()->m_AutoSendTick2COM) + m_wfPulseTimer.start(1000); + m_timerID = startTimer(1000); + QTimer::singleShot(1000, m_pNet, SLOT(onOpenServer()));//延迟2s打开网络TCP服务 } lpMainWin::~lpMainWin() @@ -361,6 +362,11 @@ lpMainWin::~lpMainWin() delete m_pLbUser; m_pLbUser = nullptr; } + if (m_pLbPLCConnect) + { + delete m_pLbPLCConnect; + m_pLbPLCConnect = nullptr; + } } if (m_pCtrl) { @@ -430,7 +436,7 @@ lpMainWin::~lpMainWin() } } - +//核心corctrl模块 包括相机算法等相关模块 bool lpMainWin::onInitCoreCtrl() { //load coretrl @@ -473,7 +479,7 @@ void lpMainWin::loadUserModel() connect(m_pUserCtrl, SIGNAL(sgCurrentUserInfo(QString, int, int)), this, SLOT(onLogInOut(QString, int, int))); } } - +/*****************************系统语言设置*****************************/ void lpMainWin::SearchQmFile(const QString & strDir) { QDir dir(strDir); @@ -496,12 +502,10 @@ void lpMainWin::SearchQmFile(const QString & strDir) QString tt = fileInfo.fileName(); // 如果是文件夹 bool bisDir = fileInfo.isDir(); - if (bisDir) - { + if (bisDir) { SearchQmFile(fileInfo.filePath()); } - else - { + else { bool bQm = fileInfo.fileName().endsWith(".qm"); SetTranslator(fileInfo.filePath()); } @@ -511,18 +515,16 @@ void lpMainWin::SearchQmFile(const QString & strDir) void lpMainWin::SetTranslator(const QString strPath) { - if (strPath.isEmpty()) - { + if (strPath.isEmpty()) { return; } QTranslator *pTrans = new QTranslator; - if (pTrans->load(strPath)) // 如果加载成功 - { + // 如果加载成功 + if (pTrans->load(strPath)) { qApp->installTranslator(pTrans); m_VecTranPtr.append(pTrans); } - else - { + else { delete pTrans; pTrans = NULL; } @@ -532,10 +534,8 @@ void lpMainWin::SetLanguage(QString strLangage) { QString strDirPath = QString(QCoreApplication::applicationDirPath() + "/language/"); QString translatorFileName = strLangage; - if (!translatorFileName.isEmpty()) - { - if (m_VecTranPtr.size() > 0) - { + if (!translatorFileName.isEmpty()) { + if (m_VecTranPtr.size() > 0) { while (m_VecTranPtr.size()) { QTranslator *pVa = m_VecTranPtr.takeFirst(); @@ -544,14 +544,13 @@ void lpMainWin::SetLanguage(QString strLangage) pVa = NULL; } } - //if (strLangage == "Chinese") - // return; QLocale::setDefault(QLocale(translatorFileName)); QString transDir = strDirPath + translatorFileName; SearchQmFile(transDir); } } +/*****************************系统语言设置 END*****************************/ /*主线程接收图像*/ void lpMainWin::INewCameraImage(const QString& camKey, QImage img) { @@ -779,7 +778,7 @@ Q_SLOT void lpMainWin::onLogInOut(QString strName, int level, int state) m_pModelMgrDlg->onUserLevel(level); } } - +/*菜单栏所有事件*/ Q_SLOT void lpMainWin::onActionClicked() { QString strObj = sender()->objectName(); @@ -860,8 +859,8 @@ Q_SLOT void lpMainWin::onActionClicked() m_pDebugDlg->setWindowTitle(tr("调试工具")); m_pDebugDlg->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); m_pDebugDlg->setWindowIcon(QIcon(":/image/leaper")); - m_pDebugDlg->setWindowModality(Qt::ApplicationModal); - m_pDebugDlg->setAttribute(Qt::WA_ShowModal, true); + //m_pDebugDlg->setWindowModality(Qt::ApplicationModal); + //m_pDebugDlg->setAttribute(Qt::WA_ShowModal, true); m_pDebugDlg->show(); } } @@ -869,7 +868,7 @@ Q_SLOT void lpMainWin::onActionClicked() if (m_pworkUI) { m_pworkUI->setParent(this); - m_pworkUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); + m_pworkUI->setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); m_pworkUI->setWindowIcon(QIcon(":/image/leaper")); m_pworkUI->setWindowModality(Qt::ApplicationModal); m_pworkUI->setAttribute(Qt::WA_ShowModal, true); @@ -884,8 +883,8 @@ Q_SLOT void lpMainWin::onActionClicked() m_pAlgParamDlg->setWindowTitle(tr("算法参数")); m_pAlgParamDlg->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); m_pAlgParamDlg->setWindowIcon(QIcon(":/image/leaper")); - m_pAlgParamDlg->setWindowModality(Qt::ApplicationModal); - m_pAlgParamDlg->setAttribute(Qt::WA_ShowModal, true); + //m_pAlgParamDlg->setWindowModality(Qt::ApplicationModal); + //m_pAlgParamDlg->setAttribute(Qt::WA_ShowModal, true); m_pAlgParamDlg->show(); } } @@ -904,7 +903,7 @@ Q_SLOT void lpMainWin::onActionClicked() { m_pModelMgrDlg->setParent(this); m_pModelMgrDlg->setWindowTitle(tr("模板管理")); - m_pModelMgrDlg->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); + m_pModelMgrDlg->setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); m_pModelMgrDlg->setWindowIcon(QIcon(":/image/leaper")); m_pModelMgrDlg->setWindowModality(Qt::ApplicationModal); m_pModelMgrDlg->setAttribute(Qt::WA_ShowModal, true); @@ -939,16 +938,16 @@ Q_SLOT void lpMainWin::onActionClicked() } } else if ("action_register" == strObj) { - if (m_pCheckLineseUI) { - m_pCheckLineseUI->setInfo(lpCheckKey::instance()->getSerialNo(), lpGlobalData::instance()->m_bCheckLinese); - m_pCheckLineseUI->setParent(this); - m_pCheckLineseUI->setWindowTitle(tr("注册")); - m_pCheckLineseUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); - m_pCheckLineseUI->setWindowIcon(QIcon(":/image/leaper")); - m_pCheckLineseUI->setWindowModality(Qt::ApplicationModal); - m_pCheckLineseUI->setAttribute(Qt::WA_ShowModal, true); - m_pCheckLineseUI->show(); - } + if (m_pCheckLineseUI) { + m_pCheckLineseUI->setInfo(lpCheckKey::instance()->getSerialNo(), lpGlobalData::instance()->m_bCheckLinese); + m_pCheckLineseUI->setParent(this); + m_pCheckLineseUI->setWindowTitle(tr("注册")); + m_pCheckLineseUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); + m_pCheckLineseUI->setWindowIcon(QIcon(":/image/leaper")); + m_pCheckLineseUI->setWindowModality(Qt::ApplicationModal); + m_pCheckLineseUI->setAttribute(Qt::WA_ShowModal, true); + m_pCheckLineseUI->show(); + } } } @@ -1015,7 +1014,9 @@ QString lpMainWin::SecondTimeString(quint64 value) void lpMainWin::timerEvent(QTimerEvent *event) { - if (event->timerId() == m_timerID) { + if (event->timerId() == m_timerID) + { + //定时刷新系统信息 m_runTimeCount++; if (m_pLbCurrentTime) { @@ -1024,17 +1025,17 @@ void lpMainWin::timerEvent(QTimerEvent *event) QString strTimeTitle = tr("运行时长:"); QString strShow = QString("%1 %2 %3").arg(m_currentTime).arg(strTimeTitle).arg(strlong); m_pLbCurrentTime->setText(strShow); - m_pLbCurrentTime->setStyleSheet("font: 14px;"); + m_pLbCurrentTime->setStyleSheet("font: 18px;"); } // state if (m_pLbDetectState) { - QString strDetectState = tr("检测状态:") + (DetectState::instance()->IsDetect == true ? tr("检测中...") : tr("未检测...")); + QString strDetectState = DetectState::instance()->IsDetect == true ? tr("检测中...") : tr("未检测..."); m_pLbDetectState->setText(strDetectState); if (DetectState::instance()->IsDetect) { - m_pLbDetectState->setStyleSheet("font: bold 14px;background-color: green;"); + m_pLbDetectState->setStyleSheet("font: bold 18px;background-color: green;"); } else { - m_pLbDetectState->setStyleSheet("font: bold 14px;background-color: red;"); + m_pLbDetectState->setStyleSheet("font: bold 18px;background-color: red;"); } } @@ -1043,22 +1044,34 @@ void lpMainWin::timerEvent(QTimerEvent *event) if (m_pCtrl) show_label = m_pCtrl->getCurrentBan(); - QString strMsg = tr("班次信息:") + (show_label.isEmpty() == true ? tr("该时间段未设置班次") : show_label); + QString strMsg = tr("班次信息:") + (show_label.isEmpty() == true ? tr("该时间段未设置班次") : show_label); // if (strLanguage != "Chinese") // { // strMsg = tr("Classes:") // + (show_label.isEmpty() == true ? tr("No set Times") : show_label); // } m_pLbBanci->setText(strMsg); - m_pLbBanci->setStyleSheet("font: 14px;"); + m_pLbBanci->setStyleSheet("font: 18px;"); } if (m_pLbUser) { QString show_label = m_pCtrl->getUserName(); // if (strLanguage != "Chinese") // m_pLbUser->setText(tr("User:") + show_label); // else - m_pLbUser->setText(tr("当前用户:") + show_label); - m_pLbUser->setStyleSheet("font: 14px;"); + m_pLbUser->setText(tr("当前用户:") + show_label); + m_pLbUser->setStyleSheet("font: 18px;"); + } + if (m_pLbPLCConnect) + { + if (lpGlobalData::instance()->m_plcConnect == true) + { + m_pLbPLCConnect->setText(tr("PLC已连接")); + m_pLbPLCConnect->setStyleSheet("font: bold 18px;background-color: green;"); + } + else { + m_pLbPLCConnect->setText(tr("PLC未连接")); + m_pLbPLCConnect->setStyleSheet("font: bold 18px;background-color: red;"); + } } } } @@ -1076,9 +1089,25 @@ void lpMainWin::closeEvent(QCloseEvent *event) { return event->ignore(); } + if (m_pDebugDlg) + { + if (!m_pDebugDlg->isHidden()) + { + m_pDebugDlg->close(); + } + } + return event->accept(); } +void lpMainWin::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + { + ui.retranslateUi(this); + } +} + void lpMainWin::SendModelKuTskFun() { /* @@ -1120,7 +1149,6 @@ void lpMainWin::SendModelKuTskFun() } emit(sgShowMsgdlg(tr("模板库发送完成"))); - } void lpMainWin::SendTickTskFun() @@ -1287,7 +1315,8 @@ Q_SLOT void lpMainWin::onReadDetectState(int nIndex, QString strModel) QMap *ptr = m_pCtrl->getAllModelMapPtr(); if (ptr) { QList lst = ptr->keys(); - /*if (nIndex < lst.size() && nIndex >= 0)*/ { + /*if (nIndex < lst.size() && nIndex >= 0)*/ + { IWheelModel*pModel = ptr->value(strModel); if (pModel) { pModel->setDetectState(1); @@ -1325,7 +1354,6 @@ Q_SLOT void lpMainWin::onTrigRecv(int m_value,double dRatio) // { // m_pCoreCtrl->ISetExposureTime(m_camKey, m_exposureTimeArray[m_exposureTimeCount]); // } - onTriggerCam(); qWarning() << "soft ctrol camera :" << "(" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz") << ")"; } @@ -1848,7 +1876,6 @@ Q_SLOT void lpMainWin::onLineseCheck(bool bFlag) ui.action_modelmgr->setDisabled(!bFlag); ui.action_checkdata->setDisabled(!bFlag); ui.action_connect_mode->setDisabled(!bFlag); - ui.action_connect_mode->setDisabled(!bFlag); ui.action_debug->setDisabled(!bFlag); ui.action_algParam->setDisabled(!bFlag); ui.actioncamSetting->setDisabled(!bFlag); diff --git a/tpvs17/tpMain/lpMainWin.h b/tpvs17/tpMain/lpMainWin.h index 39f4cbc..5c300ea 100644 --- a/tpvs17/tpMain/lpMainWin.h +++ b/tpvs17/tpMain/lpMainWin.h @@ -137,7 +137,7 @@ private: protected: virtual void timerEvent(QTimerEvent *event); virtual void closeEvent(QCloseEvent *event); - + virtual void changeEvent(QEvent *event); private: Ui::lpMainWin ui; @@ -152,7 +152,8 @@ private: class QLabel* m_pLbCurrentTime{ nullptr };//显示系统时间 class QLabel* m_pLbBanci{ nullptr };//显示班次 class QLabel* m_pLbDetectState{ nullptr };//显示检测状态 - class QLabel *m_pLbUser{ nullptr };//显示登陆用户信息 + class QLabel* m_pLbUser{ nullptr };//显示登陆用户信息 + class QLabel* m_pLbPLCConnect{ nullptr };//PLC连接状态 private: CDllCoreCtrl* m_pDllCoreCtrl{ nullptr }; ICoreCtrl* m_pCoreCtrl{ nullptr }; diff --git a/tpvs17/tpMain/lpmain_en.ts b/tpvs17/tpMain/lpmain_en.ts index 2a15cf7..931c671 100644 --- a/tpvs17/tpMain/lpmain_en.ts +++ b/tpvs17/tpMain/lpmain_en.ts @@ -17,10 +17,10 @@ CWheelNet - + IP参数设置 - IP Config - IP Config + IP Setting + IP Setting @@ -116,8 +116,8 @@ 轮毂型号 - Name: - Name: + Name + Name @@ -129,20 +129,18 @@ 直径(mm) - Diameter(mm): - Diameter(mm): + Diameter 厚度(mm) - Thickness(mm): - Thickness(mm): + Thickness + Thickness 旋转次数 - Rotations: - Rotations: + Rotate @@ -194,7 +192,7 @@ 起始时间 - Start: + Start @@ -210,7 +208,7 @@ 结束时间 - End : + End @@ -225,6 +223,114 @@ Text day + + QAlgParamDlg + + + 算法参数设置 + Algo Setting + + + + 二级圆定位: + Circle Param: + + + + 边缘宽度: + Edge Width: + + + + 从深到浅 + Dark to Write + + + + 从浅到深 + Write to Dark + + + + 边缘对比度: + AC Thres: + + + + 边缘转换: + Polarity: + + + + 圆半径大小过滤: + Circle Filter Size: + + + + 检测背景图更换: + Background Image: + + + + 查看检测背景 + Check Background + + + + 是否使用图像增强 + Use Image Enhancement + + + + 是否使用背景图找圆算法 + Use Background Algo + + + + 型号匹配: + Model Match: + + + + 是否使用偏距过滤模板 + Use Offset to Filter Model + + + + 应用 + Apply + + + + 退出 + Close + + + + 参数已生效!!! + Apply Success!!! + + + + 请选择您的背景图 + Please select your background map + + + + 提示 + Info + + + + 背景图更新完成,请重启本软件. + Background image updated, please restart this software. + + + + 确认 + OK + + QCamSettingDlg @@ -235,7 +341,7 @@ 序列号: - Serial Number: + Serial: @@ -245,12 +351,12 @@ 相机类型: - Camera Type: + Type: 虚拟相机 - Virtual Camera + Virtual @@ -275,7 +381,7 @@ 图像高度: - Image Height: + Height: @@ -290,7 +396,7 @@ 图像宽度: - Image Width: + Width: @@ -302,7 +408,7 @@ 图像格式: - Image Format + Format: @@ -317,17 +423,17 @@ 内触发 - Internal trigger + Internal 外触发 - External trigger + External 软触发 - Soft trigger + Soft @@ -498,6 +604,72 @@ Channel management + + QCryptokeyUI + + + 注册 + Register + + + + 退出 + Close + + + + 机器码: + MachineID: + + + + 注册码: + License: + + + + 激活 + Active + + + + + 请输入注册码 + Please input Licese + + + + 激活状态: + State: + + + + 未激活 + No Active + + + + + + 提示 + Info + + + + 注册码不匹配,请重新输入 + No Match,Please Input the New One + + + + 已激活 + Active + + + + 系统激活完成 + the System Active Finish + + QDebugDlg @@ -542,19 +714,19 @@ p, li { white-space: pre-wrap; } 直径mm: - diameter(mm): + Diameter(mm): 开始模拟检测 - Start simulation test + Continus 采集一张 - Collect one + Signal @@ -669,7 +841,7 @@ p, li { white-space: pre-wrap; } 确认修改 - Cancel + Apply @@ -680,7 +852,7 @@ p, li { white-space: pre-wrap; } 缩略图: - Thumbnail: + Image: @@ -727,146 +899,156 @@ p, li { white-space: pre-wrap; } QModelMgrDlg - + 轮毂信息: - Wheel information: + Model Info: - + 型号 - Model + Name - + 0% 0% - + 阈值调节 Threshold - + 严格 Strict - + 旋转次数 - Rotations + Rotate - + 缩略图 Thumbnail - + 宽松 Easy - + 厚度(mm) Thickness(mm) - + 直径(mm) Diameter(mm) - + 加入训练 Add to train - + + 最小偏距 + Min Offset + + + + 最大偏距 + Max Offset + + + 基本操作 Basic operation - - + + 删除模板 Delete - + 训练当前模板 Training - + 训练模板 Train - + 添加新的模板 Add new - + 新建模板 New - + 训练所有模板,消耗时间会较长 Training all templates will take longer - + 训练全部 Train all - + 确认修改,每次修改模板的参数后都要确认修改才有效 Confirm the modification, every time you modify the parameters of the template, you must confirm the modification to be effective - + 修改确认 - Confirm + Modify - + 修改型号名 - Modify name + Modify Name - + 图片显示: - Image display: + Images: TextLabel TextLabel - - + + 添加已裁剪的轮毂图片 Add cropped wheel image - + 追加 Add - - + + 删除所有模板 - Delete all + Del All 模板型号查询 - Template + Models @@ -879,296 +1061,297 @@ p, li { white-space: pre-wrap; } Quantity - + modelID modelID - - - - - + + + + - - - - - - - + + + + + + + + 提示 Prompt - - + + 请选择一个您要追加图像的型号! Please select a model you want to add an image to! - + 加载图像 Load image - + 图像加载中,请稍后..... The image is loading, please wait... - + 添加失败,不能添加带检测背景的图片作为模板!!! Failed to add, you cannot add a picture with a detection background as a template! ! ! - + 加载完成 Download finished - - - + + + 请选择一个您要修改的型号! Please select a model you want to modify! - + 修改了模板 Modified template - + 的参数 The parameters of the - + 修改成功! - Successfully modified! + Modified Successfully! - + 请选择一个您要删除的型号 Please select a model you want to delete - + 按下了删除模板按钮 Press the Delete Template button - + 是否删除型号 Whether to delete the model - + 产品模板 Product template - + 删除了模板 Template deleted - - - - - - - - + + + + + + + + 共 - common + with - - - - - + + + + + 个型号 - Model number + Models + number - + 按下了添加模板按钮 Press the Add Template button - + 产品信息设置 Product information settings - + 添加了一个新的模型 Added a new model - + 请选择一个您要训练的型号! Please select a model you want to train! - - + + 训练模板线程未退出,请稍等 The training template thread did not exit, please wait - + 将对所有型号模板进行重新训练,期间系统的检测功能将不能正常运行直到模板训练完成,全部重新训练模板将需要很长时间,期间将不能进行其他工作,是否继续执行? All model templates will be retrained. During this period, the system's detection function will not operate normally until the template training is completed. It will take a long time for all templates to be retrained, during which other work will not be possible. Do you want to continue? - + 确定删除该图像? Determine to delete the image? - + 模板图片删除 Template picture deletion - - - + + + 个图像 - Image + Images - + 警告 Warning - + 即将删除模板库里的所有模板,是否继续? All templates in the template library will be deleted. Do you want to continue? - + 再次确认,是否全部删除? Confirm again, delete all? - + 没有模板!!! - No template!!! + No Model!!! - + 全部删除完成!!! Complete deletion!!! - + 图像数量少于 The number of images is less than - + 个,请及时补充训练样本 - , please add training samples in time + please supplement Images - - - - - - + + + + + + 模板更新进度 Template update progress - + 正在初始化所有模板 共需要训练%1个模板,请稍后..... All templates are being initialized. A total of%1 templates need to be trained. Please wait a moment... - + 正在训练%1的模板 已完成%2/%3,请稍后..... The template training %1 is complete %2/%3, please wait... - + %1的模板获取特征 已完成%2/%3,请稍后..... Template capture feature for %1 is complete for %2/%3, please wait... - + %1的模板训练完成 已完成%2/%3,请稍后..... Template training for %1 completed %2/%3, please wait... - + 全部模板更新完成!%1s All templates updated!The %1 s - + 对全部模板进行了重新训练,共%1个模板 All templates were retrained, with a total of%1 template - + 模板正在准备请稍后..... - The template is being prepared Please wait a moment..... - - - - - - - - - - - - - - + The Model is being prepared Please wait a moment..... + + + + + + + + + + + + + + 模板训练进度 - Template training progress + Training progress - - + + %1型号没有图片不能训练! - %1 Model can not be trained without pictures! + %1 can not be trained without images! - + %1的模板 正在获取特征值,请稍后.... - The%1 template is getting the characteristic value. Please wait... + The %1 is getting the feater value. Please wait... - + 训练完成!%1s Training completed! %1s - + 训练了模板:%1 Model training:%1 - + 确认 OK - + 取消 Cancel @@ -1186,12 +1369,12 @@ p, li { white-space: pre-wrap; } 虚拟相机触发 - Virtual camera trigger + Virtual Camera 硬件相机触发 - Hardware camera trigger + Hardware Camera @@ -1216,12 +1399,32 @@ p, li { white-space: pre-wrap; } 下降沿触发 - Falling edge trigger + Falling 上升沿触发 - Rising edge trigger + Rising + + + + 警告 + Warning + + + + 本检测系统正在运行,您真的要关闭? + Are you sure quit the System? + + + + 确定 + OK + + + + 取消 + NO @@ -1269,19 +1472,19 @@ p, li { white-space: pre-wrap; } - + 检测图像设置 Image Settings - + PLC相关设置 PLC Settings - + 报警灯测试 Alarm Test @@ -1301,362 +1504,358 @@ p, li { white-space: pre-wrap; } Value - + 语言 Language - 检测背景更换 - Background + Background - - + + 抠图后 After cutout - - + + 原图 SourceImage - 背景图 - Background + Background - + 检测结果 Result - + 图像保存路径 Image Save Path - - + + 设置保存路径 Save path - - + + 打开图像路径 Open Image Path - + 保存当前设置 Save current settings - - + + 保存已匹配图 Save matched Image - - + + 保存无匹配图 Save Unmatched Image - 使用背景图 - Use background + Use background - + 轮毂全去A通道 Hub All-to-A Channel - 查看检测背景 - Check Background + Check Background - + 保存参数 Save Parameters - - + + 保存设置 Save Settings - + 传感器触发滤波(ms) Sensor filtering (ms) - + 相机触发延时(ms) Sensor filtering (ms) - + 相机触发脉宽(ms) Camera width (ms) - + 光源熄灭延时时间(ms) Light delay time (ms) - + 传感器触发类型 Sensor trigger type - + 保持结果时长(ms) Result hold Times (ms) - + 连接超时次数 Connection timeouts - + 超时是否显示信息 Display information - - + + 是否自动重启服务器 Auto restart servering - + 是否保存超时日志 Save timeout log - + 发送并保存 Send and save - + 超时提醒n次后自动重启服务 Automatically restart service after n timeout reminders - + 是否显示提示 Display Warning - + 勾选后通信超时时会显示提醒信息 Reminder message will be displayed when communication timeout occurs after checking - + 勾选后通信超时次数达到后,系统将自动重启服务,PLC会自动重新连接 After checking the number of communication timeouts reached, the system will automatically restart the service, and the PLC will automatically reconnect - + 保存信息到系统日志 Save information to system log - + 勾选后表示超时信息将自动保存到系统日志中,便于查询 Check to indicate that the timeout information will be automatically saved to the system log for easy query - + 红灯 Red light - + 绿灯 Green light - + 黄灯 Yellow light - + 蜂鸣 Buzzing - + 红灯闪一下 Red light flashed - + 绿灯闪一下 Green light flashed - + 黄灯闪一下 Yellow light flashed - + 蜂鸣响一下 Bee rings - + 开发者使用 Developers use - + 相机模式 Camera mode - + 虚拟相机触发时间 Trigger times - + 系统模式 System mode - + 相机触发模式 Trigger mode - - + + 串口发送心跳包 Serial Port - - + + 网络发送心跳包 Network - - + + 串口发送通道结果 Serial Port - - + + 网络发送检测结果 Network - - + + 网络发送通道结果 Network - + 光栅使用标志 Rester - + 保存高度厚度数据 Data - + 通道分配 Channel allocate - + 启动时是否检测 Whether to detect at startup - + 显示厚度数据 Display thickness data - + 显示厚度采样数据 Display thickness sampling data - + 使用光栅获取厚度 Acquiring Thickness by Grating - + 保存数据用于测试 Save data for testing - + 是否使用通道分配 Whether to use channel allocation or not - + 是否启动就开始检测 Start checking if it's started - - + + 是否显示 Whether to display - + 保存 Save - + 请选择您的背景图 Please select your background map - + 提示 Info Warning - + 背景图更新完成,请重启本软件. Background image updated, please restart this software. - + 确认 OK - + 打开文件夹 Open folder @@ -1668,6 +1867,11 @@ p, li { white-space: pre-wrap; } 系统设置 System settings + + + 参数设置已生效!!! + Apply Successful!!! + QTimeMgrDlg @@ -1677,24 +1881,24 @@ p, li { white-space: pre-wrap; } Classes management - + 未选中 UnSelect - + 添加时间 Add - + 删除时间 Delete - + 修改时间 Modify @@ -1801,22 +2005,22 @@ p, li { white-space: pre-wrap; } Information setup - + 确定 Ok - + 取消 Cancel - + 备注信息: Note information: - + 名称: Name: @@ -1824,204 +2028,208 @@ p, li { white-space: pre-wrap; } QWorkMgrUI - QWorkMgrUI - QWorkMgrUI + QWorkMgrUI + + + + 检测配置任务表 + Model Check - + 工作任务表 Table List - + 添加任务单 Add Table - + 添加 Add - + 删除任务单 Delete Table List - + 删除 Del - + 修改任务单名称或备注信息 Modify Table List Name or Note Information - + 修改 Mod - + 使用任务单 Set Use - + 应用 Use - + 当前选择的任务表: Current Table: - - + + 数量 Num - + 添加型号到检测列表 Add model to table - + <<< <<< - + 从检测列表移除所选型号 Remove the selected model from the table - + >>> >>> - + 缩略图 Image - + 只看已选 Selected - + 只看未选 Unselected - + 显示全部 Show all - + 查找: Find: - + 其他 Others - + 按照直径检测 By diameter - + 按照厚度检测 By thickness - + 手动发送模板库 Send Models - + 检测模板管理 Detection Model Management - - + + 共 %1 个 Total of: %1 - + 当前使用的工单为 %1 The current Table is%1 - + 以下型号为重复添加: %1已被忽略. The models are added repeatedly:%1, And They have been ignored. - + 提醒 Warning - - - + + + 确定 OK - + 工单 %1 被设为应用 Table %1 is seted to Using - + 发送模板库 Send Template Library - - + + 警告 Warning - + %1任务单正在使用不能被删除,请先切换到其他任务单,再删除该任务单? %1 Table is Using and cannot be deleted. Please switch to another Table before deleting the Table? - - + + 取消 Cancel - + 是否要删除 %1 模型? Do you want to delete the%1 model? - + 序号 Num - + 内容 About @@ -2103,7 +2311,7 @@ p, li { white-space: pre-wrap; } 轮毂型号识别 - Wheel model identification + Model Detector Application @@ -2113,13 +2321,13 @@ p, li { white-space: pre-wrap; } 状态信息 - Status information + Status - + 开始检测 - Start testing + Start @@ -2127,461 +2335,525 @@ p, li { white-space: pre-wrap; } Results - + 无匹配(个) No match - + 已检测(个) Detected - + 匹配值 - Match value + Score - + 直径(mm) - Diameter (mm) + Diameter - + 时间(s) Time(s) - + 通道 Channel - - - - - - - + + + + + + + + 0 0 - + --------- --------- - + None None - - + + 检测状态 - Detection status + Detect State - + 厚度(mm) - Thickness(mm) + Thickness - + + 偏距 + Offset + + + 统计结果 - Statistical results + Static - + modelID_detect modelID_detect - + count count - + 交换班清零 - Exchange class reset + Clear - + 型号数量 - Model number + Number - - + + 模板管理 - Template management + Model Manager - + 数据查询 History - + 模板勾选 - Template selection + Model Check - + 辅助工具 - Auxiliary tools + Test Tool - + 班次设置 - Classes setting + Class Setting - + 光栅标定 - Raster calibration + Raster Setting - + IP设置 - IP settings + IP Setting - - + + 关于 About - + 登录 Login - + 用户管理 - User Management + User Manager - + 系统设置 - System settings + System Setting - - + + 相机配置 - Camera configuration + Cam Setting + + + + 算法设置 + Algo Setting + + + + + 注册产品 + Registerer - + 加载必要模块..... Load the necessary modules..... - - + + 工具 Tool - + + + 帮助 + Help + + + + + 本系统未注册激活 + The system is not activated + + + 系统时间 - System time + Time - + 班次信息 - Classes information + Class Info - 用户: - User: + User: - + 历史 History - + 系统初始化完成... System initialization complete... - + 显示识别结果 - Display recognition results + Display Result - + 相机图像和背景图不一样,请更换检测背景! The camera image is different from the background image, please change the detection background! - + 警告!!!连续出现%1个未识别型号 Warning!!! %1 unidentified models appear continuously - + ,未开启检测功能造成的 , Caused by not opening the detection function - + 获得图像,正在计算中... - Get the image, is calculating... + Calculating... - + 注 销 Logout - + 登 录 Login - - + + 该功能未启用. The feature is not enabled. - - - + + + 确认 Ok - + 你确定要注销 Are you sure you want to log out - + 班次管理 - Classes management + Classes Manager - + 调试工具 - DebugTool + Test Tool + + + + 算法参数 + Algo Setting - + 系统参数设置 - System parameter setting + System Setting - - + + 停止检测 - Stop detecting + Stop - + 按下了开始检测按钮,检测功能开启 Press the start detection button, the detection function is turned on - + 按下了停止检测按钮,检测功能关闭 Press the stop detection button, the detection function is closed - - - - + + + + 提示 - Prompt + Info - + 将清空所有数据 - All data will be cleared + Are you sure Clear the Static - + 确定 - Ok + OK - - + + 取消 - Cancel + NO + + + + 用户: + User: + + + + PLC连接 + PLC State - - - - + + + + 当前曝光时间未识别到轮毂! The current exposure time does not recognize the hub! - - + + 调整5次曝光时间后依然未能识别到轮毂! After adjusting the exposure time for 5 times, the wheel hub is still not recognized! - + + 注册 + Register + + + 按下了清零按钮,数据全部清零 Press the reset button, all data are cleared - + 天 - d + D - + 时 - h + H - + 分 - m + M - + 秒 - s + S - 系统时间: - System time: + System time: - + 运行时长: - Running time: + Time: - 检测状态: - Status: + Status: - + 检测中... Detecting... - + 未检测... - Not detected... + Not Detected... - 班次信息: - Classes info: + Classes info: - + 该时间段未设置班次 - No classes + No Classes - 当前用户: - Current user: + Current user: + + + + 班次信息: + Class: + + + + 当前用户: + User: - + + PLC已连接 + PLC Connect + + + + PLC未连接 + PLC Disconnect + + + 模板库发送完成 Template library sending completed - - + + 正在检测型号数 Number of models - + 已连接 Connected - + 已断开 Disconnected - + PLC已收到相关设置参数! The PLC has received the relevant setting parameters! - + 已打开 Opened - + 已关闭 Closed - + 轮毂型号识别系统 - Wheel Type Identification System + Wheel Model Identification System - + 本软件由杭州利珀科技开发,用于轮毂型号识别和分类,可搭配流水线运输系统使用 This software is developed by Leaper in Hangzhou. It is used for hub type identification and classification. It can be used with pipeline transportation system - + 若需要进一步了解该产品的相关信息,请访问我们的网站 For more information about this product, please visit our website - + 软件版本 Software Version - + 算法版本 - Algorithm version + Algorithm Version - + 最后更新时间 Last update time - + 版权 (c) 属 杭州利珀科技有限公司 所有 - Copyright(C) belongs to Hangzhou Lipper Technology Co., Ltd. + Copyright(C) belongs to Hangzhou Leaper Technology company - + 关闭 Shut down - + (默认) (Default) - + 默认通道 值1000 1000 (Default) diff --git a/tpvs17/tpMain/lpmain_zh.ts b/tpvs17/tpMain/lpmain_zh.ts index c3dff8b..b0b9c4c 100644 --- a/tpvs17/tpMain/lpmain_zh.ts +++ b/tpvs17/tpMain/lpmain_zh.ts @@ -6,20 +6,20 @@ 开始读取json文件数据... - + 数据读取完成... - + CWheelNet - + IP参数设置 - + @@ -28,12 +28,12 @@ 型号 - + 数量 - + @@ -41,7 +41,7 @@ 取消 - + @@ -49,42 +49,42 @@ 新建通道 - + 发送结果: - + 通道名称: - + 备注: - + 确认 - + 取消 - + 警告 - + 数据不能为空,请输入 - + @@ -92,59 +92,59 @@ 新建模板 - + 轮毂信息: - + 轮毂型号 - + 0 - + 直径(mm) - + 厚度(mm) - + 旋转次数 - + 确定 - + 取消 - + 提醒 - + 信息不能为空! - + @@ -152,55 +152,163 @@ 时间参数设置 - + 确认 - + 取消 - + 时间参数: - + 起始时间 - + 班次名称: - + hh:mm - + 结束时间 - + 当天 - + 隔天 - + + + + + QAlgParamDlg + + + 算法参数设置 + + + + + 二级圆定位: + + + + + 边缘宽度: + + + + + 从深到浅 + + + + + 从浅到深 + + + + + 边缘对比度: + + + + + 边缘转换: + + + + + 圆半径大小过滤: + + + + + 检测背景图更换: + + + + + 查看检测背景 + + + + + 是否使用图像增强 + + + + + 是否使用背景图找圆算法 + + + + + 型号匹配: + + + + + 是否使用偏距过滤模板 + + + + + 应用 + + + + + 退出 + + + + + 参数已生效!!! + + + + + 请选择您的背景图 + + + + + 提示 + + + + + 背景图更新完成,请重启本软件. + + + + + 确认 + @@ -208,123 +316,123 @@ 相机配置 - + 内触发 - + 外触发 - + 软触发 - + 打开 - + 触发 - + 显示名称: - + 相机类型: - + 虚拟相机 - + 海康相机 - + 堡盟相机 - + 序列号: - + set - + 路径: - + 设置 - + 增益: - + 图像宽度: - + 曝光: - + 图像高度: - + 图像格式: - + Gray8 - + RGB32 - + 关闭 - + @@ -332,72 +440,72 @@ 通道信息管理 - + 所有通道数据 - + 发送结果: - + 通道名称: - + 备注: - + 是否设为默认(NG流向的通道) - + 确认修改 - + 退出 - + 编号 - + 通道名 - + 备注 - + 发送结果 - + 是否为默认 - + 默认 - + @@ -405,68 +513,134 @@ QChannelMgrDlg - + 所有型号及图像 - + 型号: - + 通道: - + 查找: - + 隐藏 - + 修改 - + 0 - + 通道分配: - + 删除通道 - + 增加通道 - + 刷新 - + 通道管理 - + + + + + QCryptokeyUI + + + 注册 + + + + + 退出 + + + + + 机器码: + + + + + 注册码: + + + + + 激活 + + + + + + 请输入注册码 + + + + + 激活状态: + + + + + 未激活 + + + + + + + 提示 + + + + + 注册码不匹配,请重新输入 + + + + + 已激活 + + + + + 系统激活完成 + @@ -474,7 +648,7 @@ QDebugDlg - + @@ -483,50 +657,50 @@ p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">右侧是算法裁剪后的图像、匹配的型号、算法匹配的最小阈值、匹配模板对应的直径和厚度(新建模板时输入的)</p></body></html> - + 000000 - + 0.0 - + 厚度mm: - + 0 - + 直径mm: - + 开始模拟检测 - + 采集一张 - + 停止 - + @@ -534,47 +708,47 @@ p, li { white-space: pre-wrap; } 直径标定 - + K:表示斜率,B:基准点,直径=高度*K+B - + 确认修改 - + 退出 - + B: - + K: - + 提示 - + 修改完成,参数已生效! - + 确定 - + @@ -582,48 +756,48 @@ p, li { white-space: pre-wrap; } QIPConfigDlg - + 本机服务器IP地址设置 - + IP 地址(I): - + 关闭服务 - + 开放端口: - + 打开服务 - + 目标客户端IP地址设置 - + 源端口: - + 确定 - + @@ -631,59 +805,59 @@ p, li { white-space: pre-wrap; } 模板名修改 - + 确认修改 - + 取消 - + 缩略图: - + TextLabel - + 旧型号名: - + 新型号名: - + 提示 - + 新型号名不能为空! - + 型号库中已包含该型号,请重新设置型号名! - + 确认 - + @@ -691,449 +865,459 @@ p, li { white-space: pre-wrap; } QModelMgrDlg - + - + 轮毂信息: - + - + 型号 - + - + 0% - + - + 阈值调节 - + - + 严格 - + - + 旋转次数 - + - + 缩略图 - + - + 宽松 - + - + 厚度(mm) - + - + 直径(mm) - + - + 加入训练 - + - + + 最小偏距 + + + + + 最大偏距 + + + + 基本操作 - + - - + + 删除模板 - + - + 训练当前模板 - + - + 训练模板 - + - + 添加新的模板 - + - + 新建模板 - + - + 训练所有模板,消耗时间会较长 - + - + 训练全部 - + - + 确认修改,每次修改模板的参数后都要确认修改才有效 - + - + 修改确认 - + - + 修改型号名 - + - + 图片显示: - + - - + + 添加已裁剪的轮毂图片 - + - + 追加 - + - - + + 删除所有模板 - + 模板型号查询 - + 查找: - + 数量 - + - + modelID - + - - - - - + + + + - - - - - - - + + + + + + + + 提示 - + - - + + 请选择一个您要追加图像的型号! - + - + 加载图像 - + - + 图像加载中,请稍后..... - + - + 添加失败,不能添加带检测背景的图片作为模板!!! - + - + 加载完成 - + - - - + + + 请选择一个您要修改的型号! - + - + 修改了模板 - + - + 的参数 - + - + 修改成功! - + - + 请选择一个您要删除的型号 - + - + 按下了删除模板按钮 - + - + 是否删除型号 - + - + 产品模板 - + - + 删除了模板 - + - - - - - - - - + + + + + + + + 共 - + - - - - - + + + + + 个型号 - + - + 按下了添加模板按钮 - + - + 产品信息设置 - + - + 添加了一个新的模型 - + - + 请选择一个您要训练的型号! - + - - + + 训练模板线程未退出,请稍等 - + - + 将对所有型号模板进行重新训练,期间系统的检测功能将不能正常运行直到模板训练完成,全部重新训练模板将需要很长时间,期间将不能进行其他工作,是否继续执行? - + - + 确定删除该图像? - + - + 模板图片删除 - + - - - + + + 个图像 - + - + 警告 - + - + 即将删除模板库里的所有模板,是否继续? - + - + 再次确认,是否全部删除? - + - + 没有模板!!! - + - + 全部删除完成!!! - + - + 图像数量少于 - + - + 个,请及时补充训练样本 - + - - - - - - + + + + + + 模板更新进度 - + - + 正在初始化所有模板 共需要训练%1个模板,请稍后..... - + - + 正在训练%1的模板 已完成%2/%3,请稍后..... - + - + %1的模板获取特征 已完成%2/%3,请稍后..... - + - + %1的模板训练完成 已完成%2/%3,请稍后..... - + - + 全部模板更新完成!%1s - + - + 对全部模板进行了重新训练,共%1个模板 - + - + 模板正在准备请稍后..... - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + 模板训练进度 - + - - + + %1型号没有图片不能训练! - + - + %1的模板 正在获取特征值,请稍后.... - + - + 训练完成!%1s - + - + 训练了模板:%1 - + - + 确认 - + - + 取消 - + @@ -1141,7 +1325,7 @@ p, li { white-space: pre-wrap; } 程序正在启动... - + @@ -1149,42 +1333,62 @@ p, li { white-space: pre-wrap; } 虚拟相机触发 - + 硬件相机触发 - + 调试免登陆 - + 正常工作模式 - + 传感器触发 - + 软件触发 - + 下降沿触发 - + 上升沿触发 - + + + + + 警告 + + + + + 本检测系统正在运行,您真的要关闭? + + + + + 确定 + + + + + 取消 + @@ -1192,7 +1396,7 @@ p, li { white-space: pre-wrap; } QSettingDlg - + @@ -1200,27 +1404,27 @@ p, li { white-space: pre-wrap; } 检测背景图像显示 - + 退出 - + 我要更换背景 - + pic - + 没有用于检测的背景图,请更换检测背景 - + @@ -1228,399 +1432,379 @@ p, li { white-space: pre-wrap; } 相关设备配置 - + - + 检测图像设置 - + - + PLC相关设置 - + - + 报警灯测试 - + 高级功能 - + 属性 - + 值 - + - + 语言 - + - - 检测背景更换 - - - - - + + 抠图后 - + - - + + 原图 - - - - - 背景图 - + - + 检测结果 - + - + 图像保存路径 - + - - + + 设置保存路径 - + - - + + 打开图像路径 - + - + 保存当前设置 - + - - + + 保存已匹配图 - + - - + + 保存无匹配图 - - - - - 使用背景图 - + - + 轮毂全去A通道 - + - - 查看检测背景 - - - - + 保存参数 - + - - + + 保存设置 - + - + 传感器触发滤波(ms) - + - + 相机触发延时(ms) - + - + 相机触发脉宽(ms) - + - + 光源熄灭延时时间(ms) - + - + 传感器触发类型 - + - + 保持结果时长(ms) - + - + 连接超时次数 - + - + 超时是否显示信息 - + - - + + 是否自动重启服务器 - + - + 是否保存超时日志 - + - + 发送并保存 - + - + 超时提醒n次后自动重启服务 - + - + 是否显示提示 - + - + 勾选后通信超时时会显示提醒信息 - + - + 勾选后通信超时次数达到后,系统将自动重启服务,PLC会自动重新连接 - + - + 保存信息到系统日志 - + - + 勾选后表示超时信息将自动保存到系统日志中,便于查询 - + - + 红灯 - + - + 绿灯 - + - + 黄灯 - + - + 蜂鸣 - + - + 红灯闪一下 - + - + 绿灯闪一下 - + - + 黄灯闪一下 - + - + 蜂鸣响一下 - + - + 开发者使用 - + - + 相机模式 - + - + 虚拟相机触发时间 - + - + 系统模式 - + - + 相机触发模式 - + - - + + 串口发送心跳包 - + - - + + 网络发送心跳包 - + - - + + 串口发送通道结果 - + - - + + 网络发送检测结果 - + - - + + 网络发送通道结果 - + - + 光栅使用标志 - + - + 保存高度厚度数据 - + - + 通道分配 - + - + 启动时是否检测 - + - + 显示厚度数据 - + - + 显示厚度采样数据 - + - + 使用光栅获取厚度 - + - + 保存数据用于测试 - + - + 是否使用通道分配 - + - + 是否启动就开始检测 - + - - + + 是否显示 - + - + 保存 - + - + 请选择您的背景图 - + - + 提示 - + - + 背景图更新完成,请重启本软件. - + - + 确认 - + - + 打开文件夹 - + @@ -1628,7 +1812,12 @@ p, li { white-space: pre-wrap; } 系统设置 - + + + + + 参数设置已生效!!! + @@ -1636,49 +1825,49 @@ p, li { white-space: pre-wrap; } 班次管理 - + - + 未选中 - + - + 添加时间 - + - + 删除时间 - + - + 修改时间 - + 班次 - + 起始时间 - + 结束时间 - + 设置参数 - + @@ -1688,7 +1877,7 @@ p, li { white-space: pre-wrap; } 当天 - + @@ -1698,37 +1887,37 @@ p, li { white-space: pre-wrap; } 隔天 - + 提示 - + 未选择班次,请选择进行修改。 - + 确认 - + 您确定要删除 %1 班次? - + 取消 - + @@ -1736,23 +1925,23 @@ p, li { white-space: pre-wrap; } 工单信息设置 - + 警告 - + 名称不能为空. - + 你输入的名称:%1 重复. - + @@ -1760,232 +1949,232 @@ p, li { white-space: pre-wrap; } 信息设置 - + - + 确定 - + - + 取消 - + - + 备注信息: - + - + 名称: - + QWorkMgrUI - QWorkMgrUI - + 检测配置任务表 + - + 工作任务表 - + - + 添加任务单 - + - + 添加 - + - + 删除任务单 - + - + 删除 - + - + 修改任务单名称或备注信息 - + - + 修改 - + - + 使用任务单 - + - + 应用 - + - + 当前选择的任务表: - + - - + + 数量 - + - + 添加型号到检测列表 - + - + <<< - + - + 从检测列表移除所选型号 - + - + >>> - + - + 缩略图 - + - + 只看已选 - + - + 只看未选 - + - + 显示全部 - + - + 查找: - + - + 其他 - + - + 按照直径检测 - + - + 按照厚度检测 - + - + 手动发送模板库 - + - + 检测模板管理 - + - - + + 共 %1 个 - + - + 当前使用的工单为 %1 - + - + 以下型号为重复添加: %1已被忽略. - + - + 提醒 - + - - - + + + 确定 - + - + 工单 %1 被设为应用 - + - + 发送模板库 - + - - + + 警告 - + - + %1任务单正在使用不能被删除,请先切换到其他任务单,再删除该任务单? - + - - + + 取消 - + - + 是否要删除 %1 模型? - + - + 序号 - + - + 内容 - + @@ -1994,17 +2183,17 @@ p, li { white-space: pre-wrap; } line item is not created - + line item is already created - + rect item is already created - + @@ -2012,52 +2201,52 @@ p, li { white-space: pre-wrap; } 加载通道模块 .... - + 加载模板库 .... - + 加载检测设置模块 .... - + 加载数据库 .... - + 加载班次管理模块 .... - + 加载其他模块 .... - + 创建子线程 .... - + 加载光栅通讯模块 .... - + 模块加载完成,启动线程 .... - + 未登录 - + @@ -2065,487 +2254,531 @@ p, li { white-space: pre-wrap; } 轮毂型号识别 - + image_zoom.ui - + 状态信息 - + - + 开始检测 - + 检测结果 - + - + 无匹配(个) - + - + 已检测(个) - + - + 匹配值 - + - + 直径(mm) - + - + 时间(s) - + - + 通道 - + - - - - - - - + + + + + + + + 0 - + - + --------- - + - + None - + - - + + 检测状态 - + - + 厚度(mm) - + - + + 偏距 + + + + 统计结果 - + - + modelID_detect - + - + count - + - + 交换班清零 - + - + 型号数量 - + - - + + 模板管理 - + - + 数据查询 - + - + 模板勾选 - + - + 辅助工具 - + - + 班次设置 - + - + 光栅标定 - + - + IP设置 - + - - + + 关于 - + - + 登录 - + - + 用户管理 - + - + 系统设置 - + - - + + 相机配置 - + + + + + 算法设置 + + + + + + 注册产品 + - + 加载必要模块..... - + - - + + 工具 - + + + + + + 帮助 + - + + + 本系统未注册激活 + + + + 系统时间 - + - + 班次信息 - + - - 用户: - + + 用户: + - + + PLC连接 + + + + 历史 - + - + 系统初始化完成... - + - - + + 停止检测 - + - + 显示识别结果 - + - - - - + + + + 当前曝光时间未识别到轮毂! - + - - + + 调整5次曝光时间后依然未能识别到轮毂! - + - + 相机图像和背景图不一样,请更换检测背景! - + - + 警告!!!连续出现%1个未识别型号 - + - + ,未开启检测功能造成的 - + - + 获得图像,正在计算中... - + - + 注 销 - + - + 登 录 - + - - - - + + + + 提示 - + - - + + 该功能未启用. - + - - - + + + 确认 - + - + 你确定要注销 - + - - + + 取消 - + - + 班次管理 - + - + 调试工具 - + + + + + 算法参数 + - + 系统参数设置 - + - + + 注册 + + + + 按下了开始检测按钮,检测功能开启 - + - + 按下了停止检测按钮,检测功能关闭 - + - + 将清空所有数据 - + - + 确定 - + - + 按下了清零按钮,数据全部清零 - + - + 天 - + - + 时 - + - + 分 - + - + 秒 - + - - 系统时间: - + + 运行时长: + - - 运行时长: - + + 班次信息: + - - 检测状态: - + + 当前用户: + - + 检测中... - + - + 未检测... - + - - 班次信息: - + + 该时间段未设置班次 + - - 该时间段未设置班次 - + + PLC已连接 + - - 当前用户: - + + PLC未连接 + - + 模板库发送完成 - + - - + + 正在检测型号数 - + - + 已连接 - + - + 已断开 - + - + PLC已收到相关设置参数! - + - + 已打开 - + - + 已关闭 - + - + 轮毂型号识别系统 - + - + 本软件由杭州利珀科技开发,用于轮毂型号识别和分类,可搭配流水线运输系统使用 - + - + 若需要进一步了解该产品的相关信息,请访问我们的网站 - + - + 软件版本 - + - + 算法版本 - + - + 最后更新时间 - + - + 版权 (c) 属 杭州利珀科技有限公司 所有 - + - + 关闭 - + - + (默认) - + - + 默认通道 值1000 - + diff --git a/tpvs17/wheel.sln b/tpvs17/wheel.sln index d3f3f0d..e0febb3 100644 --- a/tpvs17/wheel.sln +++ b/tpvs17/wheel.sln @@ -21,6 +21,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lpReport", "lpReport\lpRepo EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Net4Wheel", "Net4Wheel\Net4Wheel.vcxproj", "{9B718379-3719-4D4E-A903-EDE7EFB4DC65}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tpCamVirtual", "..\..\Valve\tpvs17\tpCamVirtual\tpCamVirtual.vcxproj", "{707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -85,12 +87,20 @@ Global {9B718379-3719-4D4E-A903-EDE7EFB4DC65}.Release|x64.ActiveCfg = Release|x64 {9B718379-3719-4D4E-A903-EDE7EFB4DC65}.Release|x64.Build.0 = Release|x64 {9B718379-3719-4D4E-A903-EDE7EFB4DC65}.Release|x86.ActiveCfg = Release|x64 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Debug|x64.ActiveCfg = Debug|x64 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Debug|x64.Build.0 = Debug|x64 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Debug|x86.ActiveCfg = Debug|Win32 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Debug|x86.Build.0 = Debug|Win32 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Release|x64.ActiveCfg = Release|x64 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Release|x64.Build.0 = Release|x64 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Release|x86.ActiveCfg = Release|Win32 + {707DDF6F-B78B-42F7-9EAD-E786C0FCD5FF}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - Qt5Version = qt5.9.4-msvc2017-x64 SolutionGuid = {CD365F32-5EAC-4A16-AD47-BFB1D8E5511A} + Qt5Version = qt5.9.4-msvc2017-x64 EndGlobalSection EndGlobal