From 1d2d81c703104725b412be0f8c807c7af06ef7ea Mon Sep 17 00:00:00 2001 From: qushuai777 Date: Sat, 20 Feb 2021 15:04:19 +0800 Subject: [PATCH] update algo --- src/ImageCompare/ImageCompareModel.cpp | 52 +++++----- src/ImageCompare/ImageCompareModel.h | 8 +- src/algorithm/AlgorithmFluorescence.cpp | 125 +++++++++++++++++++----- src/algorithm/ImageProcess.cpp | 122 +++++++++++------------ src/interface/ICompareModel.h | 2 + 5 files changed, 198 insertions(+), 111 deletions(-) diff --git a/src/ImageCompare/ImageCompareModel.cpp b/src/ImageCompare/ImageCompareModel.cpp index ff2674d..76b37d5 100644 --- a/src/ImageCompare/ImageCompareModel.cpp +++ b/src/ImageCompare/ImageCompareModel.cpp @@ -380,7 +380,11 @@ bool ImageCompareModel::readFromFile(string filePath) { rInner = (float)fn; } - + fn = fs[IMGCMP_STR_INSIDE_CIRCLE_NUM]; + if (!fn.empty()) + { + mInnerCircleNum = (double)fn; + } setFilePath(filePath); genMask(); @@ -734,27 +738,6 @@ void ImageCompareModel::train(const vector& vec) { Mat originalMat = vec[i]; - EDCircles edCircles(originalMat); - std::vector circles = edCircles.getCircles(); - float rMax = 0; - float rMaxInside = 0; - const int circlesSize = circles.size(); - for (int j = 0; j < circlesSize; ++j) - { - double radius = circles[j].r; - if (radius > rMax) - { - rMax = radius; - } - } - for (int j = 0; j < circlesSize; ++j) - { - double radius = circles[j].r; - if (radius < rMax * MAX_INSIDE_RATIO && radius > rMax * MIN_INSIDE_RATIO) - { - insideCircleNumSum++; - } - } Vec3f bestCircle; Point2f p = Point2f(originalMat.cols / 2.0, originalMat.rows / 2.0); @@ -797,12 +780,33 @@ void ImageCompareModel::train(const vector& vec) // { // int a = 0; // } - 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; originalMat(rect).copyTo(origianlCenterMat); + + EDCircles edCircles(origianlCenterMat); + std::vector circles = edCircles.getCircles(); + float rMax = 0; + float rMaxInside = 0; + const int circlesSize = circles.size(); + for (int j = 0; j < circlesSize; ++j) + { + double radius = circles[j].r; + if (radius > rMax) + { + rMax = radius; + } + } + for (int j = 0; j < circlesSize; ++j) + { + double radius = circles[j].r; + if (radius < rMax * MAX_INSIDE_RATIO && radius > rMax * MIN_INSIDE_RATIO) + { + insideCircleNumSum++; + } + } centerMatVec.push_back(origianlCenterMat); tmpVec.push_back(vec[i]); @@ -1868,6 +1872,8 @@ void ImageCompareModelInvoker::operator()(const cv::Range& range) const int i0 = range.start; int i1 = range.end; assert(abs(i1 - i0) == 1); + //if (abs(i1 - i0) == 1) + // return; m_pModel->parallelDetect(i0, m_pData); } diff --git a/src/ImageCompare/ImageCompareModel.h b/src/ImageCompare/ImageCompareModel.h index ede894d..826d796 100644 --- a/src/ImageCompare/ImageCompareModel.h +++ b/src/ImageCompare/ImageCompareModel.h @@ -24,6 +24,7 @@ /*#include "CircleDetector.h"*/ #define COLS_SCALE (float)(1200.0/ 416.0) +//#define COLS_SCALE (float)(1200.0/ 600.0) using std::set; using std::map; using std::fstream; @@ -138,7 +139,7 @@ public: realWidth(0), realHeight(0), rInner(DBL_MAX), - mInnerCircleNum(0) + mInnerCircleNum(0.0) {}; ImageCompareModel(const ImageCompareModel& model) : mAlignBaseImg(model.getBaseImg().clone()) @@ -172,6 +173,7 @@ public: mTrueSampleDisMin = model.getDisMin(); meanDiameter = model.getMeanDiamter(); rInner = model.getInnerR(); + mInnerCircleNum = model.getInnerCircleNum(); } void genMask(); @@ -231,7 +233,7 @@ public: Mat getInsideBaseImg() const { return mInSideBaseImg; } Mat getInsideWeightImg() const { return mInsideWeightMat; } float getInnerR() const { return rInner; } - float getInnerCircleNum() const { return mInnerCircleNum; } + double getInnerCircleNum() const { return mInnerCircleNum; } Mat getBaseImg() const { return mAlignBaseImg; } @@ -349,7 +351,7 @@ protected: float rInner; float x_aix; float y_aix; - float mInnerCircleNum; + double mInnerCircleNum; diff --git a/src/algorithm/AlgorithmFluorescence.cpp b/src/algorithm/AlgorithmFluorescence.cpp index abc983b..4a333bc 100644 --- a/src/algorithm/AlgorithmFluorescence.cpp +++ b/src/algorithm/AlgorithmFluorescence.cpp @@ -14,8 +14,11 @@ #pragma execution_character_set("utf-8") -#define MIN_INSIDE_RATIO 0.012 -#define MAX_INSIDE_RATIO 0.023 +#define MAX_CIRCLE_RADII 110 +#define MIN_INSIDE_RATIO 0.038 +#define MAX_INSIDE_RATIO 0.072 +#define INSIDE_NUM_DIS_THRE 1.5 + using namespace cv; using namespace lp; @@ -54,8 +57,11 @@ QString CAlgorithmFluorescence::bestMatch(const QMap* mod if (!modelMap) return bestName; QStringList strDetectModels = pLocal->defectList; - cv::Mat img = pLocal->img; + int similarNum = 0; + const QString hubName1("DH151079"); + const QString hubName2("DK151050"); + QMap simularModelMap; while (strDetectModels.size()) { QString strModelName = strDetectModels.takeFirst(); @@ -90,10 +96,16 @@ QString CAlgorithmFluorescence::bestMatch(const QMap* mod pModel->setIsEnableCache(false); - double dis = pModel->compare(img, NULL, true, 1); + double dis = pModel->compare(pLocal->img, NULL, true, 1); + double disThre = pModel->getDisThre(); + double innerCircleNum = pModel->getInnerCircleNum(); + if (dis < disThre) + { + similarNum++; + simularModelMap[name] = innerCircleNum; + } disVec[nIndex] = dis; -/* std::map disMap; - disMap[dis] = name;*/ + if (dis < minDis && dis != -1) { minDis = dis; @@ -101,6 +113,7 @@ QString CAlgorithmFluorescence::bestMatch(const QMap* mod } nIndex++; } + if (pMinDis) { *pMinDis = minDis; @@ -110,33 +123,96 @@ QString CAlgorithmFluorescence::bestMatch(const QMap* mod sort(disVec.begin(), disVec.end()); std::copy_n(disVec.begin(), minDisNum, pMinDis); } - //if (0) - //{ - // EDCircles edCircles(img); - // std::vector circles = edCircles.getCircles(); - // const int nSize = circles.size(); - // float rMax = 0; + if (similarNum < 1) + { + return bestName; + } + const cv::Mat originalMat = pLocal->img; + 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); + cv::Mat centerMat = originalMat(rect).clone(); + EDCircles edCircles(centerMat); + std::vector circles = edCircles.getCircles(); + const int nSize = circles.size(); + float rMax = 0; + + for (int i = 0; i < nSize; ++i) + { + float radius = circles[i].r; + if (radius > rMax) + { + rMax = radius; + } + } + double innerCircleNumSum = 0; + double rMaxUp = rMax * MAX_INSIDE_RATIO; + double rMaxLow = rMax * MIN_INSIDE_RATIO; + for (int i = 0; i < nSize; ++i) + { + double radius = circles[i].r; + if (radius < rMaxUp && radius > rMaxLow * MIN_INSIDE_RATIO) + { + innerCircleNumSum++; + } + } + if (bestName.toUpper() == hubName1) + { + if (innerCircleNumSum > 1) + { + bestName = hubName2; + } + } + else if (bestName.toUpper() == hubName2) + { + if (innerCircleNumSum < 2) + { + bestName = hubName1; + } + } - // for (int i = 0; i < nSize; ++i) + //if (similarNum == 1) + //{ + // double dis = std::fabs(innerCircleNumSum - simularModelMap.begin().value()); + // if (dis > INSIDE_NUM_DIS_THRE) // { - // float radius = circles[i].r; - // if (radius > rMax) - // { - // rMax = radius; - // } + // bestName = QString(); // } - // float insideCircleNumSum = 0; - // for (int i = 0; i < nSize; ++i) + //} + //if (similarNum > 1) + //{ + // auto iterEnd = simularModelMap.constEnd(); + // double disMin = DBL_MAX; + + // for (auto iter = simularModelMap.constBegin(); iter != iterEnd; ++iter) // { - // double radius = circles[i].r; - // if (radius < rMax * MAX_INSIDE_RATIO && radius > rMax * MIN_INSIDE_RATIO) + // double dis = std::fabs(innerCircleNumSum - iter.value()); + // if (dis < disMin) // { - // insideCircleNumSum++; + // disMin = dis; + // bestName = iter.key(); // } // } - // //if() //} + + //auto iterEnd = simularModelMap.constEnd(); + //bool bestMatchFlag = false; + //for (auto iter = simularModelMap.constBegin(); iter != iterEnd; ++iter) + //{ + // double dis = std::fabs(innerCircleNumSum - iter.value()); + // if (dis < INSIDE_NUM_DIS_THRE) + // { + // bestName = iter.key(); + // bestMatchFlag = true; + // break; + // } + //} + //if (!bestMatchFlag) + //{ + // bestName = QString(); + //} + return bestName; } @@ -164,6 +240,7 @@ int CAlgorithmFluorescence::IImageAnalysis(class IImageObject* pImgObj, TP_ALGOR bool useDiameter = vMap.value("useDiameter", 0).toBool(); double dD2H = vMap.value("d2h", -1).toDouble(); int nthreshold = vMap.value("Threshold", 15).toInt(); + bool bUseBackground = vMap.value("useBackground").toBool(); if (nthreshold <= 0) nthreshold = 15; diff --git a/src/algorithm/ImageProcess.cpp b/src/algorithm/ImageProcess.cpp index 9eef3af..1995fa9 100644 --- a/src/algorithm/ImageProcess.cpp +++ b/src/algorithm/ImageProcess.cpp @@ -5,7 +5,7 @@ #include "EDLines.h" #include "EDCircles.h" //鎽╄疆瀹忓畾涔 琛ㄧず璇ョ畻娉曠敤浜庢懇杞瀷鍙疯瘑鍒娴 -//#define MOTO_DETECT +#define MOTO_DETECT ImageProcess::ImageProcess() { @@ -50,66 +50,66 @@ cv::Mat ImageProcess::findCircleObject(const Mat &src, const Mat& backgroundImg, } //_EnhanImg_sharpen(); assert(backgroundImg.type() == CV_8UC1); - //Mat detectImg; - //cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); - //int bBaseX = detectImg.cols; - //int bBaseY = detectImg.rows; - ////if (nThres<=1) - //equalizeHist(detectImg, detectImg); - //detectImg = _EnhanImg_sharpen(detectImg); - - //EDCircles edcircles(detectImg); - //vector EDCircle = edcircles.getCircles(); - //double maxR = 0; - //int nIndex = -1; - //for (int i = 0; i < EDCircle.size(); i++) - //{ - // int startX = EDCircle[i].center.x - EDCircle[i].r; - // int startY = EDCircle[i].center.y - EDCircle[i].r; - // if (startX < 0 || startY <0) - // continue; - // if (EDCircle[i].center.x + EDCircle[i].r>bBaseX || EDCircle[i].center.y + EDCircle[i].r>bBaseY) - // continue; - // if (EDCircle[i].r > maxR) - // { - // maxR = EDCircle[i].r; - // nIndex = i; - // } - //} - //if (nIndex != -1) - //{ - // int startX = EDCircle[nIndex].center.x * REAIZE - EDCircle[nIndex].r * REAIZE; - // int startY = EDCircle[nIndex].center.y * REAIZE - EDCircle[nIndex].r* REAIZE; - // double radius = EDCircle[nIndex].r; - // int hight = 2 * radius * REAIZE; - // - // if (startX > 0 && startY > 0 && hight > 0 \ - // && startX < src.cols &&startY < src.rows \ - // &&hight < src.cols&&hight < src.rows \ - // && startX+hightptCenter = center; - - // //float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; - // //pCircle->fRadius = hight*1.0 / fScale; - // pCircle->fRadius = radius * REAIZE; - // return cutMat; - // } - // } - //} - //return Mat(); + Mat detectImg; + cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); + int bBaseX = detectImg.cols; + int bBaseY = detectImg.rows; + //if (nThres<=1) + equalizeHist(detectImg, detectImg); + detectImg = _EnhanImg_sharpen(detectImg); + + EDCircles edcircles(detectImg); + vector EDCircle = edcircles.getCircles(); + double maxR = 0; + int nIndex = -1; + for (int i = 0; i < EDCircle.size(); i++) + { + int startX = EDCircle[i].center.x - EDCircle[i].r; + int startY = EDCircle[i].center.y - EDCircle[i].r; + if (startX < 0 || startY <0) + continue; + if (EDCircle[i].center.x + EDCircle[i].r>bBaseX || EDCircle[i].center.y + EDCircle[i].r>bBaseY) + continue; + if (EDCircle[i].r > maxR) + { + maxR = EDCircle[i].r; + nIndex = i; + } + } + if (nIndex != -1) + { + int startX = EDCircle[nIndex].center.x * REAIZE - EDCircle[nIndex].r * REAIZE; + int startY = EDCircle[nIndex].center.y * REAIZE - EDCircle[nIndex].r* REAIZE; + double radius = EDCircle[nIndex].r; + int hight = 2 * radius * REAIZE; + + if (startX > 0 && startY > 0 && hight > 0 \ + && startX < src.cols &&startY < src.rows \ + &&hight < src.cols&&hight < src.rows \ + && startX+hightptCenter = center; + + //float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + //pCircle->fRadius = hight*1.0 / fScale; + pCircle->fRadius = radius * REAIZE; + return cutMat; + } + } + } + return Mat(); diff --git a/src/interface/ICompareModel.h b/src/interface/ICompareModel.h index d22dad3..67923b3 100644 --- a/src/interface/ICompareModel.h +++ b/src/interface/ICompareModel.h @@ -36,6 +36,8 @@ public: virtual double getDisMin() const = 0; virtual double getDisMax() const = 0; + virtual double getInnerCircleNum() const = 0; + virtual double getFalseSampleMinDis() const = 0; virtual double getMeanDiamter() const = 0;