diff --git a/src/ImageCompare/ImageCompareModel.cpp b/src/ImageCompare/ImageCompareModel.cpp index 2c5810c..6ac6a23 100644 --- a/src/ImageCompare/ImageCompareModel.cpp +++ b/src/ImageCompare/ImageCompareModel.cpp @@ -8,11 +8,13 @@ #include "ImageCompareModel.h" #include "CVUtils.h" - #include "MultiScaleImageCompareModel.h" -#include #include -//#define DEBUG_VIEW_INTERNAL_MAT + +//#define DEBUG_VIEW_PLOT +// #define DEBUG_VIEW_PLOT + + #define IMGCMP_STR_NAME "name" #define IMGCMP_STR_IMAGE_COMPARE_MODEL "imageCompareModel" #define IMGCMP_STR_ALIGN_BASE_IMAGE "alignBaseImage" @@ -31,18 +33,51 @@ #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_TEMPL "innerTempl" #define IMGCMP_CACHE_MAX_SIZE 100 +using namespace std; -#define MIN_CIRCLE_RADII 5 -#define MAX_CIRCLE_RADII 110 -int ImageCompareModel::m_parallelFlag = 0; +// void meanvarnorm(Mat& src, Mat &dst, double avg, double var, Mat mask = Mat()) +// { +// Scalar m, v; +// cv::meanStdDev(src, m, v, mask); +// // (I - m)*var/v + avg = I*var/v - m*var/v + avg +// double s = var / v.val[0]; +// double t = avg - m.val[0] * var / v.val[0]; +// dst = src * s + t; +// } + +float angleNorm(float angle) +{ + angle = angle - (int)(angle / 360.0) * 360; + if (angle < 0) + { + angle += 360.0; + } + return angle; +} +float angleDis(float angle0, float angle1) +{ + angle0 = angleNorm(angle0); + angle1 = angleNorm(angle1); + float dis = angle0 - angle1; + float ldis = dis; + if (dis < 0) + { + ldis = dis + 360; + } + else if (dis > 0) + { + ldis = dis - 360; + } + if (abs(ldis) < abs(dis)) + { + dis = ldis; + } + return dis; +} + cv::Point2f ImageCompareModel::refineCircleCen(const Mat& img, Point2f cen) { int r = 2; @@ -64,8 +99,15 @@ cv::Point2f ImageCompareModel::refineCircleCen(const Mat& img, Point2f cen) vector dftVec; dft(vec, dftVec); +// CvPlot::plot("refineCenter", &(vec[0]), vec.size()); + float diffVal = sum(vec.begin(), vec.end()); +// CvPlot::clear("dft"); +// CvPlot::plot("dft", &(dftVec[0]), 25); +// +// float diffVal = dftVec[9]; + vec.push_back(diffVal); if (minDiff > diffVal) @@ -75,6 +117,9 @@ cv::Point2f ImageCompareModel::refineCircleCen(const Mat& img, Point2f cen) bestDftVec = dftVec; } +// CvPlot::clear("bestDft"); +// CvPlot::plot("bestDft", &(bestDftVec[0]), 25); + std::cout << "diff: " << diffVal << ", " " minDiff: " << minDiff << ", " " bestCenter: " << bestCenter.x << "-" << bestCenter.y << @@ -182,13 +227,11 @@ cv::Mat ImageCompareModel::genMask(const Mat& img, Point2f center, { // default is 30 innerR = img.rows*0.178; - //innerR = img.rows; } if (outterR == -1) { // default is max radius - 10 outterR = img.rows*0.425; - //outterR = img.rows; } circle(mask, center, outterR, Scalar(255), -1); circle(mask, center, innerR, Scalar(0), -1); @@ -205,9 +248,6 @@ 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); - 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); } void ImageCompareModel::printInfo() @@ -261,10 +301,6 @@ bool ImageCompareModel::save2file(string filePath) IMGCMP_STR_ALIGN_BASE_IMAGE << mAlignBaseImg << IMGCMP_STR_COMPARE_BASE_IMAGE << mCompareBaseImg << IMGCMP_STR_WEIGHT_MAT << mWeightMat << - IMGCMP_STR_INSIDE_AVE_IMAGE << mInSideBaseImg << - IMGCMP_STR_INSIDE_COMP_AVE_IMAGE << mInsideCompareBaseImg << - IMGCMP_STR_INSIDE_WEIGHT << mInsideWeightMat << - IMGCMP_STR_INSIDE_TEMPL << innerTempl << IMGCMP_STR_MATCH_VAL_SCALE << mMatchValScale << IMGCMP_STR_TARGET_MEAN_VAL << mTargetMeanVal << IMGCMP_STR_TARGET_STDDEV_VAL << mTargetStddevVal << @@ -275,9 +311,8 @@ bool ImageCompareModel::save2file(string filePath) IMGCMP_STR_TRUE_SAMPLE_DIS_MAX << mTrueSampleDisMax << IMGCMP_STR_FALSE_SAMPLE_MIN_DIS << getFalseSampleMinDis() << IMGCMP_STR_DIS_THRE << mDisThre << - IMGCMP_STR_TRAIN_DIS << mDisMat << - IMGCMP_STR_AVER_DIAMETER << meanDiameter << - IMGCMP_STR_INSIDE_RADIUS << rInner; + IMGCMP_STR_TRAIN_DIS <> mAlignBaseImg; fs[IMGCMP_STR_COMPARE_BASE_IMAGE] >> mCompareBaseImg; fs[IMGCMP_STR_WEIGHT_MAT] >> mWeightMat; - fs[IMGCMP_STR_INSIDE_AVE_IMAGE] >> mInSideBaseImg; - fs[IMGCMP_STR_INSIDE_COMP_AVE_IMAGE] >> mInsideCompareBaseImg; - fs[IMGCMP_STR_INSIDE_WEIGHT] >> mInsideWeightMat; - fs[IMGCMP_STR_INSIDE_TEMPL] >> innerTempl; mMatchValScale = (double)fs[IMGCMP_STR_MATCH_VAL_SCALE]; FileNode fn = fs[IMGCMP_STR_TARGET_MEAN_VAL]; @@ -366,11 +397,6 @@ bool ImageCompareModel::readFromFile(string filePath) meanDiameter = (int)fn; } - fn = fs[IMGCMP_STR_INSIDE_RADIUS]; - if (!fn.empty()) - { - rInner = (float)fn; - } setFilePath(filePath); @@ -379,14 +405,9 @@ bool ImageCompareModel::readFromFile(string filePath) return true; } -void ImageCompareModel::preProcessImage(Mat& img, Mat &insideImg) const +void ImageCompareModel::preProcessImage(Mat& img) const { preProcessImage(img, m8uMaskImg, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); - if (insideImg.empty()) - { - return; - } - preProcessImage(insideImg, m8uInsideMaskImg, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); } void ImageCompareModel::preProcessImage(Mat& img, const Mat& mask, double tarMean, @@ -446,12 +467,12 @@ 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); + img = (img - meanScalar.val[0]) * dstMean / stddevScalar.val[0] + dstMean; + 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); + weightMat.mul(hightlightsMask), 125); #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vImgNorm = imgNorm / 255.0; #endif @@ -496,106 +517,45 @@ double ImageCompareModel::compare(Mat img0, Mat img1, Mat* pRImg0, Mat* pRImg1) return genMatchValue(dMat); } -double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int levelNum /*= 1*/, +double ImageCompareModel::compare(Mat img, Mat* pRImg /*= NULL*/, int levelNum /*= 1*/, bool isFilterSize /*= true*/, int flag, double md_diameter, double md_height) { if (mIsEnableCache) { - auto cacheIter = mDisCache.find(srcImage.data); + auto cacheIter = mDisCache.find(img.data); if (cacheIter != mDisCache.end()) { return cacheIter->second; } - } -/* CircleDetector cd; - cd.setAlgoType(CircleDetector::PeakCircle); - cd.setEdgeWidth(3); - //cd.setPolarity(Polarity::White2Black); - cd.setPolarity(Polarity::Either); - cd.setFindBy(FindBy::Best); - //cd.setFindBy(FindBy::Last); - cd.setRadii(MIN_CIRCLE_RADII, MAX_CIRCLE_RADII); - cd.setACThres(5); - Vec3f bestCircle; - cd.detectBest(srcImage, Point2f(srcImage.cols / 2, srcImage.rows / 2), bestCircle, nullptr); - -#ifdef DEBUG_VIEW_INTERNAL_MAT - vector vecs; - vecs.push_back(srcImage); - vecs.push_back(srcImage); - vecs.push_back(srcImage); - Mat rr; - merge(vecs, rr); - - circle(rr, Point2f(bestCircle[0], bestCircle[1]), bestCircle[2], Scalar(255, 0, 0), 2); -#endif - - if (bestCircle[2] < 3 || bestCircle[0] == 0 || bestCircle[1] == 0) - return DBL_MAX; - */ -// int x_Axis = bestCircle[0] - MAX_CIRCLE_RADII; -// int y_Axis = bestCircle[1] - MAX_CIRCLE_RADII; - - 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 < (bestCircle[0] + MAX_CIRCLE_RADII) || srcImage.rows < (bestCircle[1] + MAX_CIRCLE_RADII)) -// return DBL_MAX; - - if (srcImage.cols < (srcImage.cols / 2 + MAX_CIRCLE_RADII) || srcImage.rows < (srcImage.rows / 2 + MAX_CIRCLE_RADII)) - return DBL_MAX; - - Rect rect(x_Axis, y_Axis, r_Axis, r_Axis); - Mat srcCenterMat; - srcImage(rect).copyTo(srcCenterMat); - Mat img, centerMat; - resizeMat(srcImage, img); - resizeMat(srcCenterMat, centerMat); + } Mat rawImg = img.clone(); int nRadiusDiff = 15; - if (mAlignBaseImg.size() != img.size() || mInSideBaseImg.size() !=centerMat.size()) + if (mAlignBaseImg.size() != img.size()) { - if (isFilterSize \ - && abs(mAlignBaseImg.size().width - img.size().width) > nRadiusDiff \ - || abs(mInSideBaseImg.size().width - centerMat.size().width) > 3) + if (isFilterSize && abs(mAlignBaseImg.size().width- img.size().width) > nRadiusDiff) { return DBL_MAX; } 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(); + preProcessImage(matchImg); if (!mpMultiScaleModel) { initMultiScaleModel(); } - m_parallelFlag = 0; RotateMatchResult rmr = rotateMatch(matchImg, levelNum); Mat rImg = rmr.mBestRImg; - m_parallelFlag = 1; - RotateMatchResult rmmInside = rotateMatch(matchInsideImg, 1); - Mat rInsideImg = rmmInside.mBestRImg; - if (rImg.empty() || rInsideImg.empty()) + + if (rImg.empty()) { return DBL_MAX; } #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vRImg = rImg / 255.0; - Mat vInsideMat = rInsideImg / 255.0; #endif double bestAngle = rmr.mBestAngle; @@ -608,85 +568,37 @@ double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int level hightlightsMask /= 255.0; Mat unifiedMask = m32fMaskImg.mul(hightlightsMask).mul(mWeightMat); - //Mat ii = mWeightMat / 255.0; + preProcessImage(cmpImg, m8uMaskImg, mWeightMat, mTargetMeanVal, mTargetStddevVal, mHighlightsThreshold); cmpImg.setTo(0, cmpImg < 0); - converToType(cmpImg, CV_32FC1); 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); - -// float offset = 5; -// float startX = mAlignBaseImg.cols / 2.0 - rInner - offset; -// float startY = mAlignBaseImg.rows / 2.0 - rInner - offset; -// Rect rect(startX, startY, 2*(rInner + offset), 2*(rInner + offset)); -// Mat innerPartMat = camInsideMat(rect); -// Mat rstMat; -// cv::matchTemplate(innerTempl, innerPartMat, rstMat, CV_TM_SQDIFF_NORMED); -// double minVal; -// Point minLoc; -// minMaxLoc(rstMat, &minVal, NULL, &minLoc, NULL); -//#ifdef DEBUG_VIEW_INTERNAL_MAT -// Mat test1 = innerPartMat.clone(); -// Mat test2 = innerPartMat.clone(); -// vector imgs; -// imgs.push_back(test2); -// imgs.push_back(test1); -// imgs.push_back(innerPartMat); -// Mat rst; -// merge(imgs, rst); -// cv::rectangle(rst, Rect(minLoc.x, minLoc.y, innerTempl.cols, innerTempl.rows), Scalar(0, 0, 255)); -//#endif -// //debug -// - 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); - 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); + Mat vRotatedImg1 = cmpImg / 255.0; #endif cmpImg.setTo(0, cmpImg < 10); - //camInsideMat.setTo(0, camInsideMat < 10); if (pRImg) { *pRImg = cmpImg; } - m_parallelFlag = 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 ret = genMatchValue(cmpImg, mCompareBaseImg, unifiedMask, flag, rawImg.rows, md_diameter, md_height); - ret = 0.6*ret + 0.4*retInside; - - if (ret > mDisThre) + /*if (flag == 1) { - return DBL_MAX; - } + double matchedVal = ret; + ret = penltyCoeff(matchedVal, meanDiameter, rawImg.rows); + printf("the matched value %f", ret); + }*/ if (mIsEnableCache) { @@ -699,104 +611,25 @@ double ImageCompareModel::compare(Mat srcImage, Mat* pRImg /*= NULL*/, int level return ret; } -void ImageCompareModel::train(const vector& vec) + + +void ImageCompareModel::train(const vector& imgVec) { #ifdef _DEBUG - std::cout << getName() << std::endl; + cout << getName() << endl; #endif _DEBUG - if (0 == vec.size()) { + if (0 == imgVec.size()) { return; } - - vector centerMatVec; - vector tmpVec; - for (int i = 0; i < vec.size(); i++) - { - Mat originalMat = vec[i]; - Vec3f bestCircle; - Point2f p = Point2f(originalMat.cols / 2.0, originalMat.rows / 2.0); - -#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 - - if (bestCircle[2] > 0.00000001) - { - float startX = bestCircle[0] - MAX_CIRCLE_RADII;//找最大圆外径,固定直径 - float startY = bestCircle[1] - MAX_CIRCLE_RADII; - Rect rect(startX, startY, MAX_CIRCLE_RADII * 2, MAX_CIRCLE_RADII * 2); - Mat origianlCenterMat; - originalMat(rect).copyTo(origianlCenterMat); - centerMatVec.push_back(origianlCenterMat); - tmpVec.push_back(vec[i]); - } - -// if (bestCircle[2] > 0.00000001) -// { -// float startX = bestCircle[0] - bestCircle[2]; -// float startY = bestCircle[1] - bestCircle[2]; -// Rect rect(startX, startY, bestCircle[2]*2, bestCircle[2]*2); -// Mat origianlCenterMat; -// originalMat(rect).copyTo(origianlCenterMat); -// centerMatVec.push_back(origianlCenterMat); -// } -// else -// { -// -// } - } - vector scaledCenterVec; - resizeVecMat(centerMatVec, scaledCenterVec); - if (scaledCenterVec.size() <= 0) - return; - if (tmpVec.size() <= 0) - return; - - vector imgVec; - resizeVecMat(tmpVec, imgVec); mAlignBaseImg = imgVec.front(); - mInSideBaseImg = scaledCenterVec.front(); genMask(); - //Mat baseTempl = imgVec.front(); - //float realR = rInner + 2; - //float hf_width = sqrt(realR*realR / 2.0); - //float startx = baseTempl.cols / 2 - hf_width; - //float starty = baseTempl.rows / 2 - hf_width; - //Rect rect(startx, starty, 2*hf_width, 2*hf_width); - //innerTempl = baseTempl(rect); - 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()); - Mat minInsideMat(mInSideBaseImg.size(), mInSideBaseImg.type()); - minOutsideMat.setTo(FLT_MAX); - minInsideMat.setTo(FLT_MAX); + preProcessImage(mAlignBaseImg); + Mat sumMat = Mat::zeros(mAlignBaseImg.size(), CV_32FC1); + Mat minMat(mAlignBaseImg.size(), mAlignBaseImg.type()); + minMat.setTo(FLT_MAX); vector rImgVec; - vector rInsideImgVec; vector rmrVec; - vector rmrVecInside; vector resizedImgVec; - vector resizedCenterVec; - //vector resizedWarp; vector diametersVec; for (int i = 0; i < imgVec.size(); ++i) { @@ -806,73 +639,37 @@ void ImageCompareModel::train(const vector& vec) { Mat resizedImg; resize(img, resizedImg, mAlignBaseImg.size()); - //resize(warpImage, warpImage, mAlignBaseImg.size()); img = resizedImg; } - - Mat centerMat = scaledCenterVec[i]; - if (centerMat.size() != mInSideBaseImg.size()) - { - Mat resizedCenterMat; - resize(centerMat, resizedCenterMat, minInsideMat.size()); - centerMat = resizedCenterMat; - } resizedImgVec.push_back(img); - resizedCenterVec.push_back(centerMat); - //resizedWarp.push_back(warpImage); - //Mat insideImg = img.clone(); - preProcessImage(img, centerMat); - m_parallelFlag = 0; - RotateMatchResult rmr = rotateMatch(img);//旋转匹配 输出匹配完成的角度及图片 + preProcessImage(img); + + RotateMatchResult rmr = rotateMatch(img); rmrVec.push_back(rmr); - m_parallelFlag = 1; - RotateMatchResult rmrInside = rotateMatch(centerMat); - rmrVecInside.push_back(rmrInside); Mat rImg = rmr.mBestRImg; - //rImgVec.push_back(rImg); - - Mat rInsideImg = rmrInside.mBestRImg; - rInsideImgVec.push_back(rInsideImg); - //minMat = min(minMat, rImg); - minOutsideMat = min(minOutsideMat, rImg);//生成权重图 去毛刺 - sumOutsideMat += rImg; - - minInsideMat = min(minInsideMat, rInsideImg); - sumInsideMat += rInsideImg; + rImgVec.push_back(rImg); + minMat = min(minMat, rImg); + sumMat += rImg; #ifdef DEBUG_VIEW_INTERNAL_MAT Mat viewRImg = rImg / 255.0; - Mat viewRInsideImg = rInsideImg / 255.0; - Mat viewImage = minOutsideMat / 255.0; - Mat viewInside = minInsideMat / 255.0; + Mat viewMinMat = minMat / 255.0; #endif } meanDiameter = mean(diametersVec)[0]; - Mat avgMat = sumOutsideMat / imgVec.size(); + Mat avgMat = sumMat / imgVec.size(); mAlignBaseImg = avgMat; - - Mat avgInsideMat = sumInsideMat / imgVec.size(); - mInSideBaseImg = avgInsideMat; #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vAvgMat = avgMat / 255.0; - Mat vAvgInsideMat = avgInsideMat / 255.0; #endif - //mWeightMat = minMat; - mWeightMat = minOutsideMat; + mWeightMat = minMat; + mWeightMat /= 255.0; - mInsideWeightMat = minInsideMat; - mInsideWeightMat /= 255.0; - meanvarnorm(mWeightMat, mWeightMat, mTargetMeanVal, 150, m8uMaskImg);//对权重进行 归一化 + /*luffy_base::luffy_imageProc::*/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); - { if(mRepeatNum <= 0) { @@ -884,69 +681,42 @@ void ImageCompareModel::train(const vector& vec) #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vWeightMat = mWeightMat / 255.0; Mat vBaseMat = mAlignBaseImg / 255.0; - // Mat vMinMat = minMat / 255.0; - Mat vMinMat = minOutsideMat / 255.0; - - Mat vInsideWeight = mInsideWeightMat / 255.0; - Mat vInsidebaseMat = mInSideBaseImg / 255.0; - Mat vMinInsideMat = minInsideMat / 255.0; - + Mat vMinMat = minMat / 255.0; #endif - sumOutsideMat.setTo(0); - sumInsideMat.setTo(0); + sumMat.setTo(0); for (int i = 0; i < rmrVec.size(); ++i) { double bestAngle = rmrVec[i].mBestAngle; Mat img = resizedImgVec[i]; 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); - - sumOutsideMat += rotatedImg; - //rotatedInsideMat.setTo(0, rotatedInsideMat < 0); - sumInsideMat += rotatedInsideMat; + sumMat += rotatedImg; } - mCompareBaseImg = sumOutsideMat / resizedImgVec.size();//得到最终匹配图 - mInsideCompareBaseImg = sumInsideMat / resizedImgVec.size(); + mCompareBaseImg = sumMat / resizedImgVec.size(); + #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vCompareBaseImg = mCompareBaseImg / 255.0; vWeightMat = mWeightMat / 255.0; - Mat vcompareInsideBaseImg = mInsideCompareBaseImg / 255.0; - vInsideWeight = mInsideWeightMat / 255.0; - //cv::imwrite("F:\\temp\\insideWeight.png", mInsideWeightMat); - //cv::imwrite("F:\\temp\\insideBase.png", mInSideBaseImg); - //cv::imwrite("F:\\temp\\insideCompareBase.png", mInsideCompareBaseImg); #endif - trueSampleWeightRecon(resizedImgVec, resizedCenterVec, rmrVec, rmrVecInside); + trueSampleWeightRecon(resizedImgVec, rmrVec); mWeightMat = falseReConMat.clone(); - mInsideWeightMat = insideWeightRecon.clone(); } -void ImageCompareModel::trueSampleWeightRecon(const vector& resizedVec, - const vector& resizedCenterVec, - vector rmrVec, - vector rmrVecInside) +void ImageCompareModel::trueSampleWeightRecon(const vector& resizedVec, vector rmrVec) { falseReConMat = mWeightMat.clone(); - insideWeightRecon = mInsideWeightMat.clone(); for (int i = 0; i < resizedVec.size(); i++) { 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), + Mat processedImg = img.clone(); + preProcessImage(processedImg); + Mat rotatedImg = rotateImage(processedImg, Point2f(img.cols / 2.0, img.rows / 2.0), bestAngle); Mat hightlightsMask = rotatedImg < mHighlightsThreshold; @@ -960,80 +730,40 @@ void ImageCompareModel::trueSampleWeightRecon(const vector& resizedVec, rotatedImg.setTo(0, rotatedImg < 0); converToType(rotatedImg, CV_32FC1); - normSectors_tarImg(rotatedImg, unifiedMask, imgCen(rotatedImg), 1, mCompareBaseImg); + normSectors_tarImg(rotatedImg, unifiedMask, imgCen(rotatedImg), 1, + mCompareBaseImg); + + Mat vRotatedImg0 = rotatedImg / 255.0; #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vRotatedImg1 = rotatedImg / 255.0; #endif - rotatedImg.setTo(0, rotatedImg < 10); - ////// 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 highLightInsideMask = rotatedInsideImg < mHighlightsThreshold; - converToType(highLightInsideMask, CV_32FC1); - highLightInsideMask /= 255.0; - Mat unifiedInsideMask = m32fInsideMaskImg.mul(highLightInsideMask).mul(mInsideWeightMat); - preProcessImage(rotatedInsideImg, m8uInsideMaskImg, mInsideWeightMat, mTargetMeanVal, - mTargetStddevVal, mHighlightsThreshold); - Mat vcamInside = rotatedInsideImg / 255.0; - rotatedInsideImg.setTo(0, rotatedInsideImg < 0); - //mInsideCompareBaseImg.setTo(0, mInsideCompareBaseImg < 0); - normSectors_tarImg(rotatedInsideImg, unifiedInsideMask, imgCen(rotatedInsideImg), 1, mInsideCompareBaseImg); - trueWeightRecon(rotatedImg, mCompareBaseImg, rotatedInsideImg, mInsideCompareBaseImg); + rotatedImg.setTo(0, rotatedImg < 10); + trueWeightRecon(rotatedImg, mCompareBaseImg); } } -void ImageCompareModel::trueWeightRecon(const Mat& rImg, const Mat& baseImg, - const Mat& insideRimg, const Mat& insideBaseImg) +void ImageCompareModel::trueWeightRecon(const Mat& rImg, const Mat& baseImg) { Mat dMat = abs(rImg - baseImg); -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat tt = dMat / 255.0; - Mat m1 = rImg / 255.0; - Mat b1 = baseImg / 255.0; -#endif // DEBUG_VIEW_INTERNAL_MAT - - //Mat mData = dMat.mul(m32fMaskImg).mul(mWeightMat); + //Mat norImg = Mat::ones(dMat.size(), dMat.type()) * 255; + //dMat = max(dMat, 254); Mat mData; dMat.copyTo(mData, dMat > 1000); - - double outterVal = sum(mData).val[0]; - if (outterVal != 0) - { - mData = minMaxNorm(mData, 0, 255.0); - } - - - Mat i_dMat = abs(insideRimg - insideBaseImg); -#ifdef DEBUG_VIEW_INTERNAL_MAT - Mat i_tt = i_dMat / 255.0; - Mat i_m1 = insideRimg / 255.0; - Mat i_b1 = insideBaseImg / 255.0; - Mat i_maskR = i_m1.mul(m32fInsideMaskImg); - Mat i_masB = i_b1.mul(m32fInsideMaskImg); - -#endif // DEBUG_VIEW_INTERNAL_MAT - Mat i_mData; - i_mData.setTo(0); - //Mat test = i_dMat / 255; - //Mat imgtest = i_dMat.mul(m32fInsideMaskImg) / 255; - Mat innerDmat = i_dMat.mul(m32fInsideMaskImg).mul(mInsideWeightMat); - innerDmat = minMaxNorm(innerDmat, 0, 255.0); - - weightMapping(mData, 255.0, innerDmat, 255.0); + mData = minMaxNorm(mData, 0, 255); + //mData.copyTo(mData, mData > 0.9); + double minVal, maxVal; + minMaxIdx(mData, &minVal, &maxVal); + weightMapping(mData, maxVal); } -void ImageCompareModel::weightMapping(const Mat& mData, double maxVal, const Mat& i_mData, double i_maxVal) +void ImageCompareModel::weightMapping(const Mat& mData, double maxVal) { for (int i = 0; i < mData.rows; i++) { float* pData = (float*)mData.row(i).data; float*pWeight = (float*)falseReConMat.row(i).data; - for (int j = 0; j < mData.cols; j++) { double pixVal = pData[j]; @@ -1043,24 +773,7 @@ void ImageCompareModel::weightMapping(const Mat& mData, double maxVal, const Mat double affineCoeff = descendFunction(pixVal, maxVal); pWeight[j] *= affineCoeff; } - } - } - - - for (int i = 0; i < i_mData.rows; i++) - { - float* i_pData = (float*)i_mData.row(i).data; - float*i_pWeight = (float*)insideWeightRecon.row(i).data; - - for (int j = 0; j < i_mData.cols; j++) - { - double i_pixVal = i_pData[j]; - - if (i_pixVal != 0) - { - double affineCoeff = descendFunction(i_pixVal, i_maxVal); - i_pWeight[j] *= affineCoeff; - } + } } } @@ -1107,12 +820,10 @@ void ImageCompareModel::computeDisThre(const vector& imgVec, double* pMinDi } mDisThre = DBL_MAX; vector disVec; - std::map imgs; for_each(imgVec.begin(), imgVec.end(), [&](Mat img) { double dis = compare(img, NULL, 3, false, 1, md_diameter, md_height); disVec.push_back(dis); - imgs[dis] = img; }); double minDis = *(min_element(disVec.begin(), disVec.end())); setFalseSampleMinDis(minDis); @@ -1123,7 +834,7 @@ void ImageCompareModel::computeDisThre(const vector& imgVec, double* pMinDi } if (minDis > mTrueSampleDisMax) { - mDisThre = mTrueSampleDisMax*0.3 + minDis*0.7; + mDisThre = mTrueSampleDisMax*0.2 + minDis*0.8; //mDisThre = mTrueSampleDisMax*0.15 + minDis*0.85 + mTrueSampleDisStddev; //mDisThre = minDis; if (mDisThre > mTrueSampleDisMax*1.8) @@ -1169,7 +880,7 @@ void ImageCompareModel::genCandidateAngleRanges(vector disVec, Mat disVecMat(1, disVec.size(), CV_32FC1, &(disVec[0])); Mat normDisVecMat; - meanvarnorm(disVecMat, normDisVecMat, 0, 1.0); + /*luffy_base::luffy_imageProc::*/meanvarnorm(disVecMat, normDisVecMat, 0, 1.0); set canNums; genCandidateRepeatNums(canNums); @@ -1192,7 +903,7 @@ void ImageCompareModel::genCandidateAngleRanges(vector disVec, } else { - if (cenVec.size() >= 2 && diffAngleRaw(cenVec.front(), cenVec.back()) < 2) + if (cenVec.size() >= 2 && angleDis(cenVec.front(), cenVec.back()) < 2) { cenVec.pop_back(); } @@ -1201,7 +912,7 @@ void ImageCompareModel::genCandidateAngleRanges(vector disVec, { cen += startIdx; cen *= angleStep; - cen = normAngle(cen); + cen = angleNorm(cen); }); for (auto i = cenVec.begin(); i != cenVec.end(); ++i) { @@ -1249,9 +960,8 @@ void ImageCompareModel::genCandidateAngleRanges(const Mat& disMat, void ImageCompareModel::selfRotateMin(const Mat& img, Mat& weightMat, int repeatNum) { Point2f cen(img.cols / 2.0, img.rows / 2.0); - float angleStep = 360.0 / repeatNum; - Mat dSumMat = Mat::ones(img.size(), img.type()) * 255; - //Mat dSumMat = Mat::ones(img.size(), img.type()); + float angleStep = 360.0 / repeatNum; + Mat dSumMat = Mat::ones(img.size(), img.type())*255; for (int i = 1; i < repeatNum; ++i) { Mat rotatedImg = rotateImage(img, cen, i*angleStep); @@ -1275,38 +985,19 @@ double ImageCompareModel::genMatchValue(const Mat& rImg, const Mat& baseImg, const Mat& maskImg, int flag, int diameter, double md_diameter, double md_height) const { 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 vRImg = rImg / 255.0; Mat vDMat0 = abs(dMat) / 255.0; - //Mat vBase = baseImg.mul(m32fMaskImg) / 255.0; + Mat vBase = baseImg / 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; + Mat vMask = maskImg / 255.0; #endif - Mat minmaxScaleMat; - Mat mMask; - if (m_parallelFlag != 1) - { - 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"); - } - + + Mat minmaxScaleMat = minMaxNorm(dMat, 0, 255, m8uMaskImg); + converToType(minmaxScaleMat, CV_8UC1); + Mat mMask = lowerMajorityMask(minmaxScaleMat, m8uMaskImg, 0.97); converToType(mMask, CV_32FC1); mMask /= 255.0; @@ -1315,19 +1006,26 @@ double ImageCompareModel::genMatchValue(const Mat& rImg, const Mat& baseImg, #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; if (flag == 1) { double matchedVal = ret; - ret = penltyCoeff(matchedVal, meanDiameter, diameter, md_diameter, md_height);//做惩罚 + ret = penltyCoeff(matchedVal, meanDiameter, diameter, md_diameter, md_height); printf("the matched value %f", ret); } - printLog("myLog.txt", "finish detect, return val"); + + if (ret > mDisThre) + { + return DBL_MAX; + } + else + { return ret; + } } double ImageCompareModel::scaleMatchValue(double val) const @@ -1348,8 +1046,7 @@ ImageCompareModel* ImageCompareModel::scale(float s) pRet->setBaseImg(baseImage); pRet->setWeightMat(weightMat); - //pRet->genMask(); - pRet->genOutterMask(); + pRet->genMask(); // Mat mask8uImg; // resize(m8uMaskImg, mask8uImg, Size(), s, s, INTER_NEAREST); @@ -1390,6 +1087,33 @@ ImageCompareModel::RotateMatchResult ImageCompareModel::rotateMatch(const Mat& i rotateMatchData(img, pData, angleStep, startAngle, endAngle); } +#ifdef _TEST + if(1) + { + //if (idx == 15) + { + RotateData* pTestData = new RotateData; + rotateMatchData(img, pTestData, angleStep, startAngle, endAngle); + + stringstream ss; + ss << "multi_scale_comp_plot"; + CvPlot::clear(ss.str()); + CvPlot::plot(ss.str(), &(pTestData->mDisValVec[0]), + pTestData->mDisValVec.size()); + + float baseAngle = pTestData->bestAngle(); + float curAngle = pData->bestAngle(); + std::cout << baseAngle << " " << curAngle << " " << baseAngle - curAngle << std::endl; + delete pTestData; + if (abs(angleDis(baseAngle, curAngle)) > 1) + { + waitKey(); + } + } + idx++; + } +#endif + RotateMatchResult rmr; if (pData->mDisValVec.empty()) @@ -1414,13 +1138,11 @@ ImageCompareModel::RotateMatchResult ImageCompareModel::rotateMatch(const Mat& i void ImageCompareModel::rotateMatchData(const Mat& _img, RotateData* pData, float angleStep /*= 1.0*/, float startAngle /*= 0*/, float endAngle /*= 360*/) const { - //Mat img = _img.clone(); - if (_img.empty()) - return; - Point2f center(_img.cols / 2.0, _img.rows / 2.0); + Mat img = _img.clone(); + Point2f center(img.cols / 2.0, img.rows / 2.0); int nNum = (endAngle - startAngle) / angleStep; RotateData& data = *pData; - data.init(_img.clone(), center, angleStep, nNum); + data.init(_img, center, angleStep, nNum); data.mStartAngle = startAngle; data.mEndAngle = endAngle; @@ -1513,7 +1235,7 @@ bool isValidExtremas(const Mat& vec, const vector& lessExtremaIdxVec, float leftLessExtrema = pVec[*leftLessIdxIter]; float rightLessExtrema = pVec[*rightLessIdxIter]; - float localMaxVal = *std::max_element(pVec + *leftLessIdxIter, + float localMaxVal = *max_element(pVec + *leftLessIdxIter, pVec + *rightLessIdxIter + 1); float valRange = localMaxVal - min(leftLessExtrema, rightLessExtrema); float valTor = valRange*0.05; @@ -1549,6 +1271,11 @@ int ImageCompareModel::recognizeLowerExtremes(const Mat& vec, double vecMinVal, vecMaxVal; minMaxIdx(vec, &vecMinVal, &vecMaxVal); +#ifdef DEBUG_VIEW_PLOT + CvPlot::clear("recognizeLowerExtreams"); + CvPlot::plot("recognizeLowerExtreams", (float*)vec.data, vec.cols); +#endif + map > repeatNumLocalExtremaIdxMap; map repeatNumLocalExtremaValMap; for (auto iter = canNums.rbegin(); iter != canNums.rend(); ++iter) @@ -1695,7 +1422,7 @@ int ImageCompareModel::computeRepeatNum(const Mat& _img) vector normVec(vec); Mat vecMat(1, vec.size(), CV_32FC1, &(vec[0])); Mat normVecMat(1, normVec.size(), CV_32FC1, &(normVec[0])); - meanvarnorm(vecMat, normVecMat, 0, 1.0); + /*luffy_base::luffy_imageProc::*/meanvarnorm(vecMat, normVecMat, 0, 1.0); #ifdef DEBUG_VIEW_PLOT Mat dftVec; @@ -1712,8 +1439,12 @@ int ImageCompareModel::computeRepeatNum(const Mat& _img) Mat ddDftVec; dft(ddVecMat, ddDftVec); -// no need to code for plotting in visual studio later than 2017, -// install the ArrayPlotter extension to see the data distribution + CvPlot::plot("normVec", (float*)&(normVec[0]), normVec.size()); + CvPlot::plot("dVec", (float*)dVecMat.data, dVecMat.cols); + CvPlot::plot("ddVec", (float*)ddVecMat.data, ddVecMat.cols); + CvPlot::plot("ddft", (float*)dDftVec.data, 50); + CvPlot::plot("dft", (float*)dftVec.data, 50); + CvPlot::plot("dddft", (float*)ddDftVec.data, 50); waitKey(); #endif @@ -1755,7 +1486,7 @@ void ImageCompareModelInvoker::operator()(const cv::Range& range) const { int i0 = range.start; int i1 = range.end; - assert(abs(i1 - i0) == 1); + //assert(abs(i1 - i0) == 1); m_pModel->parallelDetect(i0, m_pData); } @@ -1765,53 +1496,12 @@ void ImageCompareModel::parallelDetect(int index, void *p) const Mat t = getRotationMatrix2D(pData->mCenter, pData->angle(index), 1.0); Mat rImg; warpAffine(pData->mImgSrc, rImg, t, pData->mImgSrc.size()); - - // need add insideImage base image; - - // .... - Mat imgRes; - if (m_parallelFlag!=1) - { - if (rImg.size() != mAlignBaseImg.size()) - { - resize(rImg, rImg, mAlignBaseImg.size()); - } - imgRes = rImg - mAlignBaseImg; - if (!m32fMaskImg.empty()) - { - if (m32fMaskImg.size() != imgRes.size()) - resize(imgRes, imgRes, m32fMaskImg.size()); - imgRes = imgRes.mul(m32fMaskImg); - if (!mWeightMat.empty()) - { - if (mWeightMat.size() != imgRes.size()) - resize(imgRes, imgRes, mWeightMat.size()); - imgRes.mul(mWeightMat); - } - } - } - else - { - if (rImg.size() != mInSideBaseImg.size()) - { - resize(rImg, rImg, mInSideBaseImg.size()); - } - - imgRes = rImg - mInSideBaseImg; - if (!m32fInsideMaskImg.empty()) - { - if (m32fInsideMaskImg.size() != imgRes.size()) - resize(imgRes, imgRes, m32fInsideMaskImg.size()); - imgRes = imgRes.mul(m32fInsideMaskImg); - if (!mInsideWeightMat.empty()) - { - if (mInsideWeightMat.size() != imgRes.size()) - resize(imgRes, imgRes, mInsideWeightMat.size()); - imgRes.mul(mInsideWeightMat); - } - } - } + if (rImg.size() != mAlignBaseImg.size()) + { + resize(rImg, rImg, mAlignBaseImg.size()); + } + Mat imgRes = rImg - mAlignBaseImg; #ifdef DEBUG_VIEW_INTERNAL_MAT Mat vRImg, vBaseImg; @@ -1819,11 +1509,15 @@ void ImageCompareModel::parallelDetect(int index, void *p) const vBaseImg = mAlignBaseImg / 255.0; Mat vImgRes = imgRes / 255.0; Mat vWeightMat = mWeightMat / 255.0; - Mat viewInsideMat = mInSideBaseImg / 255.0; -#endif - double val = 0; - if(!imgRes.empty()) - val = norm(imgRes); +#endif + + imgRes = imgRes.mul(m32fMaskImg); + + if (!mWeightMat.empty()) + { + imgRes.mul(mWeightMat); + } + double val = norm(imgRes); #ifdef DEBUG_VIEW_INTERNAL_MAT vImgRes = imgRes / 255.0; @@ -1848,14 +1542,10 @@ double ImageCompareModel::filterTrainImage(const Mat&img) } void ImageCompareModel::weightOptimization(const vector& falseSamples) { - if (falseSamples.size() <= 0) - return; reConMat = mWeightMat.clone(); - vector falseVec; - resizeVecMat(falseSamples, falseVec); - for (int i = 0; i < falseVec.size(); i++) + for (int i = 0; i < falseSamples.size(); i++) { - Mat falseSample = falseVec[i].clone(); + Mat falseSample = falseSamples[i].clone(); preWeightReconstruction(falseSample, reConMat); } mWeightMat = reConMat; @@ -1863,18 +1553,14 @@ void ImageCompareModel::weightOptimization(const vector& falseSamples) void ImageCompareModel::preWeightReconstruction(Mat img, Mat &reConImg) { - if (mAlignBaseImg.size().height <= 0 || mAlignBaseImg.size().width <= 0) - { - //mAlignBaseImg = img.clone(); - return; - } + if (mAlignBaseImg.size() != img.size()) { resize(img, img, mAlignBaseImg.size()); } Mat matchImg = img.clone(); - preProcessImage(matchImg, Mat()); + preProcessImage(matchImg); if (!mpMultiScaleModel) { @@ -1884,7 +1570,6 @@ void ImageCompareModel::preWeightReconstruction(Mat img, Mat &reConImg) Mat rImg = rmr.mBestRImg; #ifdef DEBUG_VIEW_INTERNAL_MAT - Mat ttt = mAlignBaseImg / 255.0; Mat vRImg = rImg / 255.0; #endif @@ -1912,7 +1597,7 @@ void ImageCompareModel::preWeightReconstruction(Mat img, Mat &reConImg) #endif #ifdef DEBUG_VIEW_INTERNAL_MAT - Mat vRotatedImg1 = mCompareBaseImg / 255.0; + Mat vRotatedImg1 = cmpImg / 255.0; #endif cmpImg.setTo(0, cmpImg < 10); @@ -1924,11 +1609,11 @@ void ImageCompareModel::preWeightReconstruction(Mat img, Mat &reConImg) void ImageCompareModel::weightReconstruction(const Mat& rImg, const Mat& baseImg, const Mat& maskImg, Mat &reConImg) { Mat dMat = abs(rImg - baseImg); - Mat test = dMat / 255.0; Mat norImg = Mat::ones(dMat.size(), dMat.type()) * 255; dMat = min(dMat, norImg); - Mat w(dMat.size(), dMat.type(), Scalar::all(0)); + Mat w; dMat.copyTo(w, dMat < 0.5); + w = minMaxNorm(w, 0, 1.0); for (int i = 0; i < reConImg.rows; i++) { @@ -1944,6 +1629,7 @@ void ImageCompareModel::weightReconstruction(const Mat& rImg, const Mat& baseImg } } } + } double ImageCompareModel::penltyCoeff(double matchedVal, int diameterMean, int targetDiameter, double modelDiamter, double modelHeight) const { @@ -1959,401 +1645,6 @@ double ImageCompareModel::penltyCoeff(double matchedVal, int diameterMean, int t { return matchedVal; } -} - -cv::Mat ImageCompareModel::genInsideMask(const Mat& img, Point2f center, float innerR /*= -1*/, float outterR /*= -1*/, int type /*= CV_32FC1*/) -{ - Mat mask(img.size(), CV_8UC1); - mask.setTo(0); - if (innerR == -1) - { - // default is 30 - innerR = img.rows*0.178; - //innerR = img.rows; - } - if (outterR == -1) - { - // default is max radius - 10 - outterR = img.rows*0.425; - } - //outterR = r; - /*Mat img1 = img.clone(); - - img1.convertTo(img1, CV_8UC1); - float r = allocateInnerRadius(img1); - rInner = r;*/ - circle(mask, center, outterR, Scalar(255), -1); - circle(mask, center, innerR, Scalar(0), -1); - if (type != CV_8UC1) - { - converToType(mask, type); - mask /= 255; - } - return mask; -} - -float ImageCompareModel::allocateInnerRadius(cv::Mat subImage) -{ - -// //// find global center -// const int &roughRadius = subImage.cols *0.08; -// const Point center(subImage.cols / 2.0, subImage.rows / 2.0); -// Rect rect(center.x - roughRadius, center.y - roughRadius, 2 * roughRadius, 2 * roughRadius); -// Mat centerMat = subImage(rect); -// Mat test = subImage(rect).clone(); -// genSobelImage(centerMat); -// centerMat.convertTo(centerMat, CV_8UC1); -// Mat bMat = centerMat > 100; -// //cv::threshold(centerMat, bMat, 0, 255, CV_THRESH_OTSU); -// Mat mask(bMat.size(), CV_8UC1); -// mask.setTo(0); -// //circle(mask, center, roughRadius, Scalar(255), -1); -// //cv::Mat bImage = subImage.mul(mask / 255) > 100; -// Mat dilatedImgBin; -// Mat erodeMat; -// dilate(bMat, dilatedImgBin, Mat::ones(3, 3, CV_32FC1)); -// erode(dilatedImgBin, erodeMat, Mat::ones(3, 3, CV_32FC1)); -// closeOper(erodeMat, Mat::ones(1, 3, CV_32FC1)); -// Mat vMat = erodeMat.clone(); -// vector> contours; -// findContours(erodeMat, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); -// for (int i = 0; i < contours.size(); i++) { -// const vector &pt = contours.at(i); -// if (pt.size() < 10) { -// continue; -// } -// Rect rt = boundingRect(pt); -// if (rt.width < 5 || rt.height < 5) { -// continue; -// } -// drawContours(mask, contours, i, Scalar::all(255), -1); -// } -// -// using namespace luffy_base; -// Mat hit; vector pts; -// luffy_hit::firstHit4Circle(mask, hit, pts, Point(mask.cols / 2, mask.rows / 2), 0, mask.cols / 2, 360, luffy_hit::emHitOut2In); -// luffy_imageProc::RansacParam rs(0.01, 1, 100, 80, 100);//0421 -// vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); -// float fRadius; -// Point2f ptCenter; -// bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); -//#ifdef _DEBUG -// Mat insideMat(mask.size(), mask.type(), Scalar::all(0)); -// int offset = 2; -// cv::circle(insideMat, ptCenter, fRadius, Scalar(1), -1); -// Mat ddst = insideMat.mul(test); -//#endif -// const Point globalCenter(ptCenter.x + center.x - roughRadius, ptCenter.y + center.y - roughRadius); -// -// -// -// //// find minR -// cv::Mat binaryImg = subImage > 25; -// const int innerRadius = binaryImg.rows*0.05; -// const int outterRadius = binaryImg.cols*0.22; -// Mat mmask(binaryImg.size(), CV_8UC1); -// mmask.setTo(0); -// circle(mmask, globalCenter, outterRadius, Scalar(1), -1); -// Mat dilatedImgBin1; -// Mat erodeMat1; -// dilate(binaryImg, dilatedImgBin1, Mat::ones(9, 9, CV_32FC1)); -// erode(dilatedImgBin1, erodeMat1, Mat::ones(9, 9, CV_32FC1)); -// openOper(erodeMat1, Mat::ones(1, 13, CV_32FC1)); -// circle(erodeMat1, globalCenter, innerRadius, Scalar(255), -1); -// Mat tarMat = mmask.mul(erodeMat1) > 0; -// -// vector maxCon; -// vector> m_contours; -// findContours(tarMat, m_contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); -// maxCon = m_contours.front(); -// for (const vector& contour : m_contours) -// { -// if (contour.size() > maxCon.size()) -// { -// maxCon = contour; -// } -// } -// float minDis = FLT_MAX; -// Point initialPoint = maxCon.front(); -// for (int i = 0; i < maxCon.size(); i++) -// { -// const Point& p = maxCon[i]; -// float dis = pointDis(p, globalCenter); -// if (dis < minDis) -// { -// minDis = dis; -// initialPoint = p; -// } -// } -//#ifdef _DEBUG -// Mat m_Mat(tarMat.size(), tarMat.type(), Scalar::all(0)); -// //int offset = 2; -// cv::circle(m_Mat, globalCenter, minDis, Scalar(1), -1); -// Mat d_dst = m_Mat.mul(subImage); -//#endif -// vector rst; -// rst.resize(3); -// rst[0] = minDis - 3; -// rst[1] = globalCenter.x; -// rst[2] = globalCenter.y; -// return rst; - if (subImage.size() != mAlignBaseImg.size()) - { - resize(subImage, subImage, mAlignBaseImg.size()); - } - - cv::Mat binaryImg = subImage > 30; - const int innerRadius = binaryImg.rows*0.05; - const int outterRadius = binaryImg.cols*0.22; - const Point center(binaryImg.cols / 2.0, binaryImg.rows / 2.0); - Mat mask(binaryImg.size(), CV_8UC1); - mask.setTo(0); - circle(mask, center, outterRadius, Scalar(1), -1); - Mat dilatedImgBin; - Mat erodeMat; - dilate(binaryImg, dilatedImgBin, Mat::ones(9, 9, CV_32FC1)); - erode(dilatedImgBin, erodeMat, Mat::ones(9, 9, CV_32FC1)); - openOper(erodeMat, Mat::ones(1, 13, CV_32FC1)); - circle(erodeMat, center, innerRadius, Scalar(255), -1); - Mat tarMat = mask.mul(erodeMat) > 0; - - vector maxCon; - vector> contours; - findContours(tarMat, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); - maxCon = contours.front(); - for (const vector& contour : contours) - { - if (contour.size() > maxCon.size()) - { - maxCon = contour; - } - } - float minDis = FLT_MAX; - Point initialPoint = maxCon.front(); - for (int i = 0; i < maxCon.size(); i++) - { - const Point& p = maxCon[i]; - float dis = pointDis(p, center); - if (dis < minDis) - { - minDis = dis; - 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; -} - -float ImageCompareModel::allocateRadius(cv::Mat subImage) -{ - -// //// find global center -// const int &roughRadius = subImage.cols *0.08; -// const Point center(subImage.cols / 2.0, subImage.rows / 2.0); -// Rect rect(center.x - roughRadius, center.y - roughRadius, 2 * roughRadius, 2*roughRadius); -// Mat centerMat = subImage(rect); -// Mat test = subImage(rect).clone(); -// genSobelImage(centerMat); -// centerMat.convertTo(centerMat, CV_8UC1); -// Mat bMat = centerMat > 100; -// //cv::threshold(centerMat, bMat, 0, 255, CV_THRESH_OTSU); -// Mat mask(bMat.size(), CV_8UC1); -// mask.setTo(0); -// //circle(mask, center, roughRadius, Scalar(255), -1); -// //cv::Mat bImage = subImage.mul(mask / 255) > 100; -// Mat dilatedImgBin; -// Mat erodeMat; -// dilate(bMat, dilatedImgBin, Mat::ones(3, 3, CV_32FC1)); -// erode(dilatedImgBin, erodeMat, Mat::ones(3, 3, CV_32FC1)); -// closeOper(erodeMat, Mat::ones(1, 3, CV_32FC1)); -// Mat vMat = erodeMat.clone(); -// vector> contours; -// findContours(erodeMat, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); -// for (int i = 0; i < contours.size(); i++) { -// const vector &pt = contours.at(i); -// if (pt.size() < 5) { -// continue; -// } -// Rect rt = boundingRect(pt); -// if (rt.width < 5 || rt.height < 5) { -// continue; -// } -// drawContours(mask, contours, i, Scalar::all(255), -1); -// } -// -// using namespace luffy_base; -// Mat hit; vector pts; -// luffy_hit::firstHit4Circle(mask, hit, pts, Point(mask.cols / 2, mask.rows / 2), 0, mask.cols / 2, 360, luffy_hit::emHitOut2In); -// luffy_imageProc::RansacParam rs(0.01, 1, 100, 80, 100);//0421 -// vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); -// float fRadius; -// Point2f ptCenter; -// bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); -//#ifdef _DEBUG -// Mat insideMat(mask.size(), mask.type(), Scalar::all(0)); -// //int offset = 2; -// cv::circle(insideMat, ptCenter, fRadius, Scalar(1), -1); -// Mat ddst = insideMat.mul(test); -//#endif -// const Point globalCenter(ptCenter.x + center.x - roughRadius, ptCenter.y + center.y - roughRadius); -// -// -// -// //// find minR -// cv::Mat binaryImg = subImage > 25; -// const int innerRadius = binaryImg.rows*0.05; -// const int outterRadius = binaryImg.cols*0.22; -// Mat mmask(binaryImg.size(), CV_8UC1); -// mmask.setTo(0); -// circle(mmask, globalCenter, outterRadius, Scalar(1), -1); -// Mat dilatedImgBin1; -// Mat erodeMat1; -// dilate(binaryImg, dilatedImgBin1, Mat::ones(9, 9, CV_32FC1)); -// erode(dilatedImgBin1, erodeMat1, Mat::ones(9, 9, CV_32FC1)); -// openOper(erodeMat1, Mat::ones(1, 13, CV_32FC1)); -// circle(erodeMat1, globalCenter, innerRadius, Scalar(255), -1); -// Mat tarMat =mmask.mul(erodeMat1) > 0; -// -// vector maxCon; -// vector> m_contours; -// findContours(tarMat, m_contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); -// maxCon = m_contours.front(); -// for (const vector& contour : m_contours) -// { -// if (contour.size() > maxCon.size()) -// { -// maxCon = contour; -// } -// } -// float minDis = FLT_MAX; -// Point initialPoint = maxCon.front(); -// for (int i = 0; i < maxCon.size(); i++) -// { -// const Point& p = maxCon[i]; -// float dis = pointDis(p, globalCenter); -// if (dis < minDis) -// { -// minDis = dis; -// initialPoint = p; -// } -// } -//#ifdef _DEBUG -// Mat m_Mat(tarMat.size(), tarMat.type(), Scalar::all(0)); -// //int offset = 2; -// cv::circle(m_Mat, globalCenter, minDis, Scalar(1), -1); -// Mat d_dst = m_Mat.mul(subImage); -//#endif -// //return minDis - 2; -// vector rst; -// rst.resize(3); -// rst[0] = minDis - 3; -// rst[1] = globalCenter.x; -// rst[2] = globalCenter.y; -// return rst; - - if (subImage.size() != mAlignBaseImg.size()) - { - resize(subImage, subImage, mAlignBaseImg.size()); - } - cv::Mat binaryImg = subImage > 30; - const int innerRadius = binaryImg.rows*0.05; - const int outterRadius = binaryImg.cols*0.22; - const Point center(binaryImg.cols / 2.0, binaryImg.rows / 2.0); - Mat mask(binaryImg.size(), CV_8UC1); - mask.setTo(0); - circle(mask, center, outterRadius, Scalar(1), -1); - Mat dilatedImgBin; - Mat erodeMat; - dilate(binaryImg, dilatedImgBin, Mat::ones(9, 9, CV_32FC1)); - erode(dilatedImgBin, erodeMat, Mat::ones(9, 9, CV_32FC1)); - openOper(erodeMat, Mat::ones(1, 13, CV_32FC1)); - circle(erodeMat, center, innerRadius, Scalar(255), -1); - Mat tarMat = mask.mul(erodeMat) > 0; - - vector maxCon; - vector> contours; - findContours(tarMat, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); - maxCon = contours.front(); - for (const vector& contour : contours) - { - if (contour.size() > maxCon.size()) - { - maxCon = contour; - } - } - float minDis = FLT_MAX; - Point initialPoint = maxCon.front(); - for (int i = 0; i < maxCon.size(); i++) - { - const Point& p = maxCon[i]; - float dis = pointDis(p, center); - if (dis < minDis) - { - minDis = dis; - 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; -} - -void ImageCompareModel::genOutterMask() -{ - 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); -} - -void ImageCompareModel::resizeVecMat(vector srcVec, vector &dstVec) -{ - if (srcVec.size() <= 0) - return; - dstVec.resize(srcVec.size()); - int nWidth = ((int)((float)srcVec.front().cols / COLS_SCALE / 4)) * 4; - for (int i = 0; i < srcVec.size(); i++) - { - const Mat& mat = srcVec[i]; - Mat dstMat; - cv::resize(mat, dstMat, cv::Size(nWidth, nWidth)); - dstVec[i] = dstMat; - } -} - -void ImageCompareModel::resizeMat(Mat src, Mat &dst) -{ - int nWidth = ((int)((float)src.cols / COLS_SCALE / 4)) * 4; - 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 -} - + + +} \ No newline at end of file diff --git a/src/ImageCompare/ImageCompareModel.h b/src/ImageCompare/ImageCompareModel.h index 622131c..0b1073e 100644 --- a/src/ImageCompare/ImageCompareModel.h +++ b/src/ImageCompare/ImageCompareModel.h @@ -15,8 +15,6 @@ #include #include "MultiScaleObj.h" #include "ICompareModel.h" - -#define COLS_SCALE (float)(1200.0/ 416.0) using std::set; using std::map; using std::fstream; @@ -96,14 +94,9 @@ public: float outterR = -1); static void selfRotationSimilarityFeature(const Mat& img, vector& vec, Point2f cen = Point2f(-1, -1)); - Mat genMask(const Mat& img, Point2f center, float innerR = -1, + static Mat genMask(const Mat& img, Point2f center, float innerR = -1, float outterR = -1, int type = CV_32FC1); - - Mat genInsideMask (const Mat& img, Point2f center, float innerR = -1, - float outterR = -1, - int type = CV_32FC1); - static void genCandidateRepeatNums(set& canNums); int computeRepeatNum(const Mat& img); static int recognizeLowerExtremes(const Mat& vec, set canNums, int extremeRefineRange = 5, vector *pExtemeIdxVec = 0); @@ -115,42 +108,38 @@ public: static void genCandidateAngleRanges(const Mat& disMat, float angleStep, vector& rangeVec, float rangeScale = 1); static void selfRotateMin(const Mat& img, Mat& weightMat, int repeatNum); - float allocateInnerRadius(cv::Mat subImage); - float allocateRadius(cv::Mat subImage); - void resizeVecMat(vector srcVec, vector &dstVec); - void resizeMat(Mat src, Mat &dst); + + public: - ImageCompareModel() : - mMatchValScale(1.0), - mTargetMeanVal(127), - mTargetStddevVal(50), - mHighlightsThreshold(256), - mRepeatNum(0), - mName("unnamed"), - mDisThre(DBL_MAX), - mTrueSampleDisMin(DBL_MAX), - mTrueSampleDisMax(DBL_MIN), - mTrueSampleDisMean(-1), - mTrueSampleDisStddev(-1), - mIsEnableCache(false), - mpMultiScaleModel(NULL), + ImageCompareModel() : + mMatchValScale(1.0), + mTargetMeanVal(127), + mTargetStddevVal(50), + mHighlightsThreshold(256), + mRepeatNum(0), + mName("unnamed"), + mDisThre(DBL_MAX), + mTrueSampleDisMin(DBL_MAX), + mTrueSampleDisMax(DBL_MIN), + mTrueSampleDisMean(-1), + mTrueSampleDisStddev(-1), + mIsEnableCache(false), + mpMultiScaleModel(NULL), meanDiameter(0), realWidth(0), - realHeight(0), - rInner(DBL_MAX) + realHeight(0) {}; ImageCompareModel(const ImageCompareModel& model) : mAlignBaseImg(model.getBaseImg().clone()) , mWeightMat(model.getWeightMat().clone()) , mMatchValScale(model.getMatchValScale()) - , mInSideBaseImg(model.getInsideBaseImg().clone()) - , mInsideWeightMat(model.getInsideWeightImg().clone()) { genMask(); } ~ImageCompareModel() {}; void printInfo(); + void saveImages(string dirPath); bool save2file(string filePath); bool readFromFile(string filePath); @@ -159,8 +148,6 @@ public: { mAlignBaseImg = model.getBaseImg().clone(); mWeightMat = model.getWeightMat().clone(); - mInSideBaseImg = model.getInsideBaseImg().clone(); - mInsideWeightMat = model.getInsideWeightImg().clone(); mMatchValScale = model.getMatchValScale(); mTargetMeanVal = model.getTargetMeanVal(); mTargetStddevVal = model.getTargetStddevVal(); @@ -170,68 +157,61 @@ public: mTrueSampleDisMax = model.getDisMax(); mTrueSampleDisMin = model.getDisMin(); meanDiameter = model.getMeanDiamter(); - rInner = model.getInnerR(); } void genMask(); - void genOutterMask(); - void preProcessImage(Mat& img, Mat &insideImg) const; + + void preProcessImage(Mat& img) const; 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 compare(Mat img, 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); + void train(const vector& imgVec); void calculateAllParams(const vector& imgVec); - void trueSampleWeightRecon(const vector& resizedVec, const vector& resizedCenterVec, vector rmrVec, - vector rmrVecInside); - void trueWeightRecon(const Mat& rImg, const Mat& baseImg, const Mat& insideRimg, const Mat& insideBaseImg); - void weightMapping(const Mat& weight, double maxVal, const Mat& i_mData, double i_maxVal); + void trueSampleWeightRecon(const vector& resizedVec, vector rmrVec); + void trueWeightRecon(const Mat& rImg, const Mat& baseImg); + void weightMapping(const Mat& weight, double maxVal); //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; } - float getInnerR() const { return rInner; } - - virtual Mat getBaseImg() const { return mAlignBaseImg; } + Mat getBaseImg() const { return mAlignBaseImg; } void setBaseImg(const Mat& img) { mAlignBaseImg = img; } @@ -259,17 +239,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接口输入的img参数的data指针作为key存储 - // 差异值。 + //! û档ὫÿεcompareӿimgdataָΪkey洢 + // ֵ /*! \return void */ @@ -300,16 +280,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; - + + 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); @@ -333,24 +313,16 @@ protected: Mat mDisMat; Mat reConMat; Mat falseReConMat; - Mat insideWeightRecon; - Mat innerTempl; - double mDisThre{ DBL_MAX }; + double mDisThre; string mName; double falseMinDis; int meanDiameter; int realWidth; int realHeight; - // INSIDE PART - Mat mInSideBaseImg, mInsideCompareBaseImg; - Mat mInsideWeightMat; - Mat m32fInsideMaskImg, m8uInsideMaskImg; - float rInner; - float x_aix; - float y_aix; + // some training data - double mTrueSampleDisStddev, mTrueSampleDisMean, mTrueSampleDisMax{DBL_MAX}, mTrueSampleDisMin; + double mTrueSampleDisStddev, mTrueSampleDisMean, mTrueSampleDisMax, mTrueSampleDisMin; double mFalseSampleMinDis; // temp data @@ -361,8 +333,6 @@ protected: // cache bool mIsEnableCache; map mDisCache; -public: - static int m_parallelFlag; private: }; diff --git a/src/ImageCompare/MultiScaleImageCompareModel.cpp b/src/ImageCompare/MultiScaleImageCompareModel.cpp index a849b1c..d98364d 100644 --- a/src/ImageCompare/MultiScaleImageCompareModel.cpp +++ b/src/ImageCompare/MultiScaleImageCompareModel.cpp @@ -1,11 +1,13 @@ #include "MultiScaleImageCompareModel.h" #include "ImageCompareModel.h" +//#include "../3rd/cvplot/cvplot.h" + void MultiScaleImageCompareModel::setBaseLevel(const ImageCompareModel* pModel) { ImageCompareModel* p = new ImageCompareModel; *p = *pModel; - p->genOutterMask(); + p->genMask(); clear(); mMultiScaleModels.resize(1); mMultiScaleModels[0] = p; @@ -16,14 +18,9 @@ void MultiScaleImageCompareModel::genMultiScale() resetMaxLevel(); while (getLevel() >= 1) { - if (mMultiScaleModels.size()>1) - { - ImageCompareModel* pScaledModel = mMultiScaleModels.back()->scale(mScaleStep); - mMultiScaleModels.push_back(pScaledModel); - downLevel(); - } - else - downLevel(); + ImageCompareModel* pScaledModel = mMultiScaleModels.back()->scale(mScaleStep); + mMultiScaleModels.push_back(pScaledModel); + downLevel(); } } @@ -58,19 +55,11 @@ void MultiScaleImageCompareModel::proc(void *pData) vector angleRangeVec(1, Range(0, 360)); ImageCompareModel::RotateData* pRotateData = pCmpData->getRotateData(); - int nlevel = getLevel(); - while (nlevel >= 0) - { - nlevel = getLevel(); - if (nlevel<0) - break; - const ImageCompareModel* pModel = NULL; - if (nlevel >= mMultiScaleModels.size()) - pModel = mMultiScaleModels[0]; - else - pModel = mMultiScaleModels[nlevel]; + while (getLevel() >= 0) + { + const ImageCompareModel* pModel = mMultiScaleModels[getLevel()]; assert(pModel); - Mat img = pMSImg->getImg(nlevel); + Mat img = pMSImg->getImg(getLevel()); assert(!img.empty()); @@ -111,6 +100,26 @@ void MultiScaleImageCompareModel::proc(void *pData) // Mat viewBestRImg = pRotateData->bestRImg() / 255.0; // imshow("bestRImg", viewBestRImg); #endif + +#ifdef DEBUG_VIEW_PLOT + { + stringstream ss; + ss << "multi_scale_comp_plot" << getLevel(); + CvPlot::clear(ss.str()); + CvPlot::plot(ss.str(), &(pRotateData->mDisValVec[0]), + pRotateData->mDisValVec.size()); + } + { + stringstream ss; + ss << "multi_scale_comp_plot_0_360_" << getLevel(); + CvPlot::clear(ss.str()); + ImageCompareModel::RotateData testRotateData = *pRotateData; + pModel->rotateMatchData(img, &testRotateData, 1.0, startAngle, endAngle); + CvPlot::plot(ss.str(), &(testRotateData.mDisValVec[0]), + testRotateData.mDisValVec.size()); + } +#endif + downLevel(); } } diff --git a/src/interface/readme.txt b/src/interface/readme.txt new file mode 100644 index 0000000..892c277 --- /dev/null +++ b/src/interface/readme.txt @@ -0,0 +1 @@ +接口文件 公用 \ No newline at end of file diff --git a/src/tpMain/ThreadVector.cpp b/src/tpMain/ThreadVector.cpp deleted file mode 100644 index 4008bde..0000000 --- a/src/tpMain/ThreadVector.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "ThreadVector.h" - - -ThreadVector::ThreadVector() -{ -} - - -ThreadVector::~ThreadVector() -{ -} diff --git a/src/tpMain/ThreadVector.h b/src/tpMain/ThreadVector.h deleted file mode 100644 index 00a3d14..0000000 --- a/src/tpMain/ThreadVector.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -enum EM_THREAD_TASK { - emThreadSendState, emThreadSendLib, emThread -}; -class ThreadVector -{ -public: - ThreadVector(); - ~ThreadVector(); - -}; - diff --git a/tpvs17/tpMain/QModelMgrDlg.cpp b/tpvs17/tpMain/QModelMgrDlg.cpp index a6aa9b7..9563048 100644 --- a/tpvs17/tpMain/QModelMgrDlg.cpp +++ b/tpvs17/tpMain/QModelMgrDlg.cpp @@ -47,7 +47,6 @@ QModelMgrDlg::QModelMgrDlg(IWheelCtrl *ptr, QWidget *parent) m_pShowImgList = ui.listWidget; m_pModelMgr = m_pCtrl->getModelMgr(); -// m_pState = m_pCtrl->getDetectState(); m_trainAllTsk = new QMyThread(); m_trainAllTsk->setUser(true); @@ -58,9 +57,7 @@ QModelMgrDlg::QModelMgrDlg(IWheelCtrl *ptr, QWidget *parent) m_trainOneTsk->loadfunc(this, &QModelMgrDlg::TrainOneTskFunc); -// m_pProgressView = new ProgressView(this); -// m_pProgressView->setUseCancel(true); -// connect(m_pProgressView, SIGNAL(cancel()), this, SLOT(onProgassCancel())); + //m_pProgressView->finish(); connect(this, SIGNAL(sgPrograssShow(QString, QString, int, int)), this, SLOT(onPrograssShow(QString, QString, int, int))); connect(this, SIGNAL(sgShowMsg(QString)), this, SLOT(onShowMessage(QString))); @@ -357,6 +354,13 @@ Q_SLOT void QModelMgrDlg::onItemDoubleClicked(QListWidgetItem * item) Q_SLOT void QModelMgrDlg::onPrograssShow(QString title, QString strValue, int size, int model) { + if (!m_pProgressView) + { + m_pProgressView = new ProgressView(this); + m_pProgressView->setUseCancel(true); + connect(m_pProgressView, SIGNAL(cancel()), this, SLOT(onProgassCancel())); + //return; + } switch (model) { case emPross_Init: diff --git a/tpvs17/tpMain/tpMain.vcxproj b/tpvs17/tpMain/tpMain.vcxproj index f458a57..53ca5b0 100644 --- a/tpvs17/tpMain/tpMain.vcxproj +++ b/tpvs17/tpMain/tpMain.vcxproj @@ -55,7 +55,6 @@ - @@ -486,7 +485,6 @@ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DTPMAIN_LIB -DTPMAIN_EXPORTS -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_SQL_LIB -DQT_PRINTSUPPORT_LIB -DQT_NETWORK_LIB -DQT_SERIALPORT_LIB -D%(PreprocessorDefinitions) "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\ActiveQt" "-I$(QTDIR)\include\QtSerialPort" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtPrintSupport" "-I$(QTDIR)\include\QtSql" "-I$(QTDIR)\include\QtNetwork" "-I.\..\..\..\spider\libZK" "-I.\..\..\..\tadpole\include" "-I.\..\..\..\tadpole\src\SubFilters" "-I.\..\..\..\tadpole\src\SubFilters\tpSubFilterDemo" "-I.\..\..\..\tadpole\src\tpGui" "-I.\..\..\..\tadpole\src\tpBase" "-I.\..\..\..\tadpole\src\lpbengine" "-I.\..\..\..\tadpole\src\tpNet" "-I.\..\..\..\tadpole\src\lpdesigner" "-I.\..\..\..\tadpole\src\tpMain" "-I.\..\..\..\tadpole\src\tpSubFilter" "-I.\..\..\..\tadpole\src\libzkq" "-I.\..\..\..\tadpole\src\tpAssister" "-I.\..\..\include\tpMain" "-I.\..\..\include\tpMain\SubFilters" "-I.\..\include" "-I.\..\..\..\lpOpenCV\opencv2.4.9\build\include" "-I.\..\..\..\lpOpenCV\opencv2.4.9\build\include\opencv2" "-I.\..\..\..\lpOpenCV\opencv2.4.9\build\include\opencv" "-I.\..\..\..\Cyclops\include" "-I.\..\..\src\algorithm" "-I.\..\..\include" "-I.\..\..\.\src\tpMain" "-I.\..\..\.\src\tpMain\thread" "-I.\..\..\.\src\tpMain\splashScreen" "-I.\..\..\.\src\tpMain\LightBoxwidget" "-I.\..\..\.\src\tpMain\QDiskCleanThread" "-I.\..\..\.\src\tpMain\QPixmapListBar" "-I.\..\..\.\src\userCtrl" "-I.\..\..\.\src\NetWheel" "-I.\..\..\.\src\RasterSDG20" "-I.\..\..\.\src\ReportModel" - $(QTDIR)\bin\moc.exe;%(FullPath) diff --git a/tpvs17/tpMain/tpMain.vcxproj.filters b/tpvs17/tpMain/tpMain.vcxproj.filters index 67f638b..f3dcb4c 100644 --- a/tpvs17/tpMain/tpMain.vcxproj.filters +++ b/tpvs17/tpMain/tpMain.vcxproj.filters @@ -329,9 +329,6 @@ Source Files - - Source Files - Source Files @@ -616,9 +613,6 @@ Header Files - - Header Files - Header Files