diff --git a/src/algorithm/AlgorithmCompare.cpp b/src/algorithm/AlgorithmCompare.cpp index a626764..87dd829 100644 --- a/src/algorithm/AlgorithmCompare.cpp +++ b/src/algorithm/AlgorithmCompare.cpp @@ -302,7 +302,19 @@ int CAlgorithmCompare::IImageAnalysis(class IImageObject* pImgObj) bReload = false; } //imageSegementation(matSrc); - matMatch = ImageProcess::findCircleObject(matSrc, matBack, bUseBackground, nthreshold/*15*/, &lCircle/* NULL*/); + //matMatch = ImageProcess::findCircleObject(matSrc, matBack, bUseBackground, nthreshold/*15*/, &lCircle/* NULL*/); + Point2f centerPoint; + double radius = 0; + matMatch = ImageProcess::findCircle(matSrc, centerPoint, radius); + lCircle.ptCenter = centerPoint; + lCircle.fRadius = radius; + + if (matMatch.cols >= 900 || matMatch.rows >= 900) + { + + cv::resize(matMatch, matMatch, cv::Size(matMatch.cols / 2, matMatch.rows / 2)); + lCircle.fRadius = lCircle.fRadius / 2; + } } else{ matMatch = matSrc; @@ -387,11 +399,9 @@ cv::Mat CAlgorithmCompare::getBackGroundImage(class IImageObject *pObj, bool bRe if (matback.empty()) { QString filepath = ".\\user\\background.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); - //matback = cv::imread(filepath.toLatin1().data(), 0); if (matback.empty()) { QString filepath = "\\user\\background_r.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); - //matback = cv::imread(filepath.toLatin1().data(), 0); cv::flip(matback, matback, 1); } } @@ -402,7 +412,6 @@ cv::Mat CAlgorithmCompare::getBackGroundImage(class IImageObject *pObj, bool bRe if (matback.empty()) { QString filepath = "\\user\\background_r.png"; matback = cv::imread(string((const char *)filepath.toLocal8Bit()), 0); - //matback = cv::imread(filepath.toLatin1().data(), 0); cv::flip(matback, matback, 1); } } diff --git a/src/algorithm/ImageProcess.cpp b/src/algorithm/ImageProcess.cpp index 46b7f4c..8d3dcb8 100644 --- a/src/algorithm/ImageProcess.cpp +++ b/src/algorithm/ImageProcess.cpp @@ -4,6 +4,9 @@ #include "ED.h" #include "EDLines.h" #include "EDCircles.h" + +#include "CircleDetector.h" + //摩轮宏定义 表示该算法用于摩轮型号识别检测 #define MOTO_DETECT @@ -11,7 +14,6 @@ ImageProcess::ImageProcess() { } - ImageProcess::~ImageProcess() { @@ -48,7 +50,6 @@ Mat findEdge2(const Mat &Src) cv::Mat ImageProcess::findCircleObject(const Mat &srcImg, const Mat& backgroundImg, bool useBackgroundFlag, int nThres /*= 20*/, luffy_base::luffyCircle *pCircle /*= NULL*/) { #ifdef MOTO_DETECT//摩轮型号识别抠图算法 - //useBackgroundFlag = true; if (!useBackgroundFlag) { Mat detectImg; @@ -571,4 +572,86 @@ cv::Mat ImageProcess::getForeImage(const Mat & src, const Mat &backgroundImg) } return (src - resizedBackgroundImg); } +//输入一张灰度图,输出抠出的圆小图和半径,圆心坐标 +cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center ,double &radius) +{ + Mat detectImg; + Mat src = srcImg; + + cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); + int bBaseX = detectImg.cols; + int bBaseY = detectImg.rows; + 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; + radius = EDCircle[nIndex].r; + int hight = 2 * radius * REAIZE; + + center.x = (EDCircle[nIndex].center.x * REAIZE); + center.y = (EDCircle[nIndex].center.y * REAIZE); + radius = radius * REAIZE; + return DetectCircle(srcImg, center, radius); + } + else { + center.x = 0; + center.y = 0; + radius = 0; + return Mat(); + } +} + +Mat ImageProcess::DetectCircle(Mat img, Point2f& center, double& radius) +{ + Mat detectImg; + equalizeHist(img, detectImg); + CircleDetector cd; + cd.setAlgoType(CircleDetector::PeakCircle); + cd.setEdgeWidth(3); + cd.setPolarity(Polarity::White2Black); + cd.setFindBy(FindBy::Best); + cd.setRadii(radius - 100, radius + 150); + cd.setACThres(3); + vector allScores; + Vec3f bestCircle; + float bestScore = cd.detectBest(detectImg, Point2f(center.x, center.y), bestCircle, &allScores); + if (abs(bestScore) <= FLT_EPSILON || bestCircle == Vec3f::zeros()) { + center.x = 0; + center.y = 0; + radius = 0; + return Mat(); + } + Point2f cen(bestCircle[0], bestCircle[1]); + double r = bestCircle[2]; + Rect rect; + rect.x = cen.x - r; + rect.y = cen.y - r; + rect.width = 2 * r; + rect.height = 2 * r; + Mat s = img(rect); + center = cen; + radius = r; + return s; +} \ No newline at end of file diff --git a/src/algorithm/ImageProcess.h b/src/algorithm/ImageProcess.h index ecc3fbe..6d5098d 100644 --- a/src/algorithm/ImageProcess.h +++ b/src/algorithm/ImageProcess.h @@ -23,6 +23,8 @@ public: static cv::Mat findCircleObject(const Mat &src, const Mat& backgroundImg, bool useBackgroundFlag, int nThres = 20, luffy_base::luffyCircle *pCircle = NULL); static cv::Mat getForeImage(const Mat & src, const Mat &backgroundImg); + static cv::Mat findCircle(const Mat &srcImg, Point2f& center, double &radius);//找圆 + static cv::Mat DetectCircle(Mat img, Point2f& center, double& radius);//精细找圆 }; #endif diff --git a/tpvs17/AlgoTest.sln b/tpvs17/AlgoTest.sln new file mode 100644 index 0000000..6bc2bd1 --- /dev/null +++ b/tpvs17/AlgoTest.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1585 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlgoTest", "AlgoTest\AlgoTest.vcxproj", "{9432FDF3-AEA1-4095-BD7B-63EC9C79EA89}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9432FDF3-AEA1-4095-BD7B-63EC9C79EA89}.Debug|x64.ActiveCfg = Debug|x64 + {9432FDF3-AEA1-4095-BD7B-63EC9C79EA89}.Debug|x64.Build.0 = Debug|x64 + {9432FDF3-AEA1-4095-BD7B-63EC9C79EA89}.Release|x64.ActiveCfg = Release|x64 + {9432FDF3-AEA1-4095-BD7B-63EC9C79EA89}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DFA23C5E-6500-493E-94B9-A71A977D4DAD} + EndGlobalSection +EndGlobal diff --git a/tpvs17/AlgoTest/AlgoTest.cpp b/tpvs17/AlgoTest/AlgoTest.cpp new file mode 100644 index 0000000..4b51846 --- /dev/null +++ b/tpvs17/AlgoTest/AlgoTest.cpp @@ -0,0 +1,94 @@ +#include "AlgoTest.h" +#include +#include +#include +#include + +#pragma execution_character_set("utf-8") + +AlgoTest::AlgoTest(QWidget *parent) + : QMainWindow(parent) +{ + ui.setupUi(this); + connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + + { + QGridLayout *pLayout = new QGridLayout(ui.widget_src); + m_srcView = new lpImgViewer(ui.widget_src); + pLayout->addWidget(m_srcView); + ui.widget_src->setLayout(pLayout); + } + { + QGridLayout *pLayout = new QGridLayout(ui.widget_rlt); + m_rltView = new lpImgViewer(ui.widget_rlt); + pLayout->addWidget(m_rltView); + ui.widget_rlt->setLayout(pLayout); + } + loadImage(); + + m_pAlg = new QAlgDetect(); +} + +AlgoTest::~AlgoTest() +{ + if (m_rltView) + { + delete m_rltView; + m_rltView = nullptr; + } + if (m_srcView) { + delete m_srcView; + m_srcView = nullptr; + } + if (m_pAlg) + { + delete m_pAlg; + m_pAlg = nullptr; + } +} + +void AlgoTest::loadImage() +{ + QString strPath = "H:\\½ļ\\Source\\"; + //QString strPath = "H:\\½ļ\\7\\"; + QStringList fileFilter; + fileFilter<< "*.BMP" << "*.JPEG" << "*.JPG" << "*.PNG"; + + QDirIterator qdi(strPath, + fileFilter, + QDir::NoSymLinks | QDir::Files, + QDirIterator::Subdirectories); + while (qdi.hasNext()) + { + m_filelst.append(qdi.next()); + } +} + +void AlgoTest::algCallFunc(QImage img) +{ + m_rltView->setImg(img); +} + +Q_SLOT void AlgoTest::onButtonClicked() +{ + QString strObj = sender()->objectName(); + if (strObj == "pushButton") + { + if (m_filelst.size() <= 0) + return; + if (m_gIndex >= m_filelst.size()) + m_gIndex = 0; + QString strPath = m_filelst.at(m_gIndex); + m_gIndex++; + + QImage img; + bool b = img.load(strPath); + if (b == true) + { + m_srcView->setImg(img); + } + + AlgCallBack func = std::bind(&AlgoTest::algCallFunc, this, std::placeholders::_1); + m_pAlg->detect(img, func); + } +} diff --git a/tpvs17/AlgoTest/AlgoTest.h b/tpvs17/AlgoTest/AlgoTest.h new file mode 100644 index 0000000..7af9cd3 --- /dev/null +++ b/tpvs17/AlgoTest/AlgoTest.h @@ -0,0 +1,32 @@ +#ifndef _ALGOTEST_H_ +#define _ALGOTEST_H_ + +#include +#include "ui_AlgoTest.h" +#include "lpImgViewer.h" +#include "QAlgDetect.h" + +class AlgoTest : public QMainWindow +{ + Q_OBJECT + +public: + AlgoTest(QWidget *parent = Q_NULLPTR); + ~AlgoTest(); + void loadImage(); + void algCallFunc(QImage img); + Q_SLOT void onButtonClicked(); +private: + Ui::AlgoTestClass ui; + + lpImgViewer* m_srcView{ nullptr }; + lpImgViewer* m_rltView{ nullptr }; + +private: + QStringList m_filelst; + int m_gIndex{ 0 }; + + QAlgDetect *m_pAlg{ nullptr }; +}; +#endif + diff --git a/tpvs17/AlgoTest/AlgoTest.qrc b/tpvs17/AlgoTest/AlgoTest.qrc new file mode 100644 index 0000000..cb590ab --- /dev/null +++ b/tpvs17/AlgoTest/AlgoTest.qrc @@ -0,0 +1,4 @@ + + + + diff --git a/tpvs17/AlgoTest/AlgoTest.ui b/tpvs17/AlgoTest/AlgoTest.ui new file mode 100644 index 0000000..927e3d7 --- /dev/null +++ b/tpvs17/AlgoTest/AlgoTest.ui @@ -0,0 +1,90 @@ + + + AlgoTestClass + + + + 0 + 0 + 681 + 748 + + + + AlgoTest + + + + + + + PushButton + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + + + 原图 + + + + + + background-color: rgb(255, 223, 208); + + + + + + + + + + 结果 + + + + + + background-color: rgb(194, 194, 194); + + + + + + + + + + + + + + + + + + diff --git a/tpvs17/AlgoTest/AlgoTest.vcxproj b/tpvs17/AlgoTest/AlgoTest.vcxproj new file mode 100644 index 0000000..2d937a3 --- /dev/null +++ b/tpvs17/AlgoTest/AlgoTest.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {9432FDF3-AEA1-4095-BD7B-63EC9C79EA89} + Qt4VSv1.0 + 10.0.17763.0 + + + + Application + v141 + + + Application + v141 + + + + $(MSBuildProjectDirectory)\QtMsBuild + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + + + + + + + + + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;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;E:\wheelValve\3part\opencv3.4.1\include;E:\wheelValve\3part\opencv3.4.1\include\opencv;E:\wheelValve\3part\opencv3.4.1\include\opencv2;E:\wheelValve\src\tpMain\algela;E:\wheelValve\3part\edcircle\include;E:\wheelValve\3part\Cyclops\include;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(OutDir)\$(ProjectName).exe + $(QTDIR)\lib;E:\wheelValve\3part\opencv3.4.1\x64\vc15\lib;E:\wheelValve\3part\edcircle\lib;E:\wheelValve\3part\Cyclops\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;opencv_world341d.lib;EDCircled.lib;Cyclopsd.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;E:\wheelValve\3part\opencv3.4.1\include;E:\wheelValve\3part\opencv3.4.1\include\opencv;E:\wheelValve\3part\opencv3.4.1\include\opencv2;E:\wheelValve\src\tpMain\algela;E:\wheelValve\3part\edcircle\include;E:\wheelValve\3part\Cyclops\include;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + + + Uic'ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h + + + Rcc'ing %(Identity)... + .\GeneratedFiles\qrc_%(Filename).cpp + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;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) + + MultiThreadedDLL + true + + + Windows + $(OutDir)\$(ProjectName).exe + $(QTDIR)\lib;%(AdditionalLibraryDirectories) + false + qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.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_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + + + Uic'ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h + + + Rcc'ing %(Identity)... + .\GeneratedFiles\qrc_%(Filename).cpp + + + + + + + + + + + + + + + + + + + + .\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 + + + + + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;E:\wheelValve\3part\opencv3.4.1\include;E:\wheelValve\3part\opencv3.4.1\include\opencv;E:\wheelValve\3part\opencv3.4.1\include\opencv2 + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/AlgoTest/AlgoTest.vcxproj.filters b/tpvs17/AlgoTest/AlgoTest.vcxproj.filters new file mode 100644 index 0000000..cab9d49 --- /dev/null +++ b/tpvs17/AlgoTest/AlgoTest.vcxproj.filters @@ -0,0 +1,67 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Form Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/tpvs17/AlgoTest/QAlgDetect.cpp b/tpvs17/AlgoTest/QAlgDetect.cpp new file mode 100644 index 0000000..c6b1033 --- /dev/null +++ b/tpvs17/AlgoTest/QAlgDetect.cpp @@ -0,0 +1,244 @@ +#include "QAlgDetect.h" +#include "ED.h" +#include "EDLines.h" +#include "EDCircles.h" +#include +#include +#include "CircleDetector.h" + +using namespace std; + +static QImage cvMat2QImage(const cv::Mat& mat) { + if (mat.type() == CV_8UC1) { + QImage image(mat.cols, mat.rows, QImage::Format_Indexed8); + image.setColorCount(256); + for (int i = 0; i < 256; i++) { + image.setColor(i, qRgb(i, i, i)); + } + uchar *pSrc = mat.data; + for (int row = 0; row < mat.rows; row++) { + uchar *pDest = image.scanLine(row); + memcpy(pDest, pSrc, mat.cols); + pSrc += mat.step; + } + return image; + } + else if (mat.type() == CV_8UC3) { + const uchar *pSrc = (const uchar*)mat.data; + QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888); + if (image.isNull()) + return QImage(); + return image.rgbSwapped(); + } + else if (mat.type() == CV_8UC4) { + const uchar *pSrc = (const uchar*)mat.data; + QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32); + return image.copy(); + } + else { + qDebug() << "ERROR: Mat could not be converted to QImage."; + return QImage(); + } +} + +static cv::Mat QImageToMat(QImage image) { + cv::Mat mat; + QImage::Format f = image.format(); + switch (image.format()) + { + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); + break; + case QImage::Format_RGB888: + mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); + cv::cvtColor(mat, mat, CV_BGR2RGB); + break; + case QImage::Format_Indexed8: + case QImage::Format_Grayscale8: + mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); + break; + } + return mat; +} + +Mat _EnhanImg_sharpen(const Mat &img) { + int mGainValue = 3; + float amount = mGainValue * 0.5f; + Mat blurred; + + int mSmoothValue = 3; + GaussianBlur(img, blurred, Size(), mSmoothValue); + Mat lowContrastMask = abs(img - blurred) < 5; + Mat orResult = img * (1 + amount) + blurred * (-amount); + img.copyTo(orResult, lowContrastMask); + Mat openMat = orResult.clone(); + return openMat; +} + +Mat findEdge2(const Mat &Src) +{ + Mat ret = Src.clone(); + Mat kernel = (Mat_(5, 5) << + -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, + -1, -1, 24, -1, -1, + -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1); + filter2D(Src, ret, CV_8UC1, kernel); + return ret; +} + + + + +QAlgDetect::QAlgDetect(QObject *parent) + : QObject(parent) +{ +} + +QAlgDetect::~QAlgDetect() +{ +} + +#define REAIZE 4 + +void QAlgDetect::detect(QImage img, AlgCallBack func) +{ + Mat srcImg = QImageToMat(img); + if(srcImg.channels()!=1) + cv::cvtColor(srcImg, srcImg, CV_RGB2GRAY); + Mat detectImg; + Mat src = srcImg; + + cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); + int bBaseX = detectImg.cols; + int bBaseY = detectImg.rows; +// 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; + + QPointF centerP; + centerP.setX(EDCircle[nIndex].center.x * REAIZE); + centerP.setY(EDCircle[nIndex].center.y * REAIZE); + double r = radius * REAIZE; + Mat aa = DetectCircle(srcImg, centerP, r); + QImage rltImg = cvMat2QImage(aa); + if (func) { + func(rltImg); + return; + } + + + if (startX > 0 && startY > 0 && hight > 0 \ + && startX < src.cols &&startY < src.rows \ + && hight < src.cols&&hight < src.rows \ + && (startX + hight) < src.cols && (startY + hight) < src.rows) + { + Mat cutMat = src(Rect(startX, startY, hight, hight)); + if (cutMat.data != NULL) + { +// if (hight < 50) +// return Mat(); + +// pCircle->ptCenter = center; +// pCircle->fRadius = radius * REAIZE; + + //2021-05-10 ͼСж Գ900صͼһѹ + if (cutMat.cols >= 900 || cutMat.rows >= 900) + { + Mat newCutImg; + cv::resize(cutMat, newCutImg, cv::Size(cutMat.cols / REAIZE, cutMat.rows / REAIZE)); +// pCircle->fRadius = pCircle->fRadius / REAIZE; +// return newCutImg; + + QImage rltImg = cvMat2QImage(newCutImg); + if (func) { + func(rltImg); + return; + } + } + else { + QImage rltImg = cvMat2QImage(cutMat); + if (func) { + func(rltImg); + return; + } + } + } + } + } + + + + + + if (func) + { + func(img); + } +} + + +Mat QAlgDetect::DetectCircle(Mat img, QPointF center, double radius) +{ + Mat detectImg; + //equalizeHist(img, detectImg); + detectImg = img; + CircleDetector cd; + cd.setAlgoType(CircleDetector::PeakCircle); + cd.setEdgeWidth(3); + cd.setPolarity(Polarity::White2Black); + cd.setFindBy(FindBy::Best); + double difRadiusMin = radius - 100; + double difRadiusMax = radius + 150; + if (difRadiusMin < 0) + { + difRadiusMin = 0; + difRadiusMax = abs(center.y()-(img.cols / 2))-50; + } + + cd.setRadii(difRadiusMin, difRadiusMax); + cd.setACThres(3); + vector allScores; + Vec3f bestCircle; + float bestScore = cd.detectBest(detectImg, Point2f(center.x(), center.y()), bestCircle, &allScores); + if (abs(bestScore) <= FLT_EPSILON || bestCircle == Vec3f::zeros()) { + return Mat(); + } + + QPointF cen(bestCircle[0], bestCircle[1]); + double r = bestCircle[2]; + Rect rect; + rect.x = cen.x() - r; + rect.y = cen.y() - r; + rect.width = 2 * r; + rect.height = 2 * r; + Mat s = img(rect); + return s; +} diff --git a/tpvs17/AlgoTest/QAlgDetect.h b/tpvs17/AlgoTest/QAlgDetect.h new file mode 100644 index 0000000..7268a11 --- /dev/null +++ b/tpvs17/AlgoTest/QAlgDetect.h @@ -0,0 +1,23 @@ +#ifndef _QALGDETECT_H_ +#define _QALGDETECT_H_ + +#include +#include +#include + +using namespace cv; +typedef std::function AlgCallBack; +class QAlgDetect : public QObject +{ + Q_OBJECT + +public: + QAlgDetect(QObject *parent = nullptr); + ~QAlgDetect(); + + void detect(QImage img, AlgCallBack func); + Mat DetectCircle(Mat img, QPointF center, double radius); +private: + +}; +#endif diff --git a/tpvs17/AlgoTest/main.cpp b/tpvs17/AlgoTest/main.cpp new file mode 100644 index 0000000..a70a3c4 --- /dev/null +++ b/tpvs17/AlgoTest/main.cpp @@ -0,0 +1,10 @@ +#include "AlgoTest.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + AlgoTest w; + w.show(); + return a.exec(); +} diff --git a/tpvs17/tpMain/lpMainWin.cpp b/tpvs17/tpMain/lpMainWin.cpp index 83bf3e8..742bcc3 100644 --- a/tpvs17/tpMain/lpMainWin.cpp +++ b/tpvs17/tpMain/lpMainWin.cpp @@ -817,8 +817,11 @@ void lpMainWin::IEngineResult(QVariantMap vMap) } onSaveValveResult(valueRlt); ui.main_value_DetectTime->setText(QString("%1s").arg(taskTime)); - if(m_ImgViewer) - m_ImgViewer->setImg(maskImg); + if (m_ImgViewer) + { + if(!maskImg.isNull()) + m_ImgViewer->setImg(maskImg); + } } /*展示结果*/ } diff --git a/tpvs17/valueMainUI/valueMainUI.cpp b/tpvs17/valueMainUI/valueMainUI.cpp index 72b13df..1add77b 100644 --- a/tpvs17/valueMainUI/valueMainUI.cpp +++ b/tpvs17/valueMainUI/valueMainUI.cpp @@ -50,6 +50,7 @@ valueMainUI::valueMainUI(QWidget *parent) QGridLayout *pLayout_B = new QGridLayout(ui.widget_B); m_ImgViewer_B = new RoiImgViewer(ui.widget_A); m_ImgViewer_B->setObjectName("m_ImgViewer_B"); + connect(m_ImgViewer_B, SIGNAL(sgImageScale(qreal)), this, SLOT(onImageScale(qreal))); pLayout_B->addWidget(m_ImgViewer_B); ui.widget_B->setLayout(pLayout_B); diff --git a/tpvs17/wheel.sln b/tpvs17/wheel.sln index a07167b..9672af0 100644 --- a/tpvs17/wheel.sln +++ b/tpvs17/wheel.sln @@ -128,7 +128,7 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - Qt5Version = qt5.9.4-msvc2017-x64 SolutionGuid = {CD365F32-5EAC-4A16-AD47-BFB1D8E5511A} + Qt5Version = qt5.9.4-msvc2017-x64 EndGlobalSection EndGlobal