diff --git a/src/ImageCompare/ImageCompareModel.cpp b/src/ImageCompare/ImageCompareModel.cpp index 7c27d53..3a87202 100644 --- a/src/ImageCompare/ImageCompareModel.cpp +++ b/src/ImageCompare/ImageCompareModel.cpp @@ -1,4 +1,4 @@ -/*! \file ImageCompareModel.cpp +/*! \file ImageCompareModel.cpp Copyright (C) 2014 Hangzhou Leaper. @@ -12,30 +12,30 @@ #include #include //#define DEBUG_VIEW_INTERNAL_MAT -#define IMGCMP_STR_NAME "name" -#define IMGCMP_STR_IMAGE_COMPARE_MODEL "imageCompareModel" -#define IMGCMP_STR_ALIGN_BASE_IMAGE "alignBaseImage" -#define IMGCMP_STR_COMPARE_BASE_IMAGE "compareBaseImage" -#define IMGCMP_STR_WEIGHT_MAT "weightMat" -#define IMGCMP_STR_MATCH_VAL_SCALE "matchValScale" -#define IMGCMP_STR_TARGET_MEAN_VAL "targetMeanVal" -#define IMGCMP_STR_TARGET_STDDEV_VAL "targetStddevVal" -#define IMGCMP_STR_REPEAT_NUM "repeatNum" +#define IMGCMP_STR_NAME "name" +#define IMGCMP_STR_IMAGE_COMPARE_MODEL "imageCompareModel" +#define IMGCMP_STR_ALIGN_BASE_IMAGE "alignBaseImage" +#define IMGCMP_STR_COMPARE_BASE_IMAGE "compareBaseImage" +#define IMGCMP_STR_WEIGHT_MAT "weightMat" +#define IMGCMP_STR_MATCH_VAL_SCALE "matchValScale" +#define IMGCMP_STR_TARGET_MEAN_VAL "targetMeanVal" +#define IMGCMP_STR_TARGET_STDDEV_VAL "targetStddevVal" +#define IMGCMP_STR_REPEAT_NUM "repeatNum" #define IMGCMP_STR_TRUE_SAMPLE_DIS_MEAN "trueSampleDisMean" #define IMGCMP_STR_TRUE_SAMPLE_DIS_STDDEV "trueSampleDisStddev" -#define IMGCMP_STR_TRUE_SAMPLE_DIS_MIN "trueSampleDisMin" -#define IMGCMP_STR_TRUE_SAMPLE_DIS_MAX "trueSampleDisMax" -#define IMGCMP_STR_DIS_THRE "disThre" +#define IMGCMP_STR_TRUE_SAMPLE_DIS_MIN "trueSampleDisMin" +#define IMGCMP_STR_TRUE_SAMPLE_DIS_MAX "trueSampleDisMax" +#define IMGCMP_STR_DIS_THRE "disThre" #define IMGCMP_STR_FALSE_SAMPLE_MIN_DIS "falseSampleMinDis" -#define IMGCMP_STR_TRAIN_DIS "trainDis" -#define IMGCMP_STR_SMALLEST_MATCH_DIS "falseMinDis" -#define IMGCMP_STR_AVER_DIAMETER "averageDiameter" -#define IMGCMP_STR_INSIDE_WEIGHT "insideWeightimage" -#define IMGCMP_STR_INSIDE_AVE_IMAGE "insideBaseimage" +#define IMGCMP_STR_TRAIN_DIS "trainDis" +#define IMGCMP_STR_SMALLEST_MATCH_DIS "falseMinDis" +#define IMGCMP_STR_AVER_DIAMETER "averageDiameter" +#define IMGCMP_STR_INSIDE_WEIGHT "insideWeightimage" +#define IMGCMP_STR_INSIDE_AVE_IMAGE "insideBaseimage" #define IMGCMP_STR_INSIDE_COMP_AVE_IMAGE "insideCompareBaseImage" -#define IMGCMP_STR_INSIDE_RADIUS "insideRadius" +#define IMGCMP_STR_INSIDE_RADIUS "insideRadius" #define IMGCMP_STR_INSIDE_TEMPL "innerTempl" -#define IMGCMP_STR_INSIDE_CIRCLE_NUM "insideCircleNum" // the number of circle +#define IMGCMP_STR_INSIDE_CIRCLE_NUM "insideCircleNum" // the number of circle #define IMGCMP_CACHE_MAX_SIZE 100 @@ -56,10 +56,7 @@ cv::Point2f ImageCompareModel::refineCircleCen(const Mat& img, Point2f cen) { for (float x = cen.x - r; x <= cen.x + r; x += 0.5) { - std::cout << "newCenter: " << x << "-" << y << ", "; - Point2f newCenter(x, y); - vector vec; selfRotationSimilarityFeature(img, vec, newCenter); @@ -73,7 +70,6 @@ cv::Point2f ImageCompareModel::refineCircleCen(const Mat& img, Point2f cen) #endif float diffVal = sum(vec.begin(), vec.end()); - vec.push_back(diffVal); if (minDiff > diffVal) @@ -82,11 +78,6 @@ cv::Point2f ImageCompareModel::refineCircleCen(const Mat& img, Point2f cen) bestCenter = newCenter; bestDftVec = dftVec; } - - std::cout << "diff: " << diffVal << ", " - " minDiff: " << minDiff << ", " - " bestCenter: " << bestCenter.x << "-" << bestCenter.y << - std::endl; } } @@ -153,20 +144,19 @@ void ImageCompareModel::selfRotationSimilarityFeature( fImg = fImg.mul(weightImg); double sumVal = sum(weightImg).val[0]; - Mat baseImg; - { - Mat t = getRotationMatrix2D(center, 1.0, 1.0); - Mat rImg; - warpAffine(fImg, rImg, t, fImg.size(), CV_INTER_CUBIC); - t = getRotationMatrix2D(center, -1.0, 1.0); - warpAffine(rImg, baseImg, t, rImg.size(), CV_INTER_CUBIC); - } + + Mat t = getRotationMatrix2D(center, 1.0, 1.0); + Mat rImg; + warpAffine(fImg, rImg, t, fImg.size(), CV_INTER_CUBIC); + t = getRotationMatrix2D(center, -1.0, 1.0); + warpAffine(rImg, baseImg, t, rImg.size(), CV_INTER_CUBIC); + -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat viewBaseImg = baseImg / 255.0/25.0; - Mat viewfImg = fImg / 255.0/25.0; -#endif +// #ifdef DEBUG_VIEW_INTERNAL_MAT +// Mat viewBaseImg = baseImg / 255.0/25.0; +// Mat viewfImg = fImg / 255.0/25.0; +// #endif for (float a = 0; a <= 360.0; a += angleStep) { @@ -211,11 +201,9 @@ cv::Mat ImageCompareModel::genMask(const Mat& img, Point2f center, void ImageCompareModel::genMask() { m32fMaskImg = genMask(mAlignBaseImg, Point2f(mAlignBaseImg.cols / 2.0, mAlignBaseImg.rows / 2.0)); - m8uMaskImg = genMask(mAlignBaseImg, Point2f(mAlignBaseImg.cols / 2.0, mAlignBaseImg.rows / 2.0), - -1.0, -1.0, CV_8UC1); + m8uMaskImg = genMask(mAlignBaseImg, Point2f(mAlignBaseImg.cols / 2.0, mAlignBaseImg.rows / 2.0), -1.0, -1.0, CV_8UC1); m32fInsideMaskImg = genInsideMask(mInSideBaseImg, Point2f(mInSideBaseImg.cols / 2.0, mInSideBaseImg.rows / 2.0)); - m8uInsideMaskImg = genInsideMask(mInSideBaseImg, Point2f(mInSideBaseImg.cols / 2.0, mInSideBaseImg.rows / 2.0), - -1.0, -1.0, CV_8UC1); + m8uInsideMaskImg = genInsideMask(mInSideBaseImg, Point2f(mInSideBaseImg.cols / 2.0, mInSideBaseImg.rows / 2.0), -1.0, -1.0, CV_8UC1); } void ImageCompareModel::printInfo() @@ -397,6 +385,7 @@ bool ImageCompareModel::readFromFile(string filePath) } } +//图像预处理 void ImageCompareModel::preProcessImage(Mat& img, Mat &insideImg) const { preProcessImage(img, m8uMaskImg, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); @@ -407,8 +396,7 @@ void ImageCompareModel::preProcessImage(Mat& img, Mat &insideImg) const preProcessImage(insideImg, m8uInsideMaskImg, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); } -void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, double tarMean, - double tarStddev, int highlightsThreshold) const +void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, double tarMean, double tarStddev, int highlightsThreshold) const { if (img.channels() > 1) { @@ -418,33 +406,32 @@ void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, double tarMea { converToType(img, CV_32FC1); } - + //高斯模糊 处理噪点 Mat gaussImg; GaussianBlur(img, gaussImg, Size(3, 3), 5.0); img = gaussImg; - + + //膨胀 扩大掩膜模板 Mat dilatedMask; - dilate(mask, dilatedMask, Mat::ones(Size(3, 3), CV_32FC1)); + Mat kernel = Mat::ones(Size(3, 3), CV_8UC1); + dilate(mask, dilatedMask, kernel); Mat hightlightsMask = img < highlightsThreshold; Mat imgMask = hightlightsMask & dilatedMask; - + + //计算图像像素均值 对检测图像做均衡 Scalar meanScalar, stddevScalar; meanStdDev(img, meanScalar, stddevScalar, imgMask); img = (img - meanScalar.val[0]) * tarStddev / stddevScalar.val[0] + tarMean; + //归一化处理图像 减少图像间差异 converToType(imgMask, CV_32FC1); imgMask /= 255.0; - Mat imgNorm = cocentricNorm(img, Point2f(img.cols / 2.0, img.rows / 2.0), - imgMask, 125); -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vImgNorm = imgNorm / 255.0; -#endif + Mat imgNorm = cocentricNorm(img, Point2f(img.cols / 2.0, img.rows / 2.0), imgMask, 125); img = imgNorm; } -void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, - const Mat& weightMat, double dstMean, double dstStddev, int highlightsThreshold) const +void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, const Mat& weightMat, double dstMean, double dstStddev, int highlightsThreshold) const { if (img.channels() > 1) { @@ -465,20 +452,11 @@ void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, Scalar meanScalar, stddevScalar; meanStdDev(img, meanScalar, stddevScalar, imgMask); img = (img - meanScalar.val[0]) * dstStddev / stddevScalar.val[0] + dstMean; - //img.setTo(0, img < 0); - converToType(hightlightsMask, CV_32FC1); - //converToType(imgMask, CV_32FC1); - Mat imgNorm = cocentricNorm(img, Point2f(img.cols / 2.0, img.rows / 2.0), - weightMat.mul(hightlightsMask), 125); -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vImgNorm = imgNorm / 255.0; -#endif - img = imgNorm; -} -void ImageCompareModel::preProcessImage0(Mat& img) const -{ + converToType(hightlightsMask, CV_32FC1); + Mat imgNorm = cocentricNorm(img, Point2f(img.cols / 2.0, img.rows / 2.0), weightMat.mul(hightlightsMask), 125); + img = imgNorm; } double ImageCompareModel::compare(Mat img0, Mat img1, Mat* pRImg0, Mat* pRImg1) @@ -492,7 +470,6 @@ double ImageCompareModel::compare(Mat img0, Mat img1, Mat* pRImg0, Mat* pRImg1) int bestAngle = -1; Mat bestImg1; double bestDD = 0; - double w = 0; Point2f center((float)img1.cols / 2.0, (float)img1.rows / 2.0); @@ -510,10 +487,9 @@ double ImageCompareModel::compare(Mat img0, Mat img1, Mat* pRImg0, Mat* pRImg1) { *pRImg1 = rImg1; } - return genMatchValue(dMat); } - +//匹配比较 double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int levelNum /*= 1*/, bool isFilterSize /*= true*/, int flag, double md_diameter, double md_height) { @@ -528,16 +504,13 @@ double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int level int x_Axis = srcImage.cols / 2 - MAX_CIRCLE_RADII; int y_Axis = srcImage.rows / 2 - MAX_CIRCLE_RADII; - int r_Axis = 2 * MAX_CIRCLE_RADII; - if (x_Axis <= 0 || y_Axis <= 0) return DBL_MAX; if (r_Axis <= 0) return DBL_MAX; if (r_Axis >= srcImage.cols || r_Axis >= srcImage.rows) return DBL_MAX; - if (srcImage.cols < (srcImage.cols / 2 + MAX_CIRCLE_RADII) || srcImage.rows < (srcImage.rows / 2 + MAX_CIRCLE_RADII)) return DBL_MAX; @@ -548,11 +521,11 @@ double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int level resizeMat(srcImage, img); resizeMat(srcCenterMat, centerMat); Mat rawImg = img.clone(); - int nRadiusDiff = 15; + int nRadiusDiff = 15;//过滤图像尺寸和模板尺寸不匹配的动作 if (mAlignBaseImg.size() != img.size() || mInSideBaseImg.size() !=centerMat.size()) { - if (isFilterSize \ - && abs(mAlignBaseImg.size().width - img.size().width) > nRadiusDiff \ + if (isFilterSize + && abs(mAlignBaseImg.size().width - img.size().width) > nRadiusDiff || abs(mInSideBaseImg.size().width - centerMat.size().width) > 3) { return DBL_MAX; @@ -560,80 +533,58 @@ double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int level resize(img, img, mAlignBaseImg.size()); resize(centerMat, centerMat, mInSideBaseImg.size()); } - - Mat matchImg = img.clone(); - Mat matchInsideImg = centerMat.clone(); - - preProcessImage(matchImg, matchInsideImg); + //抠出需要检测的图像 + Mat matchImg = img.clone();//辐条部位 + Mat matchInsideImg = centerMat.clone();//圆心部位 + + preProcessImage(matchImg, matchInsideImg);//图像预处理 +// Mat s = matchImg / 255.0; +// imwrite("11.png", s); if (!mpMultiScaleModel) { initMultiScaleModel(); } m_parallelFlag = 0; - RotateMatchResult rmr = rotateMatch(matchImg, levelNum); + RotateMatchResult rmr = rotateMatch(matchImg, levelNum);//旋转图像,计算最佳旋转角度 Mat rImg = rmr.mBestRImg; m_parallelFlag = 1; - RotateMatchResult rmmInside = rotateMatch(matchInsideImg, 1); + RotateMatchResult rmmInside = rotateMatch(matchInsideImg, 1);//旋转图像,计算最佳旋转角度 Mat rInsideImg = rmmInside.mBestRImg; if (rImg.empty() || rInsideImg.empty()) { return DBL_MAX; } -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vRImg = rImg / 255.0; - Mat vInsideMat = rInsideImg / 255.0; -#endif double bestAngle = rmr.mBestAngle; - Mat cmpImg = rotateImage(img, Point2f(img.cols / 2.0, img.rows / 2.0), - bestAngle); + Mat cmpImg = rotateImage(img, Point2f(img.cols / 2.0, img.rows / 2.0), bestAngle);//旋转图像 - // remove highlights + // remove highlights 去除高光影响 Mat hightlightsMask = cmpImg < mHighlightsThreshold; converToType(hightlightsMask, CV_32FC1); hightlightsMask /= 255.0; Mat unifiedMask = m32fMaskImg.mul(hightlightsMask).mul(mWeightMat); - //Mat ii = mWeightMat / 255.0; - preProcessImage(cmpImg, m8uMaskImg, mWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); + preProcessImage(cmpImg, m8uMaskImg, mWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); cmpImg.setTo(0, cmpImg < 0); - converToType(cmpImg, CV_32FC1); - normSectors_tarImg(cmpImg, unifiedMask, imgCen(cmpImg), 1, - mCompareBaseImg); + normSectors_tarImg(cmpImg, unifiedMask, imgCen(cmpImg), 1, mCompareBaseImg); double bestInsideAngle = rmmInside.mBestAngle; - Mat camInsideMat = rotateImage(centerMat, Point2f(centerMat.cols / 2.0, centerMat.rows / 2.0), - bestInsideAngle); - + Mat camInsideMat = rotateImage(centerMat, Point2f(centerMat.cols / 2.0, centerMat.rows / 2.0), bestInsideAngle); Mat highLightInsideMask = camInsideMat < mHighlightsThreshold; converToType(highLightInsideMask, CV_32FC1); highLightInsideMask /= 255.0; Mat unifiedInsideMask = m32fInsideMaskImg.mul(highLightInsideMask).mul(mInsideWeightMat); - preProcessImage(camInsideMat, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); + preProcessImage(camInsideMat, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); Mat vcamInside = camInsideMat / 255.0; camInsideMat.setTo(0, camInsideMat < 0); //mInsideCompareBaseImg.setTo(0, mInsideCompareBaseImg < 0); normSectors_tarImg(camInsideMat, unifiedInsideMask, imgCen(camInsideMat), 1, mInsideCompareBaseImg); - // mInsideCompareBaseImg.setTo(0, mInsideCompareBaseImg < 0); -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vRotatedImg0 = cmpImg / 255.0; - Mat vrotatedInsideImage = camInsideMat / 255.0; - cv::imwrite("F:\\temp\\insideAfterSector.png", camInsideMat); -#endif - -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vRotatedImg1 = mCompareBaseImg / 255.0; - Mat vrotatedInsideBase = mInsideCompareBaseImg / 255.0; - cv::imwrite("F:\\temp\\insideAfterSectorCompareBase.png", mInsideCompareBaseImg); -#endif cmpImg.setTo(0, cmpImg < 10); //camInsideMat.setTo(0, camInsideMat < 10); @@ -642,10 +593,14 @@ double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int level *pRImg = cmpImg; } m_parallelFlag = 0; - double ret = genMatchValue(cmpImg, mCompareBaseImg, unifiedMask, flag, rawImg.rows, md_diameter, md_height);//óֵ + Mat s1 = cmpImg / 255.0; + Mat s2 = mCompareBaseImg / 255.0; + Mat s3 = unifiedMask / 255.0; + Mat s4 = rawImg / 255.0; + double ret = genMatchValue(cmpImg, mCompareBaseImg, unifiedMask, flag, rawImg.rows, md_diameter, md_height);//得出相似值 m_parallelFlag = 1; - double retInside = genMatchValue(camInsideMat, mInsideCompareBaseImg, unifiedInsideMask, 0, rawImg.rows, md_diameter, md_height);//óֵ + double retInside = genMatchValue(camInsideMat, mInsideCompareBaseImg, unifiedInsideMask, 0, rawImg.rows, md_diameter, md_height);//得出相似值 ret = 0.6*ret + 0.4*retInside; @@ -695,32 +650,32 @@ void ImageCompareModel::train(const vector& vec) Vec3f bestCircle; Point2f p = Point2f(originalMat.cols / 2.0, originalMat.rows / 2.0); // cd.detectBest(originalMat, Point2f(originalMat.cols / 2.0, originalMat.rows / 2.0), bestCircle, nullptr); -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat img1 = vec.front().clone(); - Mat img2 = vec.front().clone(); - vector vecs; - vecs.push_back(originalMat); - vecs.push_back(originalMat); - vecs.push_back(originalMat); - Mat rr; - merge(vecs, rr); - - circle(rr, Point2f(bestCircle[0], bestCircle[1]), bestCircle[2], Scalar(255, 0, 0), 2); - vector imgVec; - resizeVecMat(vec, imgVec); - vector vecss; - vecss.push_back(originalMat); - vecss.push_back(originalMat); - vecss.push_back(originalMat); - Mat rrr; - merge(vecss, rrr); - - // circle(rrr, Point2f(bestCircle[0] / COLS_SCALE, bestCircle[1] / COLS_SCALE), rInner, Scalar(255, 0, 0), 1); -#endif // DEBUG_VIEW_INTERNAL_MAT +// #ifdef DEBUG_VIEW_INTERNAL_MAT +// Mat img1 = vec.front().clone(); +// Mat img2 = vec.front().clone(); +// vector vecs; +// vecs.push_back(originalMat); +// vecs.push_back(originalMat); +// vecs.push_back(originalMat); +// Mat rr; +// merge(vecs, rr); +// +// circle(rr, Point2f(bestCircle[0], bestCircle[1]), bestCircle[2], Scalar(255, 0, 0), 2); +// vector imgVec; +// resizeVecMat(vec, imgVec); +// vector vecss; +// vecss.push_back(originalMat); +// vecss.push_back(originalMat); +// vecss.push_back(originalMat); +// Mat rrr; +// merge(vecss, rrr); +// +// // circle(rrr, Point2f(bestCircle[0] / COLS_SCALE, bestCircle[1] / COLS_SCALE), rInner, Scalar(255, 0, 0), 1); +// #endif // DEBUG_VIEW_INTERNAL_MAT //bob edit - float startX = originalMat.cols / 2.0 - MAX_CIRCLE_RADII;//Բ⾶̶ֱ + float startX = originalMat.cols / 2.0 - MAX_CIRCLE_RADII;//找最大圆外径,固定直径 float startY = originalMat.rows / 2.0 - MAX_CIRCLE_RADII; Rect rect(startX, startY, MAX_CIRCLE_RADII * 2, MAX_CIRCLE_RADII * 2); Mat origianlCenterMat; @@ -767,7 +722,7 @@ void ImageCompareModel::train(const vector& vec) mInSideBaseImg = scaledCenterVec.front(); genMask(); - preProcessImage(mAlignBaseImg, mInSideBaseImg);//Ԥ վ + preProcessImage(mAlignBaseImg, mInSideBaseImg);//预处理 光照均衡 Mat sumOutsideMat = Mat::zeros(mAlignBaseImg.size(), CV_32FC1); Mat sumInsideMat = Mat::zeros(mInSideBaseImg.size(), CV_32FC1); Mat minOutsideMat(mAlignBaseImg.size(), mAlignBaseImg.type()); @@ -807,7 +762,7 @@ void ImageCompareModel::train(const vector& vec) //Mat insideImg = img.clone(); preProcessImage(img, centerMat); m_parallelFlag = 0; - RotateMatchResult rmr = rotateMatch(img);//תƥ ƥɵĽǶȼͼƬ + RotateMatchResult rmr = rotateMatch(img);//旋转匹配 输出匹配完成的角度及图片 rmrVec.push_back(rmr); m_parallelFlag = 1; RotateMatchResult rmrInside = rotateMatch(centerMat); @@ -819,7 +774,7 @@ void ImageCompareModel::train(const vector& vec) Mat rInsideImg = rmrInside.mBestRImg; rInsideImgVec.push_back(rInsideImg); //minMat = min(minMat, rImg); - minOutsideMat = min(minOutsideMat, rImg);//Ȩͼ ȥë + minOutsideMat = min(minOutsideMat, rImg);//生成权重图 去毛刺 sumOutsideMat += rImg; minInsideMat = min(minInsideMat, rInsideImg); @@ -848,14 +803,13 @@ void ImageCompareModel::train(const vector& vec) mWeightMat /= 255.0; mInsideWeightMat = minInsideMat; mInsideWeightMat /= 255.0; - /*luffy_base::luffy_imageProc::*/meanvarnorm(mWeightMat, mWeightMat,//Ȩؽ һ - mTargetMeanVal, 150, m8uMaskImg); + + //对权重进行 归一化 + meanvarnorm(mWeightMat, mWeightMat, mTargetMeanVal, 150, m8uMaskImg); mWeightMat.setTo(0, mWeightMat < 10); Scalar meanScalar, stddevScalar; meanStdDev(mInsideWeightMat, meanScalar, stddevScalar, m8uInsideMaskImg); mInsideWeightMat = mInsideWeightMat* (127 / meanScalar.val[0]); - //luffy_base::luffy_imageProc::meanvarnorm(mInsideWeightMat, mInsideWeightMat, - // mTargetMeanVal, 50, m8uInsideMaskImg); mInsideWeightMat.setTo(0, mInsideWeightMat < 0); { @@ -884,25 +838,22 @@ void ImageCompareModel::train(const vector& vec) { double bestAngle = rmrVec[i].mBestAngle; Mat img = resizedImgVec[i]; - Mat rotatedImg = rotateImage(img, Point2f(img.cols/2.0, img.rows/2.0), - bestAngle); + Mat rotatedImg = rotateImage(img, Point2f(img.cols/2.0, img.rows/2.0), bestAngle); - preProcessImage(rotatedImg, m8uMaskImg, mWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); + preProcessImage(rotatedImg, m8uMaskImg, mWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); double bestInsidePart = rmrVecInside[i].mBestAngle; //Mat i_Mat = resizedImgVec[i]; Mat centerMat = resizedCenterVec[i]; Mat rotatedInsideMat = rotateImage(centerMat, Point2f(centerMat.cols / 2.0, centerMat.rows / 2.0), bestInsidePart); - preProcessImage(rotatedInsideMat, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); + preProcessImage(rotatedInsideMat, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); sumOutsideMat += rotatedImg; //rotatedInsideMat.setTo(0, rotatedInsideMat < 0); sumInsideMat += rotatedInsideMat; } - mCompareBaseImg = sumOutsideMat / resizedImgVec.size();//õƥͼ + mCompareBaseImg = sumOutsideMat / resizedImgVec.size();//得到最终匹配图 mInsideCompareBaseImg = sumInsideMat / resizedImgVec.size(); #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vCompareBaseImg = mCompareBaseImg / 255.0; @@ -931,8 +882,7 @@ void ImageCompareModel::trueSampleWeightRecon(const vector& resizedVec, const Mat &img = resizedVec[i]; double bestAngle = rmrVec[i].mBestAngle; //preProcessImage(processedImg, insideMatchImg); - Mat rotatedImg = rotateImage(img, Point2f(img.cols / 2.0, img.rows / 2.0), - bestAngle); + Mat rotatedImg = rotateImage(img, Point2f(img.cols / 2.0, img.rows / 2.0), bestAngle); Mat hightlightsMask = rotatedImg < mHighlightsThreshold; converToType(hightlightsMask, CV_32FC1); @@ -940,8 +890,7 @@ void ImageCompareModel::trueSampleWeightRecon(const vector& resizedVec, Mat unifiedMask = m32fMaskImg.mul(hightlightsMask).mul(mWeightMat); - preProcessImage(rotatedImg, m8uMaskImg, mWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); + preProcessImage(rotatedImg, m8uMaskImg, mWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); rotatedImg.setTo(0, rotatedImg < 0); converToType(rotatedImg, CV_32FC1); @@ -955,15 +904,13 @@ void ImageCompareModel::trueSampleWeightRecon(const vector& resizedVec, ////// FOR INSIDE CIRCLE double insideBestAngle = rmrVecInside[i].mBestAngle; const Mat & centerMat = resizedCenterVec[i]; - Mat rotatedInsideImg = rotateImage(centerMat, Point2f(centerMat.cols / 2.0, centerMat.rows / 2.0), - insideBestAngle); + Mat rotatedInsideImg = rotateImage(centerMat, Point2f(centerMat.cols / 2.0, centerMat.rows / 2.0), insideBestAngle); Mat highLightInsideMask = rotatedInsideImg < mHighlightsThreshold; converToType(highLightInsideMask, CV_32FC1); highLightInsideMask /= 255.0; Mat unifiedInsideMask = m32fInsideMaskImg.mul(highLightInsideMask).mul(mInsideWeightMat); - preProcessImage(rotatedInsideImg, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); + preProcessImage(rotatedInsideImg, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); Mat vcamInside = rotatedInsideImg / 255.0; rotatedInsideImg.setTo(0, rotatedInsideImg < 0); //mInsideCompareBaseImg.setTo(0, mInsideCompareBaseImg < 0); @@ -1240,7 +1187,8 @@ void ImageCompareModel::selfRotateMin(const Mat& img, Mat& weightMat, int repeat { Mat rotatedImg = rotateImage(img, cen, i*angleStep); Mat dilatedImg; - dilate(rotatedImg, dilatedImg, Mat::ones(3, 3, CV_32FC1)); + Mat kernel = Mat::ones(3, 3, CV_32FC1); + dilate(rotatedImg, dilatedImg, kernel); dSumMat = min(dSumMat, dilatedImg); } weightMat = dSumMat; @@ -1249,31 +1197,59 @@ void ImageCompareModel::selfRotateMin(const Mat& img, Mat& weightMat, int repeat double ImageCompareModel::genMatchValue(const Mat& dMat) const { double v = norm(dMat, NORM_L2); - double ret = scaleMatchValue(v); - return ret; } +double ImageCompareModel::genMatchValue2(const Mat& rImg, const Mat& baseImg, const Mat& maskImg) const +{ + Mat dMat = rImg - baseImg; + dMat = abs(dMat.mul(maskImg)); + + Mat minmaxScaleMat; + Mat mMask; + if (m_parallelFlag != 1) + { + minmaxScaleMat = minMaxNorm(dMat, 0, 255, m8uMaskImg); + converToType(minmaxScaleMat, CV_8UC1); + mMask = lowerMajorityMask(minmaxScaleMat, m8uMaskImg, 0.98); + // Mat dd = mMask / 255.0; + // Mat ddmask = m8uMaskImg / 255.0; + } + else + { + minmaxScaleMat = minMaxNorm(dMat, 0, 255, m8uInsideMaskImg); + converToType(minmaxScaleMat, CV_8UC1); + mMask = lowerMajorityMask(minmaxScaleMat, m8uInsideMaskImg, 0.97); + } + converToType(mMask, CV_32FC1); + mMask /= 255.0; + + dMat = dMat.mul(mMask); + +#ifdef DEBUG_VIEW_INTERNAL_MAT + Mat vDMat1 = abs(dMat) / 255.0 / 255.0; +#endif + Mat vii = mMask.mul(maskImg); + Mat ii = mMask.mul(maskImg) / 255.0; + double s = sum(mMask.mul(maskImg)).val[0]; + double ret = genMatchValue(dMat) / s; + + return ret; +} + double ImageCompareModel::genMatchValue(const Mat& rImg, const Mat& baseImg, const Mat& maskImg, int flag, int diameter, double md_diameter, double md_height) const -{ +{ + + Mat v1 = rImg / 255.0;//展示图 + Mat v2 = baseImg / 255.0;//展示图 + Mat v3 = maskImg / 255.0;//展示图 + Mat dMat = rImg - baseImg; - //Mat testMask = maskImg.mul(m32fMaskImg); dMat = abs(dMat.mul(maskImg)); - //dMat = abs(dMat.mul(testMask)); -#ifdef DEBUG_VIEW_INTERNAL_MAT - //Mat vRImg = rImg.mul(m32fMaskImg) / 255.0; - Mat vDMat0 = abs(dMat) / 255.0; - //Mat vBase = baseImg.mul(m32fMaskImg) / 255.0; - Mat vDMat = abs(dMat) / 255.0 / 255.0; - - //Mat vinsideImg = rImg.mul(m32fInsideMaskImg) / 255.0; - //Mat vinsideBase = baseImg.mul(m32fInsideMaskImg) / 255.0; - // Mat vMask = maskImg / 255.0; - //Mat vMask = testMask / 255.0; -#endif + Mat dV = dMat / 255.0; Mat minmaxScaleMat; Mat mMask; if (m_parallelFlag != 1) @@ -1281,37 +1257,28 @@ double ImageCompareModel::genMatchValue(const Mat& rImg, const Mat& baseImg, minmaxScaleMat = minMaxNorm(dMat, 0, 255, m8uMaskImg); converToType(minmaxScaleMat, CV_8UC1); mMask = lowerMajorityMask(minmaxScaleMat, m8uMaskImg, 0.98); - printLog("myLog.txt", "finish outside mMask Part"); } else { minmaxScaleMat = minMaxNorm(dMat, 0, 255, m8uInsideMaskImg); converToType(minmaxScaleMat, CV_8UC1); mMask = lowerMajorityMask(minmaxScaleMat, m8uInsideMaskImg, 0.97); - printLog("myLog.txt", "finish inside mMask Part"); } - converToType(mMask, CV_32FC1); mMask /= 255.0; dMat = dMat.mul(mMask); - -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vDMat1 = abs(dMat) / 255.0 / 255.0; -#endif - Mat vii = mMask.mul(maskImg); - Mat ii = mMask.mul(maskImg) / 255.0; - double s = sum(mMask.mul(maskImg)).val[0]; + Mat sunMat = mMask.mul(maskImg); +// Mat ii = mMask.mul(maskImg) / 255.0; + double s = sum(sunMat).val[0]; double ret = genMatchValue(dMat) / s; if (flag == 1) { double matchedVal = ret; - ret = penltyCoeff(matchedVal, meanDiameter, diameter, md_diameter, md_height);//ͷ - printf("the matched value %f", ret); + ret = penltyCoeff(matchedVal, meanDiameter, diameter, md_diameter, md_height);//做惩罚 } - printLog("myLog.txt", "finish detect, return val"); - return ret; + return ret; } double ImageCompareModel::scaleMatchValue(double val) const @@ -1319,7 +1286,6 @@ double ImageCompareModel::scaleMatchValue(double val) const return val*mMatchValScale; } - ImageCompareModel* ImageCompareModel::scale(float s) { Mat baseImage; @@ -1348,10 +1314,6 @@ ImageCompareModel* ImageCompareModel::scale(float s) ImageCompareModel::RotateMatchResult ImageCompareModel::rotateMatch(const Mat& img, int levelNum /*= 1*/, float angleStep /*= 1.0*/, float startAngle /*= 0*/, float endAngle /*= 360*/) const { -#ifdef _TEST - static int idx = 0; - std::cout << idx << " "; -#endif RotateData* pData = new RotateData; vector angleRangeVec; if (levelNum > 1) @@ -1978,6 +1940,7 @@ void ImageCompareModel::weightReconstruction(const Mat& rImg, const Mat& baseImg } } } + double ImageCompareModel::penltyCoeff(double matchedVal, int diameterMean, int targetDiameter, double modelDiamter, double modelHeight) const { int diff = abs(diameterMean - targetDiameter); @@ -2173,13 +2136,7 @@ float ImageCompareModel::allocateInnerRadius(cv::Mat subImage) initialPoint = p; } } -#ifdef _DEBUG - Mat insideMat(tarMat.size(), tarMat.type(), Scalar::all(0)); - int offset = 2; - cv::circle(insideMat, center, minDis - offset, Scalar(1), -1); - Mat ddst = insideMat.mul(subImage); -#endif - return minDis - 2; + return (minDis - 2); } float ImageCompareModel::allocateRadius(cv::Mat subImage) @@ -2331,13 +2288,13 @@ float ImageCompareModel::allocateRadius(cv::Mat subImage) initialPoint = p; } } - #ifdef _DEBUG - Mat insideMat(tarMat.size(), tarMat.type(), Scalar::all(0)); - int offset = 2; - cv::circle(insideMat, center, minDis - offset, Scalar(1), -1); - Mat ddst = insideMat.mul(subImage); - #endif - return minDis - 2; +// #ifdef _DEBUG +// Mat insideMat(tarMat.size(), tarMat.type(), Scalar::all(0)); +// int offset = 2; +// cv::circle(insideMat, center, minDis - offset, Scalar(1), -1); +// Mat ddst = insideMat.mul(subImage); +// #endif + return (minDis - 2); } void ImageCompareModel::genOutterMask() @@ -2368,25 +2325,25 @@ void ImageCompareModel::resizeMat(Mat src, Mat &dst) cv::resize(src, dst, cv::Size(nWidth, nWidth)); } -void ImageCompareModel::printLog(string root, string log, double n) const -{ -#ifdef DEBUG_VIEW_INTERNAL_MAT - ofstream write; - write.open(root, ios::app); - time_t seconds = time(NULL); - struct tm *p; - p = localtime(&seconds); - char strTime[100] = { 0 }; - sprintf(strTime, "%02d-%02d %02d:%02d:%02d:", 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); - std::ostringstream str; - str << log; - if (n != 0) - { - str << n; - } - write << "time:" << string(strTime); - write << str.str() << "\n"; - write.close(); -#endif -} +// void ImageCompareModel::printLog(string root, string log, double n) const +// { +// #ifdef DEBUG_VIEW_INTERNAL_MAT +// ofstream write; +// write.open(root, ios::app); +// time_t seconds = time(NULL); +// struct tm *p; +// p = localtime(&seconds); +// char strTime[100] = { 0 }; +// sprintf(strTime, "%02d-%02d %02d:%02d:%02d:", 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); +// std::ostringstream str; +// str << log; +// if (n != 0) +// { +// str << n; +// } +// write << "time:" << string(strTime); +// write << str.str() << "\n"; +// write.close(); +// #endif +// } diff --git a/src/ImageCompare/ImageCompareModel.h b/src/ImageCompare/ImageCompareModel.h index 826d796..aa6e9f1 100644 --- a/src/ImageCompare/ImageCompareModel.h +++ b/src/ImageCompare/ImageCompareModel.h @@ -1,4 +1,4 @@ -/*! \file ImageCompareModel.h +/*! \file ImageCompareModel.h Copyright (C) 2014 Hangzhou Leaper. @@ -182,22 +182,21 @@ public: void preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold) const; void preProcessImage(Mat& img, const Mat& mask, const Mat& weightMat, double dstMean, double dstStddev, int highlightsThreshold) const; - void preProcessImage0(Mat& img) const; void weightOptimization(const vector& falseSamples); - //! һͼͱ׼ͼmBaseImgתƥ䣬òֵ + //! 将一个图像和标准图mBaseImg进行旋转匹配,再相减求得差异值 /*! - \param Mat img ͼ - \param Mat * pRImg ͼתƥ - \param bool isFilterSize Ƿͼߴ - \return double ֵ + \param Mat img 输入图像 + \param Mat * pRImg 输入图像的旋转匹配结果 + \param bool isFilterSize 是否根据图像尺寸过滤 + \return double 差异值 \see compare(Mat, Mat, Mat*, Mat*) */ double compare(Mat srcImage, Mat* pRImg = NULL, int levelNum = 1, bool isFilterSize = true, int flag = 0, double md_diameter = 0, double md_height = 0); - //! ѵõ׼ͼmBaseImg + //! 训练得到标准图像mBaseImg /*! - \param const vector & imgVec ͬѵͼ + \param const vector & imgVec 属于同类的训练样本图 \return void */ void train(const vector& vec); @@ -209,26 +208,26 @@ public: //void falseWeightmapping(Mat &img); double descendFunction(double pixVal, double maxVal); double penltyCoeff(double matchedVal, int diameterMean, int targetDiameterm, double modelDiamter, double modelHeight) const; - //! ݸֵжһµͼǷڸ + //! 根据负样本计算差异阈值,用于判断任意一个新的图像是否属于该类别。 /*! - \param const vector & imgVec ڸѵͼ + \param const vector & imgVec 不属于该类的训练样本图 \return void */ void computeDisThre(const vector& imgVec, double* pMinDis = NULL, double md_diameter = 0, double md_height = 0); double filterTrainImage(const Mat &img); - //! мrotate + //! 并行计算rotate /*! - \param int index ǰindex - \param void *p ָ + \param int index 当前并行index + \param void *p 数据指针 */ void parallelDetect(int index, void *p) const; - //! ȡ׼ͼ + //! 获取标准图像 /*! - \return cv::Mat ׼ͼ + \return cv::Mat 标准图像 */ Mat getInsideBaseImg() const { return mInSideBaseImg; } Mat getInsideWeightImg() const { return mInsideWeightMat; } @@ -263,17 +262,17 @@ public: double getFalseSampleMinDis() const { return mFalseSampleMinDis; } double getMeanDiamter() const { return meanDiameter; } - //! ȡһִreadFromFileʱļ· + //! 获取最近一次执行readFromFile时输入的文件路径 /*! - \return string ļ· + \return string 文件路径 */ string getFilePath() const { return mFilePath; } double getDisThre() const { return mDisThre; } void setDisThre(double val) { mDisThre = val; } - //! û档ὫÿεcompareӿimgdataָΪkey洢 - // ֵ + //! 启用缓存。缓存会将每次调用compare接口输入的img参数的data指针作为key存储 + // 差异值。 /*! \return void */ @@ -303,16 +302,16 @@ public: void setRealHeight(int val){ realHeight = val; } int getRealWidth(){ return realWidth; } int getRealHeight(){ return realHeight; } - void printLog(string root, string log, double n = 0) const; + //void printLog(string root, string log, double n = 0) const; protected: - //! δɣͼֱͱ׼ͼmBaseImgתƥ䣬òֵ + //! (尚未完成)将两个图像分别和标准图mBaseImg进行旋转匹配,再相减求得差异值 /*! - \param Mat img0 Ƚϵͼimg0 - \param Mat img1 Ƚϵͼimg1 - \param Mat * pRImg0 img0ͱ׼ͼmBaseImgתƥĽrimg0 - \param Mat * pRImg1 img1ͱ׼ͼmBaseImgתƥĽrimg1 - \return double ֵȡֵСΪmMatchValScale*norm(rimg0 - rimg1)/(cols*rows) + \param Mat img0 待比较的图像img0 + \param Mat img1 带比较的图像img1 + \param Mat * pRImg0 将img0和标准图mBaseImg旋转匹配的结果rimg0 + \param Mat * pRImg1 将img1和标准图mBaseImg旋转匹配的结果rimg1 + \return double 差异值,取值大小为mMatchValScale*norm(rimg0 - rimg1)/(cols*rows) */ double compare(Mat img0, Mat img1, Mat* pRImg0 = NULL, Mat* pRImg1 = NULL); @@ -320,7 +319,8 @@ protected: double genMatchValue(const Mat& rImg, const Mat& baseImg, const Mat& maskImg, int flag, int diameter, double md_diameter, double md_height) const; double genMatchValue(const Mat& dMat) const; - double scaleMatchValue(double val) const; + double genMatchValue2(const Mat& rImg, const Mat& baseImg, const Mat& maskImg) const; + double scaleMatchValue(double val) const; void weightReconstruction(const Mat& rImg, const Mat& baseImg, const Mat& maskImg, Mat &reConImg); void preWeightReconstruction(Mat img, Mat &reConImg); diff --git a/src/algorithm/AlgorithmCompare.cpp b/src/algorithm/AlgorithmCompare.cpp index 0f5b00b..a626764 100644 --- a/src/algorithm/AlgorithmCompare.cpp +++ b/src/algorithm/AlgorithmCompare.cpp @@ -310,7 +310,7 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj) if (matMatch.empty()) { rltMap.insert("noCircle", 0); - QImage srcImg = QtCVUtils::cvMatToQImage(matSrc); + QImage srcImg = cvMat2QImage(matSrc); rltMap.insert("srcImage", srcImg); pImgObj->IVariantMapToUI(rltMap); return 0; @@ -330,12 +330,7 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj) if (!matMatch.empty() && ptr && ptr->size() > 0) { vector minDisVec(ptr->size()); - qDebug() << "start bestMatch"; QString str = bestMatch(ptr, &wheelLocal, &(minDisVec[0]), minDisVec.size()); - qDebug() << "end bestMatch"; -// pResult->m_strModel = str; -// pResult->m_dMinDis = minDisVec[0]; - mResult.insert("modeName", str); mResult.insert("minDis", minDisVec[0]); @@ -343,7 +338,6 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj) ICompareModel *pModel = ptr->value(str)->getImageComModel(); double d = pModel->getDisThre(); double dValue = (d - minDisVec[0]) / d * 0.4 + 0.6; - //pResult->m_dScore = dValue; mResult.insert("score", dValue); } } @@ -353,18 +347,9 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj) mResult.insert("pixResult", resultImage); mResult.insert("diameter", dDiameter); mResult.insert("thickness", th); - - - //pResult->m_pixSrc = QtCVUtils::cvMatToQPixmap(matSrc);//!>原图像发送值UI 用于保存备份和调试 - //QImage img = QtCVUtils::cvMatToQImage(matMatch); - //pResult->m_pixResult = QtCVUtils::cvMatToQPixmap(matMatch); - //pResult->m_dDiameter = dDiameter; - //pResult->m_dThickness = th; double dTime = (cv::getTickCount() - dStart) / cv::getTickFrequency(); - //pResult->m_dRunTime = dTime; mResult.insert("runTime", dTime); - //long long varRlt = (long long)pResult; rltMap.insert("result", mResult); QImage srcImg = cvMat2QImage(matSrc); rltMap.insert("srcImage", srcImg); diff --git a/src/algorithm/ImageProcess.cpp b/src/algorithm/ImageProcess.cpp index ccf6cb0..46b7f4c 100644 --- a/src/algorithm/ImageProcess.cpp +++ b/src/algorithm/ImageProcess.cpp @@ -30,6 +30,7 @@ Mat _EnhanImg_sharpen(const Mat &img) { Mat openMat = orResult.clone(); return openMat; } + Mat findEdge2(const Mat &Src) { Mat ret = Src.clone(); @@ -42,6 +43,7 @@ Mat findEdge2(const Mat &Src) filter2D(Src, ret, CV_8UC1, kernel); return ret; } + #define REAIZE 2 cv::Mat ImageProcess::findCircleObject(const Mat &srcImg, const Mat& backgroundImg, bool useBackgroundFlag, int nThres /*= 20*/, luffy_base::luffyCircle *pCircle /*= NULL*/) { @@ -50,7 +52,7 @@ cv::Mat ImageProcess::findCircleObject(const Mat &srcImg, const Mat& backgroundI if (!useBackgroundFlag) { Mat detectImg; - Mat src = srcImg;// (Rect(435, 53, 1721, 1824)); + Mat src = srcImg(Rect(435, 53, 1721, 1824)); cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); int bBaseX = detectImg.cols; int bBaseY = detectImg.rows; @@ -84,7 +86,7 @@ cv::Mat ImageProcess::findCircleObject(const Mat &srcImg, const Mat& backgroundI if (startX > 0 && startY > 0 && hight > 0 \ && startX < src.cols &&startY < src.rows \ - &&hight < src.cols&&hight < src.rows \ + && hight < src.cols&&hight < src.rows \ && (startX + hight) < src.cols && (startY + hight) < src.rows) { Mat cutMat = src(Rect(startX, startY, hight, hight)); @@ -123,10 +125,6 @@ cv::Mat ImageProcess::findCircleObject(const Mat &srcImg, const Mat& backgroundI assert(backgroundImg.type() == CV_8UC1); Mat imgTmp = src, 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; luffy_threshold::Threshold(imgTmp, imgBinary, 50);//0421 @@ -175,13 +173,6 @@ cv::Mat ImageProcess::findCircleObject(const Mat &srcImg, const Mat& backgroundI 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; diff --git a/src/algorithm/tpAlgorithm.cpp b/src/algorithm/tpAlgorithm.cpp index 47eba37..f864e9c 100644 --- a/src/algorithm/tpAlgorithm.cpp +++ b/src/algorithm/tpAlgorithm.cpp @@ -11,4 +11,4 @@ ALGORITHM_API void Algorithm_Delete(IAlgorithm* pAlg) { delete pAlg; } -} \ No newline at end of file +} diff --git a/src/lpCamera/lpCamHik/CameraHik.cpp b/src/lpCamera/lpCamHik/CameraHik.cpp index d8ae845..b650b84 100644 --- a/src/lpCamera/lpCamHik/CameraHik.cpp +++ b/src/lpCamera/lpCamHik/CameraHik.cpp @@ -257,6 +257,9 @@ void CCameraHik::ISnapCamera() if (MV_OK != nRet){ qWarning() << QString("Error: TriggerSource to line0 failed [%1]").arg(nRet) << " - " << __FUNCTION__; + ICloseCamera(); + IOpenCamera(); + IStartCamera(); return ; } nValue = MV_TRIGGER_MODE_ON; diff --git a/src/tpMain/algela/lpImgViewer.cpp b/src/tpMain/algela/lpImgViewer.cpp index 057e9bb..a054191 100644 --- a/src/tpMain/algela/lpImgViewer.cpp +++ b/src/tpMain/algela/lpImgViewer.cpp @@ -88,6 +88,7 @@ void lpImgViewer::wheelEvent(QWheelEvent *evt) mpImgItem->setTransformOriginPoint(0, 0); scaleImg2(newScale); + emit sgImageScale(newScale); } else { @@ -218,7 +219,7 @@ void lpImgViewer::scaleImg(QTransform tf, QPointF center) void lpImgViewer::scaleImg2(qreal scale) { - if (scale < 0.1) + if (scale < 0.01) return; m_scale = scale; QTransform t; diff --git a/src/tpMain/algela/lpImgViewer.h b/src/tpMain/algela/lpImgViewer.h index 3cc7740..773a9e5 100644 --- a/src/tpMain/algela/lpImgViewer.h +++ b/src/tpMain/algela/lpImgViewer.h @@ -56,7 +56,7 @@ signals: void imgMoved(QPointF pos); void pixelSelected(QPoint pos); void imgScaledWithFixedSize(qreal scale); - + void sgImageScale(qreal); public slots: void scaleImg(QTransform tf, QPointF center); void moveImg(QPointF pos); diff --git a/src/tpMain/lpGlobalConfig.cpp b/src/tpMain/lpGlobalConfig.cpp index b8c6019..d45a7c6 100644 --- a/src/tpMain/lpGlobalConfig.cpp +++ b/src/tpMain/lpGlobalConfig.cpp @@ -12,6 +12,7 @@ #define WHEEL_D2H_K "k" #define WHEEL_D2H_B "b" +#pragma execution_character_set("utf-8") lpGlobalConfig::lpGlobalConfig() : IsOnline(0), IsDetect(0), IsCheck(false) @@ -36,6 +37,11 @@ void lpGlobalConfig::init(QString strPath) QString fileMyself = m_applicationDirPath + WHEEL_SELFDEFINE_FILE; QJsonObject jsMyself = QZkJsonParser::ReadJsonAuto(fileMyself); tcpServerPort = jsMyself.value("tcpServerPort").toInt(10100); + webSocketPort = jsMyself.value("webSocketPort").toInt(10110); + + bRunBackRunning = jsMyself.value("runBackRnning").toBool(false); + bRunBackClosing = jsMyself.value("runBackClosing").toBool(false);//关闭页面时自动后台运行 + strSysTitle = jsMyself.value("systitle").toString(QObject::tr("识别定位一体系统"));//系统标题 QJsonObject algObj = jsMyself.value(WHEEL_SELFDEFINE_ALGPARA).toObject(); if (!algObj.isEmpty()) @@ -280,6 +286,11 @@ void lpGlobalConfig::saveDeteImage() jsMyself.insert(WHEEL_SELFDEFINE_AUTOITEM, autosystemobj); jsMyself.insert("tcpServerPort", tcpServerPort); + jsMyself.insert("webSocketPort", webSocketPort); + + jsMyself.insert("runBackRnning",bRunBackRunning); + jsMyself.insert("runBackClosing", bRunBackClosing);//关闭页面时自动后台运行 + jsMyself.insert("systitle", strSysTitle);//系统标题 QZkJsonParser::WriteJsonObject(fileMyself, jsMyself); } diff --git a/src/tpMain/lpGlobalConfig.h b/src/tpMain/lpGlobalConfig.h index 47c02aa..4085e41 100644 --- a/src/tpMain/lpGlobalConfig.h +++ b/src/tpMain/lpGlobalConfig.h @@ -87,7 +87,7 @@ public: bool bSaveSrcNGImg_value{ false };//是否保存定位NG原始图像 bool bSaveSrcOKImg_value{ false };//是否保存定位NG原始图像 int tcpServerPort{ 10100 }; - + int webSocketPort{ 10110 }; //坐标标定 QPoint point1;//标定点 1 @@ -97,6 +97,10 @@ public: double pointXOffset{ 0 };//物理标点横向偏移 double pointYOffset{ 0 };//物理标点纵向偏移 int pointCircle{ 20 };//标定点 直径 + + bool bRunBackRunning{ true };//启动是自动后台运行 + bool bRunBackClosing{ false };//关闭页面时自动后台运行 + QString strSysTitle;//系统标题 }; #endif diff --git a/tpvs17/Enchanter/Enchanter.vcxproj b/tpvs17/Enchanter/Enchanter.vcxproj index ad3e449..30b0e78 100644 --- a/tpvs17/Enchanter/Enchanter.vcxproj +++ b/tpvs17/Enchanter/Enchanter.vcxproj @@ -53,8 +53,8 @@ true - UNICODE;_UNICODE;WIN32;WIN64;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WEBSOCKETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtNetworkAuth;$(QTDIR)\include\QtWebSockets;%(AdditionalIncludeDirectories) Disabled ProgramDatabase MultiThreadedDebugDLL @@ -65,13 +65,13 @@ $(SolutionDir)..\runner17\$(TargetName)$(TargetExt) $(QTDIR)\lib;%(AdditionalLibraryDirectories) true - qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) + qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5Locationd.lib;Qt5Networkd.lib;Qt5NetworkAuthd.lib;Qt5WebSocketsd.lib;%(AdditionalDependencies) .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp Moc'ing %(Identity)... - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) - UNICODE;_UNICODE;WIN32;WIN64;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtNetworkAuth;$(QTDIR)\include\QtWebSockets;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WEBSOCKETS_LIB;%(PreprocessorDefinitions) Uic'ing %(Identity)... @@ -85,8 +85,8 @@ true - UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WEBSOCKETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtNetworkAuth;$(QTDIR)\include\QtWebSockets;%(AdditionalIncludeDirectories) MultiThreadedDLL true @@ -96,13 +96,13 @@ $(SolutionDir)..\runner17\$(TargetName)$(TargetExt) $(QTDIR)\lib;%(AdditionalLibraryDirectories) false - qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies) + qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5Location.lib;Qt5Network.lib;Qt5NetworkAuth.lib;Qt5WebSockets.lib;%(AdditionalDependencies) .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp Moc'ing %(Identity)... - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) - UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtNetworkAuth;$(QTDIR)\include\QtWebSockets;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WEBSOCKETS_LIB;%(PreprocessorDefinitions) Uic'ing %(Identity)... @@ -115,6 +115,7 @@ + @@ -126,6 +127,10 @@ + + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets + diff --git a/tpvs17/Enchanter/Enchanter.vcxproj.filters b/tpvs17/Enchanter/Enchanter.vcxproj.filters index 368c4db..7444de7 100644 --- a/tpvs17/Enchanter/Enchanter.vcxproj.filters +++ b/tpvs17/Enchanter/Enchanter.vcxproj.filters @@ -33,11 +33,17 @@ Source Files + + Source Files + Header Files + + Header Files + diff --git a/tpvs17/Enchanter/QSignleApplication.cpp b/tpvs17/Enchanter/QSignleApplication.cpp new file mode 100644 index 0000000..c8cc39e --- /dev/null +++ b/tpvs17/Enchanter/QSignleApplication.cpp @@ -0,0 +1,105 @@ +#include "QSignleApplication.h" + +#include +#include +#include +#include +#include + +#pragma execution_character_set("utf-8") +SingleApplication::SingleApplication(int &args, char **argv, QString strServerName) : + QApplication(args, argv), + instanceRunning(false), + localServer(NULL), + mainWindow(NULL) +{ + /** + * һ˵ȡóΪ localServer Ľ̷ + * ĿǰĽǸļģһڸļôͲ׼ȷˣ + * ͨļжǽ̷DzɿģӦдڴ + */ + // serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); + //m_serverName = strServerName; + m_serverName = applicationName(); + initLocalConnection(); +} + +void SingleApplication::initLocalConnection() +{ + instanceRunning = false; + QLocalSocket socket; + //׽̷񣬲Ϊ̷ + socket.connectToServer(m_serverName); + //500ms̷˵̷ + if (socket.waitForConnected(500)) { + instanceRunning = true; + + // 磺͵̷ + QTextStream stream(&socket); + QStringList args = QCoreApplication::arguments(); + if (args.count() > 1) + stream << args.last(); + else + stream << QString(); + stream.flush(); + socket.waitForBytesWritten(); + return; + } + newLocalServer();//ӲϽ̷ʹһ +} +//////////////////////////////////////////////////////////////////////////////// +// ˵ +// LocalServer +//////////////////////////////////////////////////////////////////////////////// +void SingleApplication::newLocalServer() +{ + localServer = new QLocalServer(this); + connect(localServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection())); + if (!localServer->listen(m_serverName)) { + // ʱʧܣdzʱ,̷µ,Ƴ֮ + if (localServer->serverError() == QAbstractSocket::AddressInUseError) { + QLocalServer::removeServer(m_serverName); //Ƴ̷ + localServer->listen(m_serverName); //ٴμ + } + } +} + +void SingleApplication::newLocalConnection() +{ + //̷񣬵ݽʱͨ nextPendingConnection() ȡ׽ + QLocalSocket *socket = localServer->nextPendingConnection(); + if (!socket) + return; + socket->waitForReadyRead(1000); + // + QTextStream stream(socket); + delete socket; + if (mainWindow != NULL) { + //ڶΪʱ˵пڱˣҪչʾ棬ͬʱûʾ + mainWindow->raise(); + mainWindow->activateWindow(); + mainWindow->setWindowState((mainWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + mainWindow->show(); + //QMessageBox::warning(NULL, "", "Ѿ"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// ˵ +// Ƿһʵ, true - ʵУ false - ûʵ +//////////////////////////////////////////////////////////////////////////////// +bool SingleApplication::getInstanceRunning() const +{ + return instanceRunning; +} + +QMainWindow *SingleApplication::getMainWindow() const +{ + return mainWindow; +} + +void SingleApplication::setMainWindow(QMainWindow *value) +{ + mainWindow = value; +} + diff --git a/tpvs17/Enchanter/QSignleApplication.h b/tpvs17/Enchanter/QSignleApplication.h new file mode 100644 index 0000000..1ca30b2 --- /dev/null +++ b/tpvs17/Enchanter/QSignleApplication.h @@ -0,0 +1,46 @@ +#ifndef _H_QSIGNLEAPPLICATION_H_ +#define _H_QSIGNLEAPPLICATION_H_ + +#include +#include +class QMainWindow; +class QLocalServer; + +class SingleApplication : public QApplication +{ + Q_OBJECT +public: + SingleApplication(int &args, char **argv, QString strServerName); + bool getInstanceRunning() const; // ǷѾʵ + QMainWindow *getMainWindow() const; + + void setMainWindow(QMainWindow *value); + +private slots: + void newLocalConnection(); + +private: + void initLocalConnection(); // ʼ + void newLocalServer(); // + bool instanceRunning{ false }; // ǷѾʵ + QLocalServer *localServer{ nullptr }; // socket Serverڱؽ̼ͨţ + QString m_serverName; // + QMainWindow *mainWindow{ nullptr }; // MainWindowָ +}; +/* +Example: +int main(int argc, char *argv[]){ + SingleApplication a(argc, argv, "lp_report"); + if (!a.getInstanceRunning()) + { + slpsf_mark_report w; + a.setMainWindow(&w); + w.show(); + return a.exec(); + } + return 0; +} +*/ +#endif + + diff --git a/tpvs17/Enchanter/main.cpp b/tpvs17/Enchanter/main.cpp index 8e40f53..2499b46 100644 --- a/tpvs17/Enchanter/main.cpp +++ b/tpvs17/Enchanter/main.cpp @@ -2,14 +2,18 @@ #include #include "IMainWidget.h" #include +#include "QSignleApplication.h" #pragma execution_character_set("utf-8") int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication a(argc, argv); IMainWidget* pMain = nullptr; QWidget* pMainWid = nullptr; + + SingleApplication a(argc, argv, "mainApp"); + if (!a.getInstanceRunning()) { + #ifdef _DEBUG QLibrary lib("lpMaind"); #else @@ -30,11 +34,14 @@ int main(int argc, char *argv[]) else { QMessageBox::information(0, "", QObject::tr("lpMainʧ")); } + if (pMain) { delete pMain; pMain = nullptr; } + if (lib.isLoaded()) lib.unload(); + } return 0; } diff --git a/tpvs17/tpAlgorithmQt/tpAlgorithmQt.vcxproj b/tpvs17/tpAlgorithmQt/tpAlgorithmQt.vcxproj index a0b0520..bb27429 100644 --- a/tpvs17/tpAlgorithmQt/tpAlgorithmQt.vcxproj +++ b/tpvs17/tpAlgorithmQt/tpAlgorithmQt.vcxproj @@ -75,10 +75,10 @@ UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;TPALGORITHMQT_LIB;%(PreprocessorDefinitions);ALGORITHM_EXPORTS;QT_GUI_LIB .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;..\..\3part\tadpole\include\tpBase;..\..\3part\opencv3.4.1\include;..\..\3part\opencv3.4.1\include\opencv;..\..\3part\opencv3.4.1\include\opencv2;..\..\3part\libzkq\include;..\..\3part\libzkq\include\syswin;..\..\3part\Cyclops\include;..\..\3part\edcircle\include;..\..\src\interface;%(AdditionalIncludeDirectories) - - + ProgramDatabase MultiThreadedDLL true + Disabled Windows diff --git a/tpvs17/tpMain/lpMainWin.cpp b/tpvs17/tpMain/lpMainWin.cpp index 6d3fe60..83bf3e8 100644 --- a/tpvs17/tpMain/lpMainWin.cpp +++ b/tpvs17/tpMain/lpMainWin.cpp @@ -207,6 +207,8 @@ lpMainWin::lpMainWin(QWidget *parent) ui.tp_main_tabWidget->setCurrentIndex(0); m_pImageCaliUI = new lpImageCaliUI(); + + connect(m_pSystemConfigUI, SIGNAL(sgUpdateInfo()), this, SLOT(setWindowTitleInfo())); } onSetModel(); { @@ -249,10 +251,13 @@ lpMainWin::lpMainWin(QWidget *parent) m_pWebSocket = new WebServer(); //connect(m_pServer, SIGNAL(sgConnected(bool)), this, SLOT(onConnected(bool))); //connect(m_pServer, SIGNAL(sgClientInfo(QString, int, bool)), this, SLOT(onClientInfo(QString, int, bool))); - + + int port = lpGlobalConfig::instance()->webSocketPort; RecvFunc func = std::bind(&lpMainWin::onWebSocketRecvData, this, std::placeholders::_1, std::placeholders::_2); - m_pWebSocket->openServer(10110, func); + m_pWebSocket->openServer(port, func); } + + setWindowTitleInfo(); } lpMainWin::~lpMainWin() @@ -550,6 +555,7 @@ void lpMainWin::IVariantMapToUI(const QString& camKey, const QVariantMap& vMap) (2)执行定位算法,解析定位算法的结果 */ + pResult->m_pixSrc = QPixmap::fromImage(srcImg); if (!pResult->m_strModel.isEmpty()) { ui.main_value_Result->setText("定位中"); @@ -568,6 +574,9 @@ void lpMainWin::IVariantMapToUI(const QString& camKey, const QVariantMap& vMap) valueRlt.angle = 361; valueRlt.strModel = "NG"; valueRlt.score = 0; + int h = srcImg.height(); + int w = srcImg.width(); + uchar* p = srcImg.bits(); if(!srcImg.isNull()) valueRlt.pixmap = QPixmap::fromImage(srcImg); valueRlt.strRunState = "no task"; @@ -816,14 +825,13 @@ void lpMainWin::IEngineResult(QVariantMap vMap) void lpMainWin::showWidget() { - if (m_showMode == 1) + if (lpGlobalConfig::instance()->bRunBackRunning == false) { setMainWindowVisibility(true); } else { setMainWindowVisibility(false); - } - + } } Q_SLOT void lpMainWin::onLogInOut(QString strName, int level, int state) @@ -1081,10 +1089,13 @@ void lpMainWin::timerEvent(QTimerEvent *event) void lpMainWin::closeEvent(QCloseEvent *event) { - if (m_bExit == false) + if (lpGlobalConfig::instance()->bRunBackClosing == true) { - setMainWindowVisibility(false); - return event->ignore(); + if (m_bExit == false) + { + setMainWindowVisibility(false); + return event->ignore(); + } } return event->accept(); } @@ -1275,26 +1286,26 @@ Q_SLOT void lpMainWin::onTriggerCam() void lpMainWin::onInitAbout() { - QString aboutString; - aboutString = QString( - "

%1

" - "

%2.

" - "

%3:www.hzleaper.com

" - "

%4:%5

" - "

%6:%7

" - "

%8:%9

" - "

" - ).arg(tr("轮毂型号识别系统")) - .arg(tr("本软件由杭州利珀科技开发,用于轮毂型号识别和分类,可搭配流水线运输系统使用")) - .arg(tr("若需要进一步了解该产品的相关信息,请访问我们的网站")) - .arg(tr("软件版本")).arg(VERSION_HUB) - .arg(tr("算法版本")).arg(VERSION_ALG) - .arg(tr("最后更新时间")).arg(UPDATE_TIME) - .arg(tr("版权 (c) 属 杭州利珀科技有限公司 所有")); +// QString aboutString; +// aboutString = QString( +// "

%1

" +// "

%2.

" +// "

%3:www.hzleaper.com

" +// "

%4:%5

" +// "

%6:%7

" +// "

%8:%9

" +// "

" +// ).arg(tr("轮毂型号识别系统")) +// .arg(tr("本软件由杭州利珀科技开发,用于轮毂型号识别和分类,可搭配流水线运输系统使用")) +// .arg(tr("若需要进一步了解该产品的相关信息,请访问我们的网站")) +// .arg(tr("软件版本")).arg(VERSION_HUB) +// .arg(tr("算法版本")).arg(VERSION_ALG) +// .arg(tr("最后更新时间")).arg(UPDATE_TIME) +// .arg(tr("版权 (c) 属 杭州利珀科技有限公司 所有")); m_aboutDlg.setFixedSize(500, 300); QTextEdit* pEdit = new QTextEdit(&m_aboutDlg); pEdit->setReadOnly(true); - pEdit->append(aboutString); + pEdit->append("11"); pEdit->setAttribute(Qt::WA_TranslucentBackground, true); QPalette pl = pEdit->palette(); pl.setBrush(QPalette::Base, QBrush(QColor(255, 0, 0, 0))); @@ -1473,6 +1484,13 @@ bool lpMainWin::readExposureTimeConfig(const QString& strPath) if (jsonObj.empty()) { qDebug() << "Json file parsing failed!"; + + QJsonObject rootObj; + QJsonArray exposttime; + exposttime.append("1000"); + rootObj.insert("exposureTime", exposttime); + rootObj.insert("switch", 0); + QZkJsonParser::WriteJsonObject(filePath, rootObj); return false; } @@ -1517,7 +1535,7 @@ Result2Ui *lpMainWin::parseMap(const QVariantMap &vMap) pRes->m_dScore = vMap.value("score").toDouble(); pRes->m_dDiameter = vMap.value("diameter").toDouble(); pRes->m_dThickness = vMap.value("thickness").toDouble(); - pRes->m_pixSrc = QPixmap::fromImage(vMap.value("pixSrc").value()); + pRes->m_pixResult = QPixmap::fromImage(vMap.value("pixResult").value()); pRes->m_dRunTime = vMap.value("runTime").toDouble(); return pRes; @@ -1671,6 +1689,14 @@ Q_SLOT void lpMainWin::onWebSocketRecvData(QWebSocket* p, QByteArray data) { this->show(); } + else if (strcmd == "hideWidget") + { + + } + else if (strcmd == "exitApp") + { + onQuitApplication(); + } } } @@ -1737,7 +1763,7 @@ void lpMainWin::setupTrayIcon() m_trayIcon->setIcon(icon); m_trayIcon->setContextMenu(m_trayIconMenu); m_trayIcon->show(); - + connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(onActivated(QSystemTrayIcon::ActivationReason))); connect(m_restoreAction, &QAction::triggered, this, [this]() { setMainWindowVisibility(isHidden() @@ -1758,7 +1784,8 @@ Q_SLOT void lpMainWin::onActivated(QSystemTrayIcon::ActivationReason reason) void lpMainWin::setMainWindowVisibility(bool state) { if (state) { - show(); + //show(); + showMaximized(); qApp->processEvents(); qApp->setActiveWindow(this); qApp->processEvents(); @@ -1775,3 +1802,14 @@ Q_SLOT void lpMainWin::onQuitApplication() m_bExit = true; lpMainWin::close(); } + +Q_SLOT void lpMainWin::setWindowTitleInfo() +{ + setWindowTitle(lpGlobalConfig::instance()->strSysTitle); + ui.m_winTitle->setText(lpGlobalConfig::instance()->strSysTitle); + if (m_trayIcon) + { + m_trayIcon->setToolTip(lpGlobalConfig::instance()->strSysTitle); + } +} + diff --git a/tpvs17/tpMain/lpMainWin.h b/tpvs17/tpMain/lpMainWin.h index f3f75a5..ea4f3f8 100644 --- a/tpvs17/tpMain/lpMainWin.h +++ b/tpvs17/tpMain/lpMainWin.h @@ -116,13 +116,13 @@ protected: void sendWebAlgRlt(const ValueResult& rlt); QJsonObject byte2Json(QByteArray data); QByteArray Json2byte(QJsonObject obj); + Q_SLOT void setWindowTitleInfo(); - +private://trayIcon void setupTrayIcon(); Q_SLOT void onActivated(QSystemTrayIcon::ActivationReason reason); void setMainWindowVisibility(bool state); Q_SLOT void onQuitApplication(); - private: void onShowResult(Result2Ui* pRlt);//展示识别结果 void saveValveImage(QImage image, QString strName = "NG"); diff --git a/tpvs17/tpMain/lpMainWin.ui b/tpvs17/tpMain/lpMainWin.ui index cf3c0a6..a231cb8 100644 --- a/tpvs17/tpMain/lpMainWin.ui +++ b/tpvs17/tpMain/lpMainWin.ui @@ -7,7 +7,7 @@ 0 0 1026 - 675 + 704 @@ -107,7 +107,7 @@ 0 - + true @@ -219,6 +219,18 @@ + + + + 18 + 75 + true + + + + 识别定位检测 + + @@ -772,8 +784,6 @@ font: 75 24pt "Consolas"; false - - diff --git a/tpvs17/tpMain/lpSystemConfigUI.cpp b/tpvs17/tpMain/lpSystemConfigUI.cpp index 79cf49d..1db771c 100644 --- a/tpvs17/tpMain/lpSystemConfigUI.cpp +++ b/tpvs17/tpMain/lpSystemConfigUI.cpp @@ -36,11 +36,19 @@ Q_SLOT void lpSystemConfigUI::onButtonClicked() lpGlobalConfig::instance()->bSaveSrcNGImg_value = ui.checkBox_saveValue_NGSrcImg->isChecked();//λ lpGlobalConfig::instance()->m_SaveImgDirPath = ui.lineEdit->text(); lpGlobalConfig::instance()->tcpServerPort = ui.lineEdit_2->text().toInt(); + lpGlobalConfig::instance()->webSocketPort = ui.lineEdit_3->text().toInt(); + lpGlobalConfig::instance()->bRunBackRunning = ui.checkBox_runBackRunning->isChecked(); + lpGlobalConfig::instance()->bRunBackClosing = ui.checkBox_runBackClosing->isChecked(); + lpGlobalConfig::instance()->strSysTitle = ui.lineEdit_4->text(); lpGlobalConfig::instance()->saveDeteImage(); QString strLanguage = ui.comboBox->currentText(); QSettings languageSetting("hubdetect.ini", QSettings::IniFormat); languageSetting.setValue("language", strLanguage); + + ui.m_label_SaveInfo->setVisible(true); + m_timerID = startTimer(1000); + emit sgUpdateInfo(); } else if (strObj == "m_pbExit") { this->close(); @@ -56,6 +64,7 @@ Q_SLOT void lpSystemConfigUI::onButtonClicked() void lpSystemConfigUI::showEvent(QShowEvent *event) { + ui.m_label_SaveInfo->setVisible(false); ui.checkBox_saveNGCutImg->setChecked(lpGlobalConfig::instance()->bSaveCutNGImg);//ʶ ui.checkBox_saveOKCutImg->setChecked(lpGlobalConfig::instance()->bSaveCutOKImg);//ʶ ui.checkBox_saveNGSrcImg->setChecked(lpGlobalConfig::instance()->bSaveSrcNGImg);//ʶ @@ -63,6 +72,12 @@ void lpSystemConfigUI::showEvent(QShowEvent *event) ui.checkBox_saveValue_OKSrcImg->setChecked(lpGlobalConfig::instance()->bSaveSrcOKImg_value);//λ ui.checkBox_saveValue_NGSrcImg->setChecked(lpGlobalConfig::instance()->bSaveSrcNGImg_value);//λ ui.lineEdit_2->setText(QString("%1").arg(lpGlobalConfig::instance()->tcpServerPort)); + ui.lineEdit_3->setText(QString("%1").arg(lpGlobalConfig::instance()->webSocketPort)); + + ui.checkBox_runBackRunning->setChecked(lpGlobalConfig::instance()->bRunBackRunning); + ui.checkBox_runBackClosing->setChecked(lpGlobalConfig::instance()->bRunBackClosing); + ui.lineEdit_4->setText(lpGlobalConfig::instance()->strSysTitle); + ui.lineEdit->setText(lpGlobalConfig::instance()->m_SaveImgDirPath); QSettings languageSetting("hubdetect.ini", QSettings::IniFormat); @@ -70,3 +85,15 @@ void lpSystemConfigUI::showEvent(QShowEvent *event) ui.comboBox->setCurrentText(strLanguage); } +void lpSystemConfigUI::timerEvent(QTimerEvent *event) +{ + if (m_timerID == event->timerId()) + { + killTimer(m_timerID); + m_timerID = 0; + ui.m_label_SaveInfo->setVisible(false); + } + +} + + diff --git a/tpvs17/tpMain/lpSystemConfigUI.h b/tpvs17/tpMain/lpSystemConfigUI.h index eccbf4c..4a48ec2 100644 --- a/tpvs17/tpMain/lpSystemConfigUI.h +++ b/tpvs17/tpMain/lpSystemConfigUI.h @@ -11,11 +11,15 @@ class lpSystemConfigUI : public QWidget public: lpSystemConfigUI(QWidget *parent = Q_NULLPTR); ~lpSystemConfigUI(); +signals: + void sgUpdateInfo(); protected: Q_SLOT void onButtonClicked(); virtual void showEvent(QShowEvent *event); + virtual void timerEvent(QTimerEvent *event); private: Ui::lpSystemConfigUI ui; + int m_timerID{ 0 }; }; #endif diff --git a/tpvs17/tpMain/lpSystemConfigUI.ui b/tpvs17/tpMain/lpSystemConfigUI.ui index c3d735d..36b6bec 100644 --- a/tpvs17/tpMain/lpSystemConfigUI.ui +++ b/tpvs17/tpMain/lpSystemConfigUI.ui @@ -6,8 +6,8 @@ 0 0 - 538 - 459 + 597 + 500 @@ -29,8 +29,8 @@ 0 0 - 518 - 407 + 577 + 448 @@ -162,7 +162,7 @@ - + Qt::Horizontal @@ -175,10 +175,37 @@ + + + + + + webSocket端口: + + + + + + + + + + + + Qt::Horizontal + + + + 235 + 20 + + + + - + Qt::Vertical @@ -191,12 +218,60 @@ + + + + 其他: + + + + + + + + 本系统标题: + + + + + + + + + + + + + + 启动时默认后台运行 + + + + + + + 关闭主窗口时在后台运行 + + + + + + + + + + + + 系统参数已保存且生效!!! + + + diff --git a/tpvs17/tpMain/tpMain.vcxproj b/tpvs17/tpMain/tpMain.vcxproj index 854727c..0935b3c 100644 --- a/tpvs17/tpMain/tpMain.vcxproj +++ b/tpvs17/tpMain/tpMain.vcxproj @@ -1230,6 +1230,7 @@ MultiThreadedDLL true + Disabled
Windows diff --git a/tpvs17/tpMain/tpMain.vcxproj.filters b/tpvs17/tpMain/tpMain.vcxproj.filters index af609fa..70f0337 100644 --- a/tpvs17/tpMain/tpMain.vcxproj.filters +++ b/tpvs17/tpMain/tpMain.vcxproj.filters @@ -130,12 +130,6 @@ Generated Files\Release - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug @@ -187,54 +181,18 @@ Generated Files\Release - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug Generated Files\Release - - Generated Files\Debug - - - Generated Files\Release - - - Generated Files\Debug - - - Generated Files\Release - - - Generated Files\Debug - - - Generated Files\Release - - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug Generated Files\Release - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug @@ -265,12 +223,6 @@ Generated Files\Release - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug @@ -292,12 +244,6 @@ Source Files - - Generated Files\Debug - - - Generated Files\Release - sql @@ -373,24 +319,12 @@ UIFile - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug Generated Files\Release - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug @@ -460,12 +394,6 @@ BaseUILib\pulpewidget - - Generated Files\Debug - - - Generated Files\Release - Generated Files\Debug diff --git a/tpvs17/valueMainUI/QSignleApplication.cpp b/tpvs17/valueMainUI/QSignleApplication.cpp new file mode 100644 index 0000000..7b4ee11 --- /dev/null +++ b/tpvs17/valueMainUI/QSignleApplication.cpp @@ -0,0 +1,104 @@ +#include "QSignleApplication.h" + +#include +#include +#include +#include +#include +#pragma execution_character_set("utf-8") +SingleApplication::SingleApplication(int &args, char **argv, QString strServerName) : + QApplication(args, argv), + instanceRunning(false), + localServer(NULL), + mainWindow(NULL) +{ + /** + * һ˵ȡóΪ localServer Ľ̷ + * ĿǰĽǸļģһڸļôͲ׼ȷˣ + * ͨļжǽ̷DzɿģӦдڴ + */ + // serverName = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); + m_serverName = strServerName; + QString a = applicationName(); + initLocalConnection(); +} + +void SingleApplication::initLocalConnection() +{ + instanceRunning = false; + QLocalSocket socket; + //׽̷񣬲Ϊ̷ + socket.connectToServer(m_serverName); + //500ms̷˵̷ + if (socket.waitForConnected(500)) { + instanceRunning = true; + + // 磺͵̷ + QTextStream stream(&socket); + QStringList args = QCoreApplication::arguments(); + if (args.count() > 1) + stream << args.last(); + else + stream << QString(); + stream.flush(); + socket.waitForBytesWritten(); + return; + } + newLocalServer();//ӲϽ̷ʹһ +} +//////////////////////////////////////////////////////////////////////////////// +// ˵ +// LocalServer +//////////////////////////////////////////////////////////////////////////////// +void SingleApplication::newLocalServer() +{ + localServer = new QLocalServer(this); + connect(localServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection())); + if (!localServer->listen(m_serverName)) { + // ʱʧܣdzʱ,̷µ,Ƴ֮ + if (localServer->serverError() == QAbstractSocket::AddressInUseError) { + QLocalServer::removeServer(m_serverName); //Ƴ̷ + localServer->listen(m_serverName); //ٴμ + } + } +} + +void SingleApplication::newLocalConnection() +{ + //̷񣬵ݽʱͨ nextPendingConnection() ȡ׽ + QLocalSocket *socket = localServer->nextPendingConnection(); + if (!socket) + return; + socket->waitForReadyRead(1000); + // + QTextStream stream(socket); + delete socket; + if (mainWindow != NULL) { + //ڶΪʱ˵пڱˣҪչʾ棬ͬʱûʾ + mainWindow->raise(); + mainWindow->activateWindow(); + mainWindow->setWindowState((mainWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); + mainWindow->show(); + //QMessageBox::warning(NULL, "", "Ѿ"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// ˵ +// Ƿһʵ, true - ʵУ false - ûʵ +//////////////////////////////////////////////////////////////////////////////// +bool SingleApplication::getInstanceRunning() const +{ + return instanceRunning; +} + +QMainWindow *SingleApplication::getMainWindow() const +{ + return mainWindow; +} + +void SingleApplication::setMainWindow(QMainWindow *value) +{ + mainWindow = value; +} + diff --git a/tpvs17/valueMainUI/QSignleApplication.h b/tpvs17/valueMainUI/QSignleApplication.h new file mode 100644 index 0000000..1ca30b2 --- /dev/null +++ b/tpvs17/valueMainUI/QSignleApplication.h @@ -0,0 +1,46 @@ +#ifndef _H_QSIGNLEAPPLICATION_H_ +#define _H_QSIGNLEAPPLICATION_H_ + +#include +#include +class QMainWindow; +class QLocalServer; + +class SingleApplication : public QApplication +{ + Q_OBJECT +public: + SingleApplication(int &args, char **argv, QString strServerName); + bool getInstanceRunning() const; // ǷѾʵ + QMainWindow *getMainWindow() const; + + void setMainWindow(QMainWindow *value); + +private slots: + void newLocalConnection(); + +private: + void initLocalConnection(); // ʼ + void newLocalServer(); // + bool instanceRunning{ false }; // ǷѾʵ + QLocalServer *localServer{ nullptr }; // socket Serverڱؽ̼ͨţ + QString m_serverName; // + QMainWindow *mainWindow{ nullptr }; // MainWindowָ +}; +/* +Example: +int main(int argc, char *argv[]){ + SingleApplication a(argc, argv, "lp_report"); + if (!a.getInstanceRunning()) + { + slpsf_mark_report w; + a.setMainWindow(&w); + w.show(); + return a.exec(); + } + return 0; +} +*/ +#endif + + diff --git a/tpvs17/valueMainUI/Resources/Client.png b/tpvs17/valueMainUI/Resources/Client.png new file mode 100644 index 0000000..767c6fa Binary files /dev/null and b/tpvs17/valueMainUI/Resources/Client.png differ diff --git a/tpvs17/valueMainUI/Resources/Setting.png b/tpvs17/valueMainUI/Resources/Setting.png new file mode 100644 index 0000000..95b9e34 Binary files /dev/null and b/tpvs17/valueMainUI/Resources/Setting.png differ diff --git a/tpvs17/valueMainUI/Resources/icon.ico b/tpvs17/valueMainUI/Resources/icon.ico new file mode 100644 index 0000000..a17eecb Binary files /dev/null and b/tpvs17/valueMainUI/Resources/icon.ico differ diff --git a/tpvs17/valueMainUI/Resources/icon.png b/tpvs17/valueMainUI/Resources/icon.png new file mode 100644 index 0000000..987f46e Binary files /dev/null and b/tpvs17/valueMainUI/Resources/icon.png differ diff --git a/tpvs17/valueMainUI/SystemTool.cpp b/tpvs17/valueMainUI/SystemTool.cpp new file mode 100644 index 0000000..01eb26e --- /dev/null +++ b/tpvs17/valueMainUI/SystemTool.cpp @@ -0,0 +1,186 @@ +/*! + *FileName: SystemTool.cpp + *Author: Pan Yingdong + *Email: bob.pan@hzleaper.com + *Created:2020/6/15 15:28 + *Note:ϵͳع ָ +*/ +#include "SystemTool.h" +#include +#include + +#pragma execution_character_set("utf-8") +bool SystemTool::SystemShutDown(bool bReset) +{ + if (bReset == false) + system("shutdown -s -t 00");//ػ + else + system("shutdown -r -t 00");// + return true; +} + +std::string SystemTool::TCHAR2STRING(TCHAR *STR) +{ + + int iLen = WideCharToMultiByte(CP_ACP, 0, STR, -1, NULL, 0, NULL, NULL); + + char* chRtn = new char[iLen * sizeof(char)]; + + WideCharToMultiByte(CP_ACP, 0, STR, -1, chRtn, iLen, NULL, NULL); + + std::string str(chRtn); + + return str; +} + +bool SystemTool::isProcessRunning(const char* processName) +{ + bool bFound = false; + + HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL); + PROCESSENTRY32 pEntry; + pEntry.dwSize = sizeof(pEntry); + BOOL hRes = Process32First(hSnapShot, &pEntry); + while (hRes && !bFound) + { + char* exename = UnicodeToAnsi(pEntry.szExeFile); + QString strExeName(exename); + if (strExeName.compare(processName, Qt::CaseInsensitive) == 0) + { + bFound = true; + } + delete exename; + + hRes = Process32Next(hSnapShot, &pEntry); + } + + return bFound; +} + +void SystemTool::GetProcessPath(DWORD dwProcessID, TCHAR* buffer) +{ + TCHAR Filename[MAX_PATH]; + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID); + if (hProcess == NULL)return; + HMODULE hModule; + DWORD cbNeeded; + if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded)) + { + if (GetModuleFileNameEx(hProcess, hModule, Filename, MAX_PATH)) { + RtlMoveMemory((void*)buffer, Filename, sizeof(TCHAR)*MAX_PATH); + } + } + else { + DWORD size = MAX_PATH; + if (QueryFullProcessImageName(hProcess, 0, Filename, &size)) { + RtlMoveMemory((void*)buffer, Filename, sizeof(TCHAR)*MAX_PATH); + } + } + CloseHandle(hProcess); +} + +std::vector SystemTool::getPIDByName(const char* processName) +{ + std::vector vecRet; + + HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL); + PROCESSENTRY32 pEntry; + pEntry.dwSize = sizeof(pEntry); + BOOL hRes = Process32First(hSnapShot, &pEntry); + while (hRes) + { + char* exename = SystemTool::UnicodeToAnsi(pEntry.szExeFile); + QString strExeName(exename); + if (strExeName.compare(processName, Qt::CaseInsensitive) == 0) + { + TCHAR appPath[MAX_PATH]; + SystemTool::GetProcessPath((DWORD)pEntry.th32ProcessID, appPath); + + std::string texts = SystemTool::TCHAR2STRING(appPath); +// QFileInfo appFile(texts.c_str()); +// QString strAppPath = appFile.absoluteFilePath(); +// if (strAppPath.compare(curAppPath, Qt::CaseInsensitive) == 0) + { + vecRet.push_back((DWORD)pEntry.th32ProcessID); + } + } + delete exename; + hRes = Process32Next(hSnapShot, &pEntry); + } + CloseHandle(hSnapShot); + + return vecRet; + +} + +void SystemTool::killZombieProcess(const char *curAppName) +{ + std::vector PIDs = getPIDByName(curAppName); + + for (int i = 0; i < PIDs.size(); ++i) + { + DWORD pid = PIDs.at(i); + +// QString strCmd = QString("taskkill /PID %1 -t -f").arg(pid); +// system(strCmd.toStdString().c_str()); + //if (pid != curAppPID) + { + HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pid); + if (hProcess != NULL) + { + TerminateProcess(hProcess, 9); + CloseHandle(hProcess); + } + } + } +} + +QString SystemTool::SecondTimeString(quint64 value) +{ + QString strTime; + int seconds = value % 60; + int minutes = value / 60; + strTime = QString("%1%2").arg(minutes).arg(seconds); + if (minutes >= 60) { + minutes = (value / 60) % 60; + int hours = (value / 60) / 60; + strTime = QString("%1ʱ%2%3").arg(hours).arg(minutes).arg(seconds); + if (hours >= 24) { + hours = ((value / 60) / 60) % 24; + int day = ((value / 60) / 60) / 24; + strTime = QString("%1%2ʱ%3%4").arg(day).arg(hours).arg(minutes).arg(seconds); + } + } + return strTime; +} + +void SystemTool::ReflashBarIcon() +{ +// HWND hShellTrayWnd = FindWindow("Shell_TrayWnd", NULL); +// //ұͼ+ʱ +// HWND hTrayNotifyWnd = FindWindowEx(hShellTrayWnd, 0, "TrayNotifyWnd", NULL); +// //ͬϵͳпû +// HWND hSysPager = FindWindowEx(hTrayNotifyWnd, 0, "SysPager", NULL); +// //ͼ괰 +// HWND hToolbarWindow32; +// if (hSysPager) +// { +// hToolbarWindow32 = FindWindowEx(hSysPager, 0, "ToolbarWindow32", NULL); +// } +// else +// { +// hToolbarWindow32 = FindWindowEx(hTrayNotifyWnd, 0, "ToolbarWindow32", NULL); +// } +// if (hToolbarWindow32) +// { +// RECT r; +// ::GetWindowRect(hToolbarWindow32, &r); +// int width = r.right - r.left; +// int height = r.bottom - r.top; +// //м MOUSEMOVEһ飬ͼ״̬ᱻ +// for (int x = 1; x < width; x++) +// { +// ::SendMessage(hToolbarWindow32, WM_MOUSEMOVE, 0, MAKELPARAM(x, height / 2)); +// } +// } +} \ No newline at end of file diff --git a/tpvs17/valueMainUI/SystemTool.h b/tpvs17/valueMainUI/SystemTool.h new file mode 100644 index 0000000..08030ad --- /dev/null +++ b/tpvs17/valueMainUI/SystemTool.h @@ -0,0 +1,50 @@ +/*! + *FileName: SystemTool.h + *Author: Pan Yingdong + *Email: bob.pan@hzleaper.com + *Created:2020/6/15 15:14 + *Note: +*/ +#ifndef _H_SYSTEMTOOL_H_ +#define _H_SYSTEMTOOL_H_ +#include +#include +#include +#include +#include +#include +#define PSAPI_VERSION 1 +#include +#pragma comment(lib,"psapi.lib") + +#include +#include +namespace SystemTool +{/*bReset == true ; false ػ*/ + bool SystemShutDown(bool bReset); + inline char* UnicodeToAnsi(const wchar_t* szStr) + { + int nLen = WideCharToMultiByte(CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL); + if (nLen == 0) + { + return NULL; + } + char* pResult = new char[nLen]; + WideCharToMultiByte(CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL); + return pResult; + } + std::string TCHAR2STRING(TCHAR *STR); + bool isProcessRunning(const char* processName); + + void GetProcessPath(DWORD dwProcessID, TCHAR* buffer); + + std::vector getPIDByName(const char* processName); + void killZombieProcess(const char *curAppName); + + QString SecondTimeString(quint64 value); + void ReflashBarIcon(); +} + + +#endif + diff --git a/tpvs17/valueMainUI/config.ini b/tpvs17/valueMainUI/config.ini new file mode 100644 index 0000000..8526949 --- /dev/null +++ b/tpvs17/valueMainUI/config.ini @@ -0,0 +1,5 @@ +[General] +urlA=ws://localhost:10110 +urlB=ws://localhost:10111 +appPathA=E:/wheelValve/runner17/Enchanter.exe +appPathB=E:/wheelValve/runner17/lpReportd.exe diff --git a/tpvs17/valueMainUI/lpConfig.cpp b/tpvs17/valueMainUI/lpConfig.cpp index d2ed0e7..93263d2 100644 --- a/tpvs17/valueMainUI/lpConfig.cpp +++ b/tpvs17/valueMainUI/lpConfig.cpp @@ -14,10 +14,19 @@ void lpConfig::saveConfig() { QSettings setting("config.ini", QSettings::IniFormat); - + setting.setValue("urlA", strUrlA); + setting.setValue("urlB", strUrlB); + setting.setValue("appPathA", appPathA); + setting.setValue("appPathB", appPathB); + setting.setValue("doubleStation", doubleStation); } void lpConfig::loadConfig() { QSettings setting("config.ini", QSettings::IniFormat); + strUrlA = setting.value("urlA", "ws://localhost:10110").toString(); + strUrlB = setting.value("urlB", "ws://localhost:10111").toString(); + appPathA = setting.value("appPathA").toString(); + appPathB = setting.value("appPathB").toString(); + doubleStation = setting.value("doubleStation",true).toBool(); } diff --git a/tpvs17/valueMainUI/lpConfig.h b/tpvs17/valueMainUI/lpConfig.h index 08e4b83..9f7a05f 100644 --- a/tpvs17/valueMainUI/lpConfig.h +++ b/tpvs17/valueMainUI/lpConfig.h @@ -16,6 +16,9 @@ public: public: QString strUrlA{ "ws://localhost:10110" };//A๤λwebsocket QString strUrlB{ "ws://localhost:10110" }; + QString appPathA; + QString appPathB; + bool doubleStation{ true }; }; #endif \ No newline at end of file diff --git a/tpvs17/valueMainUI/lpConfigUI.cpp b/tpvs17/valueMainUI/lpConfigUI.cpp index 8fea705..0e1d14e 100644 --- a/tpvs17/valueMainUI/lpConfigUI.cpp +++ b/tpvs17/valueMainUI/lpConfigUI.cpp @@ -1,11 +1,27 @@ #include "lpConfigUI.h" +#include +#include +#include +#include + +#pragma execution_character_set("utf-8") +/*ϵͳҳ*/ +const QString gStrAppName = "ʶλϵͳ"; lpConfigUI::lpConfigUI(QWidget *parent) : QWidget(parent) { ui.setupUi(this); + setWindowIcon(QIcon(":/Resources/icon.png")); + connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + connect(ui.pushButton_3, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + connect(ui.pushButton_4, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + ui.label_5->setVisible(false); - + onInitCheckBox(); + connect(ui.checkBox_AutoRun, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxChanged(int))); + connect(ui.checkBox_DesktopShort, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxChanged(int))); } lpConfigUI::~lpConfigUI() @@ -14,10 +30,183 @@ lpConfigUI::~lpConfigUI() Q_SLOT void lpConfigUI::onButtonClicked() { - + QString strObj = sender()->objectName(); + if ("pushButton" == strObj) + { + QString strUrl = QFileDialog::getOpenFileName(this, "", "", "*.exe"); + ui.lineEdit_APath->setText(strUrl); + } + else if ("pushButton_2" == strObj) + { + QString strUrl = QFileDialog::getOpenFileName(this, "", "", "*.exe"); + ui.lineEdit_BPath->setText(strUrl); + } + else if ("pushButton_3" == strObj) + { + lpConfig::instance()->appPathA = ui.lineEdit_APath->text(); + lpConfig::instance()->appPathB = ui.lineEdit_BPath->text(); + lpConfig::instance()->strUrlA = ui.lineEdit_AUrl->text(); + lpConfig::instance()->strUrlB = ui.lineEdit_BUrl->text(); + lpConfig::instance()->saveConfig(); + ui.label_5->setVisible(true); + m_timerID = startTimer(1000); + } + else if ("pushButton_4" == strObj) + { + this->close(); + } } void lpConfigUI::showEvent(QShowEvent *event) { + ui.lineEdit_APath->setText(lpConfig::instance()->appPathA); + ui.lineEdit_BPath->setText(lpConfig::instance()->appPathB); + ui.lineEdit_AUrl->setText(lpConfig::instance()->strUrlA); + ui.lineEdit_BUrl->setText(lpConfig::instance()->strUrlB); +} + +void lpConfigUI::timerEvent(QTimerEvent *event) +{ + if (m_timerID == event->timerId()) + { + killTimer(m_timerID); + m_timerID = 0; + ui.label_5->setVisible(false); + } +} + +void lpConfigUI::onInitCheckBox() +{ + bool bAutoRun = CheckAutoRunLink(); + if (bAutoRun == true) + { + ui.checkBox_AutoRun->setChecked(true); + } + else { + ui.checkBox_AutoRun->setChecked(false); + } + + bool bDesktop = CheckDesktopLink(); + if (bDesktop == true) + { + ui.checkBox_DesktopShort->setChecked(true); + } + else + { + ui.checkBox_DesktopShort->setChecked(false); + } +} + +Q_SLOT void lpConfigUI::onCheckBoxChanged(int state) +{ + QString strObj = sender()->objectName(); + if ("checkBox_AutoRun" == strObj) + { + if (state == 0) + { + RemoveAutoRunLink(); + } + else { + CreateAutoRunLink(); + } + } + else if ("checkBox_DesktopShort" == strObj) + { + if (state == 0) + { + RemoveDesktopLink(); + } + else { + CreateDesktopLink(); + } + } +} + +bool lpConfigUI::CheckDesktopLink() +{ + QString strDesktopLink = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/"; + strDesktopLink += gStrAppName + ".lnk"; + QFileInfo dir(strDesktopLink); + return dir.isFile(); +} + +void lpConfigUI::CreateDesktopLink() +{ + QString strAppPath = QCoreApplication::applicationFilePath();//ҪݷʽӦó· + QFile fApp(strAppPath); + + //ݷʽ + QString strDesktopLink = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/"; + strDesktopLink += gStrAppName + ".lnk"; + QFileInfo dir(strDesktopLink); + //if (!dir.isFile()) + { + fApp.link(strDesktopLink); + } +} + +void lpConfigUI::RemoveDesktopLink() +{ + QString strAppPath = QCoreApplication::applicationFilePath();//ҪݷʽӦó· + QFile fApp(strAppPath); + + //ݷʽ + QString strDesktopLink = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/"; + strDesktopLink += gStrAppName + ".lnk"; + QFileInfo dir(strDesktopLink); + //if (!dir.isFile()) + { + fApp.remove(strDesktopLink); + } +} + +bool lpConfigUI::CheckAutoRunLink() +{ + QString strMenuLink = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/"; + strMenuLink += "Startup/"; + QDir pathDir; + pathDir.mkpath(strMenuLink); + strMenuLink += gStrAppName + ".lnk"; + //жǷѴ + QFileInfo dir(strMenuLink); + return dir.isFile(); +} +void lpConfigUI::CreateAutoRunLink() +{ + QString strAppPath = QCoreApplication::applicationFilePath();//ҪݷʽӦó· + QFile fApp(strAppPath); + //ݷʽ + QString strMenuLink = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/"; + strMenuLink += "Startup/"; + QDir pathDir; + pathDir.mkpath(strMenuLink); + strMenuLink += gStrAppName + ".lnk"; + //жǷѴ + QFileInfo dir(strMenuLink); + //if (!dir.isFile()) + { + fApp.link(strMenuLink); + } +} + +void lpConfigUI::RemoveAutoRunLink() +{ + QString strAppPath = QCoreApplication::applicationFilePath();//ҪݷʽӦó· + QFile fApp(strAppPath); + QString strMenuLink = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/"; + strMenuLink += "Startup/"; + QDir pathDir; + pathDir.mkpath(strMenuLink); + strMenuLink += gStrAppName + ".lnk"; + //жǷѴ + QFileInfo dir(strMenuLink); + //if (!dir.isFile()) + { + fApp.remove(strMenuLink); + } } + + + + diff --git a/tpvs17/valueMainUI/lpConfigUI.h b/tpvs17/valueMainUI/lpConfigUI.h index 0b5bedc..c424193 100644 --- a/tpvs17/valueMainUI/lpConfigUI.h +++ b/tpvs17/valueMainUI/lpConfigUI.h @@ -12,12 +12,27 @@ public: lpConfigUI(QWidget *parent = Q_NULLPTR); ~lpConfigUI(); +protected: Q_SLOT void onButtonClicked(); virtual void showEvent(QShowEvent *event); + virtual void timerEvent(QTimerEvent *event); +private: + void onInitCheckBox(); + Q_SLOT void onCheckBoxChanged(int state); + +private: + bool CheckDesktopLink(); + void CreateDesktopLink(); + void RemoveDesktopLink(); + bool CheckAutoRunLink(); + void CreateAutoRunLink(); + void RemoveAutoRunLink(); private: Ui::lpConfigUI ui; + + int m_timerID{ 0 }; }; #endif diff --git a/tpvs17/valueMainUI/lpConfigUI.ui b/tpvs17/valueMainUI/lpConfigUI.ui index 4bddab3..cfed3fa 100644 --- a/tpvs17/valueMainUI/lpConfigUI.ui +++ b/tpvs17/valueMainUI/lpConfigUI.ui @@ -6,39 +6,238 @@ 0 0 - 628 - 444 + 545 + 303 lpConfigUI - - - - 360 - 30 - 75 - 23 - - - - PushButton - - - - - - 20 - 20 - 111 - 16 - - - - A侧检测所在目录: - - + + + + + + + + + + + + + + 12 + + + + A侧检测所在路径: + + + + + + + + 12 + + + + + + + + + 12 + + + + 设置 + + + + + + + + + + + + 12 + + + + A侧检测通讯链接: + + + + + + + + 12 + + + + + + + + + + + + + 12 + + + + B侧检测所在路径: + + + + + + + + 12 + + + + + + + + + 12 + + + + 设置 + + + + + + + + + + + + 12 + + + + B侧检测通讯链接: + + + + + + + + 12 + + + + + + + + + + + + + + + + 12 + + + + 参数已保存!!! + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 12 + + + + 应用 + + + + + + + + 12 + + + + 退出 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 12 + + + + 开机自启动 + + + + + + + + 12 + + + + 添加到桌面快捷方式 + + + + diff --git a/tpvs17/valueMainUI/lpDebugUI.cpp b/tpvs17/valueMainUI/lpDebugUI.cpp index 3713e94..36b0b0b 100644 --- a/tpvs17/valueMainUI/lpDebugUI.cpp +++ b/tpvs17/valueMainUI/lpDebugUI.cpp @@ -5,7 +5,7 @@ lpDebugUI::lpDebugUI(QWidget *parent) { ui.setupUi(this); connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(onButtonClicked())); - + setWindowIcon(QIcon(":/Resources/icon.png")); } lpDebugUI::~lpDebugUI() diff --git a/tpvs17/valueMainUI/main.cpp b/tpvs17/valueMainUI/main.cpp index 80ccc63..16d7e36 100644 --- a/tpvs17/valueMainUI/main.cpp +++ b/tpvs17/valueMainUI/main.cpp @@ -1,10 +1,15 @@ #include "valueMainUI.h" #include - +#include "QSignleApplication.h" int main(int argc, char *argv[]) { - QApplication a(argc, argv); - valueMainUI w; - w.show(); - return a.exec(); + SingleApplication a(argc, argv,"valueMain"); + if (!a.getInstanceRunning()) + { + valueMainUI w; + w.show(); + a.setMainWindow(&w); + return a.exec(); + } + return 0; } diff --git a/tpvs17/valueMainUI/resource.h b/tpvs17/valueMainUI/resource.h new file mode 100644 index 0000000..652831f --- /dev/null +++ b/tpvs17/valueMainUI/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ ɵİļ +// valueMainUI.rc ʹ +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/tpvs17/valueMainUI/valueMainUI.aps b/tpvs17/valueMainUI/valueMainUI.aps new file mode 100644 index 0000000..28113f8 Binary files /dev/null and b/tpvs17/valueMainUI/valueMainUI.aps differ diff --git a/tpvs17/valueMainUI/valueMainUI.cpp b/tpvs17/valueMainUI/valueMainUI.cpp index bc3b84c..72b13df 100644 --- a/tpvs17/valueMainUI/valueMainUI.cpp +++ b/tpvs17/valueMainUI/valueMainUI.cpp @@ -2,15 +2,21 @@ #include #include #include "lpConfig.h" +#include +#include "SystemTool.h" +#include +#include +#include "QSettings" #pragma execution_character_set("utf-8") - +#define WINDOWICON ":/Resources/icon.png" valueMainUI::valueMainUI(QWidget *parent) : QMainWindow(parent) { - setWindowTitle(tr("识别定位一体检测系统")); ui.setupUi(this); - + setupTrayIcon(); + setWindowIcon(QIcon(WINDOWICON)); + setWindowTitle(tr("识别定位一体检测系统")); m_pLabelA = new QLabel(this); m_pLabelB = new QLabel(this); m_pLabelSystem = new QLabel(this); @@ -29,14 +35,15 @@ valueMainUI::valueMainUI(QWidget *parent) m_pLabelB->setAlignment(Qt::AlignCenter); m_pLabelSystem->setAlignment(Qt::AlignCenter); - ui.statusBar->addWidget(m_pLabelA,50); - ui.statusBar->addWidget(m_pLabelB,50); - ui.statusBar->addPermanentWidget(m_pLabelSystem,50); + ui.statusBar->addWidget(m_pLabelA, 50); + ui.statusBar->addWidget(m_pLabelB, 50); + ui.statusBar->addPermanentWidget(m_pLabelSystem, 50); { QGridLayout *pLayout_A = new QGridLayout(ui.widget_A); m_ImgViewer_A = new RoiImgViewer(ui.widget_A); m_ImgViewer_A->setObjectName("m_ImgViewer_A"); + connect(m_ImgViewer_A, SIGNAL(sgImageScale(qreal)), this, SLOT(onImageScale(qreal))); pLayout_A->addWidget(m_ImgViewer_A); ui.widget_A->setLayout(pLayout_A); @@ -45,6 +52,13 @@ valueMainUI::valueMainUI(QWidget *parent) m_ImgViewer_B->setObjectName("m_ImgViewer_B"); pLayout_B->addWidget(m_ImgViewer_B); ui.widget_B->setLayout(pLayout_B); + + QString strPath = QApplication::applicationDirPath() + "/showImg.ini"; + QSettings setting(strPath, QSettings::IniFormat); + double nScale_A = setting.value("ShowImg/ScaleA", 0.53).toDouble(); + double nScale_B = setting.value("ShowImg/ScaleB", 0.53).toDouble(); + m_ImgViewer_A->setInitScale(nScale_A); + m_ImgViewer_B->setInitScale(nScale_B); } { m_pClient_A = new webClient(); @@ -68,19 +82,24 @@ valueMainUI::valueMainUI(QWidget *parent) connect(ui.actionsettingB, SIGNAL(triggered()), this, SLOT(onButtonClicked())); connect(ui.actionConfig, SIGNAL(triggered()), this, SLOT(onButtonClicked())); connect(ui.actiondebug, SIGNAL(triggered()), this, SLOT(onButtonClicked())); - //connect(ui.actionsettingA, SIGNAL(triggered()), this, SLOT(onButtonClicked())); + m_pConfigUI = new lpConfigUI(); m_pDebugUI = new lpDebugUI(); connect(m_pDebugUI, SIGNAL(sgButtonClicked(int)), this, SLOT(onDebugClicked(int))); m_SysTimerID = startTimer(1000); - + lpConfig::instance()->loadConfig(); onConnectA(); - onConnectB(); + if (lpConfig::instance()->doubleStation == true) + { + onConnectB(); + } + m_timerStartID = startTimer(2000); } valueMainUI::~valueMainUI() { + onStopProcess(); { m_task_A.quit(); m_task_A.wait(); @@ -259,24 +278,25 @@ Q_SLOT void valueMainUI::onButtonClicked() } else if (strObj == "actiondebug") { - //m_timer = startTimer(5000); - m_pDebugUI->setParent(this); - m_pDebugUI->setWindowTitle(tr("调试页面")); - m_pDebugUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); - m_pDebugUI->setWindowIcon(QIcon(":/image/leaper")); - m_pDebugUI->setWindowModality(Qt::ApplicationModal); - m_pDebugUI->setAttribute(Qt::WA_ShowModal, true); - m_pDebugUI->show(); + m_pDebugUI->setParent(this); + m_pDebugUI->setWindowTitle(tr("调试页面")); + m_pDebugUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); + m_pDebugUI->setWindowIcon(QIcon(":/image/leaper")); + m_pDebugUI->setWindowModality(Qt::ApplicationModal); + m_pDebugUI->setAttribute(Qt::WA_ShowModal, true); + m_pDebugUI->show(); + } else if (strObj == "actionConfig") { m_pConfigUI->setParent(this); - m_pConfigUI->setWindowTitle(tr("调试页面")); + m_pConfigUI->setWindowTitle(tr("系统参数配置页面")); m_pConfigUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); m_pConfigUI->setWindowIcon(QIcon(":/image/leaper")); m_pConfigUI->setWindowModality(Qt::ApplicationModal); m_pConfigUI->setAttribute(Qt::WA_ShowModal, true); m_pConfigUI->show(); + //check(); } } @@ -299,8 +319,9 @@ void valueMainUI::timerEvent(QTimerEvent *event) QJsonObject sObj; sObj.insert("cmd", "trigerCam"); m_pClient_A->onSendJson(sObj); + m_pClient_B->onSendJson(sObj); } - else if (m_SysTimerID = event->timerId()) + else if (m_SysTimerID == event->timerId()) { m_tickCount++; m_CoutB++; @@ -350,6 +371,35 @@ void valueMainUI::timerEvent(QTimerEvent *event) } } + else if (m_timerStartID == event->timerId()) + { + killTimer(m_timerStartID); + m_timerStartID = 0; + + onStartProcess(); + + } +} + +void valueMainUI::closeEvent(QCloseEvent *event) +{ + QMessageBox info(this); + info.setWindowIcon(QIcon(WINDOWICON)); + info.setWindowTitle(QObject::tr("警告")); + info.setText(QObject::tr("本检测系统正在运行,您真的要关闭?")); + info.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + info.setButtonText(QMessageBox::Ok, QObject::tr("关闭")); + info.setButtonText(QMessageBox::Cancel, QObject::tr("后台运行")); + if (info.exec() != QMessageBox::Ok) + { + m_bExit = false; + if (m_bExit == false) + { + setMainWindowVisibility(false); + return event->ignore(); + } + } + return event->accept(); } Q_SLOT void valueMainUI::onDebugClicked(int nID) @@ -382,7 +432,6 @@ Q_SLOT void valueMainUI::onConnected_A(bool bFalg) ui.textEdit->append("设备已连接"); } } - } Q_SLOT void valueMainUI::onConnected_B(bool bFalg) @@ -400,5 +449,123 @@ Q_SLOT void valueMainUI::onConnected_B(bool bFalg) ui.textEdit_2->append("设备已连接"); } } +} + +void valueMainUI::check() +{ + QString strExeName = QString("%1.exe").arg("Enchanter"); + QProcess process(this); + QString strCMD = QString("wmic process where caption=\"%1\" get caption,commandline /value").arg(strExeName); + process.start(strCMD); + process.waitForStarted(); + process.waitForFinished(); + QString strTmp = QString(process.readAllStandardOutput()); + bool bRun = false; + if (strTmp.contains(strExeName)) + bRun = true; +} + +void valueMainUI::onRunApp(QString strAppPath) +{ + QProcess *process = new QProcess(this); + QFileInfo fileInfo(strAppPath); + QString strPath = fileInfo.absolutePath(); + QString strExeName = fileInfo.fileName(); + m_appNames.append(strExeName); + //process->setWorkingDirectory(strPath); + process->startDetached(strAppPath, QStringList(), strPath); + bool ret = process->waitForStarted(); + if (ret) { + qDebug() << "start ok"; + } + else { + qDebug() << "start failed"; + } +} +Q_SLOT void valueMainUI::onStartProcess() +{ + QString strAppPath = lpConfig::instance()->appPathA; + if (strAppPath.isEmpty()) + return; + + onRunApp(lpConfig::instance()->appPathA); + onRunApp(lpConfig::instance()->appPathB); +} + +Q_SLOT void valueMainUI::onStopProcess() +{ + foreach(QString var, m_appNames) { + QString strExeName = QString("%1").arg(var); + SystemTool::killZombieProcess(strExeName.toStdString().c_str()); + } +} + +void valueMainUI::setupTrayIcon() +{ + m_trayIcon = new QSystemTrayIcon(this); + m_trayIconMenu = new QMenu(this); + m_restoreAction = new QAction(tr("后台运行"), this); + m_quitAction = new QAction(tr("退出"), this); + + m_trayIconMenu->addAction(m_restoreAction); + m_trayIconMenu->addSeparator(); + m_trayIconMenu->addAction(m_quitAction); + + QIcon icon(":/Resources/icon.png"); + m_trayIcon->setIcon(icon); + m_trayIcon->setContextMenu(m_trayIconMenu); + m_trayIcon->show(); + + connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(onActivated(QSystemTrayIcon::ActivationReason))); + connect(m_restoreAction, &QAction::triggered, this, [this]() { + setMainWindowVisibility(isHidden() + || windowState() == Qt::WindowMinimized + || (qApp->applicationState() == Qt::ApplicationInactive)); + }); + connect(m_quitAction, &QAction::triggered, this, &valueMainUI::onQuitApplication); +} + +Q_SLOT void valueMainUI::onActivated(QSystemTrayIcon::ActivationReason reason) +{ + if (reason == QSystemTrayIcon::DoubleClick) + { + setMainWindowVisibility(true); + } +} + +void valueMainUI::setMainWindowVisibility(bool state) +{ + if (state) { + show(); + qApp->processEvents(); + qApp->setActiveWindow(this); + qApp->processEvents(); + m_restoreAction->setText(tr("后台运行")); + } + else { + m_restoreAction->setText(tr("显示界面")); + hide(); + } +} + +Q_SLOT void valueMainUI::onQuitApplication() +{ + m_bExit = true; + valueMainUI::close(); +} + +Q_SLOT void valueMainUI::onImageScale(qreal value) +{ + QString strPath = QApplication::applicationDirPath() + "/showImg.ini"; + QSettings setting(strPath, QSettings::IniFormat); + QObject *obj = sender(); + if (m_ImgViewer_A == obj) + { + setting.setValue("ShowImg/ScaleA", value); + } + else if (m_ImgViewer_B == obj) + { + setting.setValue("ShowImg/ScaleB", value); + } } diff --git a/tpvs17/valueMainUI/valueMainUI.h b/tpvs17/valueMainUI/valueMainUI.h index e1faa5d..85fc7dd 100644 --- a/tpvs17/valueMainUI/valueMainUI.h +++ b/tpvs17/valueMainUI/valueMainUI.h @@ -8,6 +8,9 @@ #include "RoiImgViewer.h" #include "lpConfigUI.h" #include "lpDebugUI.h" +#include +#include +#include class valueMainUI : public QMainWindow { @@ -26,10 +29,23 @@ public: Q_SLOT void onButtonClicked(); QJsonObject byte2Json(QByteArray data); QByteArray Json2byte(QJsonObject obj); - virtual void timerEvent(QTimerEvent *event); Q_SLOT void onDebugClicked(int nID); Q_SLOT void onConnected_A(bool bFalg); Q_SLOT void onConnected_B(bool bFalg); + void check(); + void onRunApp(QString strPath); + Q_SLOT void onStartProcess(); + Q_SLOT void onStopProcess(); + +private://trayIcon + void setupTrayIcon(); + Q_SLOT void onActivated(QSystemTrayIcon::ActivationReason reason); + void setMainWindowVisibility(bool state); + Q_SLOT void onQuitApplication(); + Q_SLOT void onImageScale(qreal real); +protected: + virtual void timerEvent(QTimerEvent *event); + virtual void closeEvent(QCloseEvent *event); private: Ui::valueMainUIClass ui; @@ -47,6 +63,7 @@ private: QThread m_task_B; int m_timer{ 0 }; + int m_timerStartID{ 0 }; lpConfigUI *m_pConfigUI{ nullptr }; lpDebugUI *m_pDebugUI{ nullptr }; @@ -56,8 +73,15 @@ private: bool m_bServerB{ false }; int m_SysTimerID{ 0 }; - quint64 m_tickCount{ 0 }; + + QStringList m_appNames;//ӻapp +private: + QSystemTrayIcon* m_trayIcon{ nullptr }; + QMenu* m_trayIconMenu{ nullptr }; + QAction* m_restoreAction{ nullptr }; + QAction* m_quitAction{ nullptr }; + bool m_bExit{ false }; }; #endif diff --git a/tpvs17/valueMainUI/valueMainUI.qrc b/tpvs17/valueMainUI/valueMainUI.qrc index d8308b4..004dc3b 100644 --- a/tpvs17/valueMainUI/valueMainUI.qrc +++ b/tpvs17/valueMainUI/valueMainUI.qrc @@ -1,4 +1,7 @@ - + + Resources/icon.png + Resources/Client.png + Resources/Setting.png diff --git a/tpvs17/valueMainUI/valueMainUI.rc b/tpvs17/valueMainUI/valueMainUI.rc new file mode 100644 index 0000000..bbabcd1 Binary files /dev/null and b/tpvs17/valueMainUI/valueMainUI.rc differ diff --git a/tpvs17/valueMainUI/valueMainUI.ui b/tpvs17/valueMainUI/valueMainUI.ui index 6a709f9..23179fd 100644 --- a/tpvs17/valueMainUI/valueMainUI.ui +++ b/tpvs17/valueMainUI/valueMainUI.ui @@ -6,8 +6,8 @@ 0 0 - 970 - 691 + 918 + 617 @@ -17,6 +17,12 @@ + + + 5 + 0 + + 12 @@ -26,24 +32,27 @@ A侧检测工位 - - - - - 0 - 5 - - - - - - - - - 0 - 5 - + + + + Qt::Vertical + + + + 0 + 8 + + + + + + + 0 + 1 + + + @@ -51,6 +60,12 @@ + + + 5 + 0 + + 12 @@ -60,24 +75,27 @@ B侧检测工位 - - - - - 0 - 5 - - - - - - - - - 0 - 5 - + + + + Qt::Vertical + + + + 0 + 8 + + + + + + + 0 + 1 + + + @@ -87,9 +105,15 @@ + + Qt::NoContextMenu + toolBar + + Qt::ToolButtonTextUnderIcon + TopToolBarArea @@ -102,6 +126,10 @@ + + + :/Resources/Client.png:/Resources/Client.png + A侧设置 @@ -112,6 +140,10 @@ + + + :/Resources/Client.png:/Resources/Client.png + B侧设置 @@ -122,6 +154,10 @@ + + + :/Resources/Setting.png:/Resources/Setting.png + 系统设置 diff --git a/tpvs17/valueMainUI/valueMainUI.vcxproj b/tpvs17/valueMainUI/valueMainUI.vcxproj index c84815e..8ee4f7e 100644 --- a/tpvs17/valueMainUI/valueMainUI.vcxproj +++ b/tpvs17/valueMainUI/valueMainUI.vcxproj @@ -52,8 +52,8 @@ true - UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;%(AdditionalIncludeDirectories) Disabled ProgramDatabase MultiThreadedDebugDLL @@ -64,13 +64,13 @@ $(OutDir)\$(ProjectName).exe $(QTDIR)\lib;%(AdditionalLibraryDirectories) true - qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5WebSocketsd.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) + qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5WebSocketsd.lib;Qt5Widgetsd.lib;Qt5Locationd.lib;Qt5Networkd.lib;%(AdditionalDependencies) .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp Moc'ing %(Identity)... - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase;%(AdditionalIncludeDirectories) - UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;%(PreprocessorDefinitions) Uic'ing %(Identity)... @@ -84,8 +84,8 @@ true - UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;%(AdditionalIncludeDirectories) MultiThreadedDLL true @@ -95,13 +95,13 @@ $(OutDir)\$(ProjectName).exe $(QTDIR)\lib;%(AdditionalLibraryDirectories) false - qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5WebSockets.lib;Qt5Widgets.lib;%(AdditionalDependencies) + qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5WebSockets.lib;Qt5Widgets.lib;Qt5Location.lib;Qt5Network.lib;%(AdditionalDependencies) .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp Moc'ing %(Identity)... - .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) - UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase;$(QTDIR)\include\QtLocation;$(QTDIR)\include\QtNetwork;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WEBSOCKETS_LIB;QT_WIDGETS_LIB;QT_LOCATION_LIB;QT_NETWORK_LIB;%(PreprocessorDefinitions) Uic'ing %(Identity)... @@ -125,6 +125,8 @@ + + @@ -153,6 +155,12 @@ .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets + + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase + + + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets;.\..\..\src\tpMain\algela;E:\wheelValve\3part\tadpole\include\tpBase .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets @@ -178,6 +186,12 @@ .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWebSockets;$(QTDIR)\include\QtWidgets + + + + + + diff --git a/tpvs17/valueMainUI/valueMainUI.vcxproj.filters b/tpvs17/valueMainUI/valueMainUI.vcxproj.filters index 8222171..a44a951 100644 --- a/tpvs17/valueMainUI/valueMainUI.vcxproj.filters +++ b/tpvs17/valueMainUI/valueMainUI.vcxproj.filters @@ -75,6 +75,12 @@ Source Files + + Source Files + + + Source Files + @@ -101,6 +107,9 @@ Header Files + + Header Files + @@ -131,5 +140,17 @@ Header Files + + Header Files + + + Header Files + + + + + + + \ No newline at end of file diff --git a/tpvs17/wheel.sln b/tpvs17/wheel.sln index 9c7bf44..a07167b 100644 --- a/tpvs17/wheel.sln +++ b/tpvs17/wheel.sln @@ -27,6 +27,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tpCamVirtual", "tpCamVirtua EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Enchanter", "Enchanter\Enchanter.vcxproj", "{7B76D75A-0E01-451E-880E-FB9AC63A914B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tpCamHik", "tpCamHik\tpCamHik.vcxproj", "{64C9A32D-82E8-4C36-9AA6-52D58B23F687}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -113,12 +115,20 @@ Global {7B76D75A-0E01-451E-880E-FB9AC63A914B}.Release|x64.ActiveCfg = Release|x64 {7B76D75A-0E01-451E-880E-FB9AC63A914B}.Release|x64.Build.0 = Release|x64 {7B76D75A-0E01-451E-880E-FB9AC63A914B}.Release|x86.ActiveCfg = Release|x64 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Debug|x64.ActiveCfg = Debug|x64 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Debug|x64.Build.0 = Debug|x64 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Debug|x86.ActiveCfg = Debug|Win32 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Debug|x86.Build.0 = Debug|Win32 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Release|x64.ActiveCfg = Release|x64 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Release|x64.Build.0 = Release|x64 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Release|x86.ActiveCfg = Release|Win32 + {64C9A32D-82E8-4C36-9AA6-52D58B23F687}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CD365F32-5EAC-4A16-AD47-BFB1D8E5511A} Qt5Version = qt5.9.4-msvc2017-x64 + SolutionGuid = {CD365F32-5EAC-4A16-AD47-BFB1D8E5511A} EndGlobalSection EndGlobal