From 9acbdfb7e830b31ccc42f4d5c0eb1858b0566b5c Mon Sep 17 00:00:00 2001 From: "bob.pan" Date: Mon, 9 Aug 2021 18:37:20 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E6=97=A7lpengine?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=B8=AD=E7=9A=84=E8=A7=A3=E5=86=B3=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E7=AE=A1=E7=90=86=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3part/tadpole/include/tpBase/lpbengine.h | Bin 32500 -> 29740 bytes src/lpbdesigner/MainFrame.cpp | 96 +- src/lpbdesigner/RoiScene.cpp | 1 - src/lpbengine/Algorithm.cpp | 30 +- src/lpbengine/CDetectorEngine.cpp | 43 + src/lpbengine/CDetectorEngine.h | 5 +- src/lpbengine/Solution.cpp | 472 ++--- src/lpbengine/Solution.h | 23 +- src/lpbengine/SolutionMgr.cpp | 84 +- src/lpbengine/SolutionMgr.h | 8 +- src/lpbengine/Task.cpp | 56 +- src/lpbengine/Task.h | 4 +- tpvs17/caliCenter/algEg.cpp | 79 + tpvs17/caliCenter/algEg.h | 23 + tpvs17/caliCenter/algEg_global.h | 12 + tpvs17/caliCenter/caliCenter.cpp | 70 + tpvs17/caliCenter/caliCenter.h | 29 + tpvs17/caliCenter/caliCenter.vcxproj | 106 + tpvs17/caliCenter/caliCenter.vcxproj.filters | 56 + tpvs17/caliValve/algEg.cpp | 190 ++ tpvs17/caliValve/algEg.h | 23 + tpvs17/caliValve/algEg_global.h | 12 + tpvs17/caliValve/caliValve.cpp | 502 +++++ tpvs17/caliValve/caliValve.h | 58 + tpvs17/caliValve/caliValve.vcxproj | 106 + tpvs17/caliValve/caliValve.vcxproj.filters | 56 + tpvs17/tpMain/lpMainWin.cpp | 93 +- tpvs17/tpMain/lpMainWin.ui | 8 +- tpvs17/valveDetector/BatchTest4Alg.cpp | 104 + tpvs17/valveDetector/BatchTest4Alg.h | 14 + tpvs17/valveDetector/algEg.cpp | 307 +++ tpvs17/valveDetector/algEg.h | 23 + tpvs17/valveDetector/algEg_global.h | 12 + tpvs17/valveDetector/modelVerfication.cpp | 407 ++++ tpvs17/valveDetector/modelVerfication.h | 108 + tpvs17/valveDetector/valveDetector.cpp | 1810 +++++++++++++++++ tpvs17/valveDetector/valveDetector.h | 146 ++ tpvs17/valveDetector/valveDetector.vcxproj | 174 ++ .../valveDetector.vcxproj.filters | 68 + tpvs17/wheel.sln | 28 +- 40 files changed, 4940 insertions(+), 506 deletions(-) create mode 100644 tpvs17/caliCenter/algEg.cpp create mode 100644 tpvs17/caliCenter/algEg.h create mode 100644 tpvs17/caliCenter/algEg_global.h create mode 100644 tpvs17/caliCenter/caliCenter.cpp create mode 100644 tpvs17/caliCenter/caliCenter.h create mode 100644 tpvs17/caliCenter/caliCenter.vcxproj create mode 100644 tpvs17/caliCenter/caliCenter.vcxproj.filters create mode 100644 tpvs17/caliValve/algEg.cpp create mode 100644 tpvs17/caliValve/algEg.h create mode 100644 tpvs17/caliValve/algEg_global.h create mode 100644 tpvs17/caliValve/caliValve.cpp create mode 100644 tpvs17/caliValve/caliValve.h create mode 100644 tpvs17/caliValve/caliValve.vcxproj create mode 100644 tpvs17/caliValve/caliValve.vcxproj.filters create mode 100644 tpvs17/valveDetector/BatchTest4Alg.cpp create mode 100644 tpvs17/valveDetector/BatchTest4Alg.h create mode 100644 tpvs17/valveDetector/algEg.cpp create mode 100644 tpvs17/valveDetector/algEg.h create mode 100644 tpvs17/valveDetector/algEg_global.h create mode 100644 tpvs17/valveDetector/modelVerfication.cpp create mode 100644 tpvs17/valveDetector/modelVerfication.h create mode 100644 tpvs17/valveDetector/valveDetector.cpp create mode 100644 tpvs17/valveDetector/valveDetector.h create mode 100644 tpvs17/valveDetector/valveDetector.vcxproj create mode 100644 tpvs17/valveDetector/valveDetector.vcxproj.filters diff --git a/3part/tadpole/include/tpBase/lpbengine.h b/3part/tadpole/include/tpBase/lpbengine.h index cf00c3765f6543b8e4bed69ea10ba6027ae17952..64d89141cecdce77d27f910a295e9fc4b9f639c9 100644 GIT binary patch delta 428 zcmaiwze@sP7{{N}AeF-|F+#Jj%tIrP3$w5z%!|UI5L>EA@fYTKsdw2aL5+>Y(;T!$ zgYXVPLpZneAJp2`(i-%5L$t*M@AK>PJl}`+>zjM{;QB`{Ci8DR27GfYIpFMC^+K<_jZiP{}$mYdToJb;#Lc5X15AG~Tz|7%!%* z{LT#FbKAjgb-#Ty4PD52Gl6hK*w2g1#jx}D3~6$ZzgTHx+H{k0!ol1t5|D`zXLLKXs|}z2)=tJ zqftv@xV#EE64HrRiB_OMUWGLIBGh4xUH3jY3}yq-l66m+$_7N}?N~xP1R8X$4sEJs jpaE5UZB8sVNNzZ>OZ^7PYR~K@a delta 1895 zcmbVNOHUI~6h0-sS|BZHaD=8|N)>B0X{(5d4@{L7Nu*-isDy<~OQ98*4(;GG1lKHx zZQfQG1R3#0oJXSJ|VMn1ktjF=cLY?FSR-j+l)=t<}S_W38`&0&Qp0e}|=MX|Co(4gWbn}DS-z0bMP;raF=cQIS)FCV2Y&?$-ojg@8L$*61SS=GqHVHJse(NPwwusv*|Lb5#!yq) zhE1DwD4Y5G+3yVe%&y?^$Wbd=MANB*L955Ykx9v2Q?F4|{yYX_(c;G& zQ$7o6NJU^D_+Yda(S|RP=oeRDAc*pYDstatusBar->addWidget(m_plablStatus); _pSaveStatus = ui->label_SaveStatus; -// m_tParamMgrDlg.setParent(this); -// m_tParamMgrDlg.setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); - //m_tParamDlg.setParent(parent); - //m_tParamDlg.setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); } CMainFrame::~CMainFrame() @@ -195,12 +191,6 @@ bool CMainFrame::OnMainMenuTrigger(QAction* pAction) if (!oldMat.empty()) _pOldTask->GetTaskInfo()->templateImg = oldMat; } -// if (m_pDE && m_pDE->SaveTasks(m_TaskChangeList)) -// { -// m_TaskChangeList.clear(); -// return true; -// } - return false; } } @@ -217,28 +207,28 @@ void CMainFrame::OnTrigger() if (!oldMat.empty()) _pOldTask->GetTaskInfo()->templateImg = oldMat; } -// if (m_pDE && m_pDE->SaveTasks(m_TaskChangeList)) -// { -// if (_pSaveStatus) -// { -// _pSaveStatus->setText(QObject::tr(" 标定数据保存完成!")); -// QTimer::singleShot(1500, [&](){ -// _pSaveStatus->setText(""); -// update(); -// }); -// m_TaskChangeList.clear(); -// SystemStateInfo::bParamStateFlag = false; -// } -// } -// else -// { -// if (_pSaveStatus) -// { -// _pSaveStatus->setText(QObject::tr(" 保存失败!")); -// QTimer::singleShot(2000, [&](){_pSaveStatus->setText(""); }); -// update(); -// } -// } + if (m_pDE && m_pSolutionMgr->SaveByNames(m_TaskChangeList)) + { + if (_pSaveStatus) + { + _pSaveStatus->setText(QObject::tr(" 标定数据保存完成!")); + QTimer::singleShot(1500, [&](){ + _pSaveStatus->setText(""); + update(); + }); + m_TaskChangeList.clear(); + SystemStateInfo::bParamStateFlag = false; + } + } + else + { + if (_pSaveStatus) + { + _pSaveStatus->setText(QObject::tr(" 保存失败!")); + QTimer::singleShot(2000, [&](){_pSaveStatus->setText(""); }); + update(); + } + } } } @@ -280,19 +270,19 @@ bool CMainFrame::InitGraphView() ui->textEdit->setWordWrapMode(QTextOption::NoWrap); - int nSolutionCount = m_pSolutionMgr->EnumSolution(NULL, 0); - if (nSolutionCount > 0) + //int nSolutionCount = m_pSolutionMgr->GetSolutionCount(); + //if (nSolutionCount > 0) { - IDetectorSolution** lppSolution = new IDetectorSolution*[nSolutionCount]; - nSolutionCount = m_pSolutionMgr->EnumSolution(lppSolution, nSolutionCount); - for (int i = 0; i < nSolutionCount; i++) + QMap tmp = m_pSolutionMgr->GetAllSolutions(); + for (QMap::iterator it = tmp.begin();it!= tmp.end();++it) { - if (lppSolution[i]) + IDetectorSolution* tmpSolution = *it; + if (tmpSolution != nullptr) { - PLP_DETECTOR_SOLUTION pSolutionInfo = lppSolution[i]->GetSolutionInfo(); + PLP_DETECTOR_SOLUTION pSolutionInfo = tmpSolution->GetSolutionInfo(); QTreeWidgetItem *solutionItem = NULL; - if (m_pSolutionMgr->GetRunSolution() && m_pSolutionMgr->GetRunSolution()->GetID() == lppSolution[i]->GetID()) + if (m_pSolutionMgr->GetRunSolution() && m_pSolutionMgr->GetRunSolution()->GetID() == tmpSolution->GetID()) { QString strText = pSolutionInfo->strName + tr("(√)"); solutionItem = new QTreeWidgetItem(ui->treeWidget, QStringList(strText)); @@ -302,14 +292,14 @@ bool CMainFrame::InitGraphView() solutionItem = new QTreeWidgetItem(ui->treeWidget, QStringList(pSolutionInfo->strName)); } - solutionItem->setData(0, Qt::UserRole, lppSolution[i]->GetID()); + solutionItem->setData(0, Qt::UserRole, tmpSolution->GetID()); solutionItem->setData(1, Qt::UserRole, SOLUTION); - QStringList strKeys = lppSolution[i]->GetAllTaskNames(); + QStringList strKeys = tmpSolution->GetAllTaskNames(); QMap m_tmpMap; for (int n = 0; n < strKeys.size();n++) { - IDetectorTask* pTask = lppSolution[i]->GetTask(strKeys[n]); + IDetectorTask* pTask = tmpSolution->GetTask(strKeys[n]); if (pTask) { PLP_DETECTOR_TASK pTaskInfo = pTask->GetTaskInfo(); @@ -336,7 +326,7 @@ bool CMainFrame::InitGraphView() int camID = its.key(); QString strStationName = QString(QObject::tr("工位%1")).arg(camID); QTreeWidgetItem *childItem = new QTreeWidgetItem(solutionItem, QStringList(strStationName)); - childItem->setData(0, Qt::UserRole, lppSolution[i]->GetID()); + childItem->setData(0, Qt::UserRole, tmpSolution->GetID()); childItem->setData(1, Qt::UserRole, SOLUTION); solutionItem->addChild(childItem); @@ -373,26 +363,24 @@ bool CMainFrame::InitGraphView() } } - if (i == 0) + //if (i == 0) { ui->treeWidget->setCurrentItem(solutionItem); } - if (m_pSolutionMgr->GetRunSolution() && m_pSolutionMgr->GetRunSolution()->GetID() == lppSolution[i]->GetID()) + if (m_pSolutionMgr->GetRunSolution() && m_pSolutionMgr->GetRunSolution()->GetID() == tmpSolution->GetID()) { ui->treeWidget->setCurrentItem(solutionItem); ui->treeWidget->expandItem(solutionItem); - ui->treeWidget->setCurrentItem( solutionItem); + ui->treeWidget->setCurrentItem(solutionItem); } } } - - delete[] lppSolution; } - - if (!InitCurrentTask()) - return false; m_TaskChangeList.clear(); + if (!InitCurrentTask()) + return true; + return true; } @@ -674,7 +662,7 @@ bool CMainFrame::InitCurrentNode() m_pCurrentSolution->ClearUserParamValue(); int nSolutionID = currentItem->data(0, Qt::UserRole).toInt(); - m_pCurrentSolution = m_pSolutionMgr->GetSolution(nSolutionID); + m_pCurrentSolution = m_pSolutionMgr->GetSolutionByID(nSolutionID); if (!m_pCurrentSolution) return false; @@ -686,7 +674,7 @@ bool CMainFrame::InitCurrentNode() if (currentItem->parent()) { int nSolutionID = currentItem->parent()->data(0, Qt::UserRole).toInt(); - m_pCurrentSolution = m_pSolutionMgr->GetSolution(nSolutionID); + m_pCurrentSolution = m_pSolutionMgr->GetSolutionByID(nSolutionID); if (!m_pCurrentSolution) return false; diff --git a/src/lpbdesigner/RoiScene.cpp b/src/lpbdesigner/RoiScene.cpp index 06bc707..6258182 100644 --- a/src/lpbdesigner/RoiScene.cpp +++ b/src/lpbdesigner/RoiScene.cpp @@ -2,7 +2,6 @@ #include #include #include "RoiItem.h" -//#include "colossusbase.h" #include "QGraphicsSceneEvent" #include "colossusbase.h" #pragma execution_character_set("utf-8") diff --git a/src/lpbengine/Algorithm.cpp b/src/lpbengine/Algorithm.cpp index b6edbe2..ca8d234 100644 --- a/src/lpbengine/Algorithm.cpp +++ b/src/lpbengine/Algorithm.cpp @@ -467,8 +467,8 @@ bool CDetectorAlgorithm::SerializeToJson(QJsonDocument* pJsonDocument, QJsonArra case LP_MAT: { cv::Mat matResult = p->value.value(); - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + LP_DETECTOR_BUSSINESS_IN_PARAM_FILE_DIR; + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strFilePath = m_pTask->GetPath();// strExePath + LP_DETECTOR_BUSSINESS_IN_PARAM_FILE_DIR; QString strName = QString("%1_%2_%3_%4").arg(m_pTask->GetParentSolution()->GetID()).arg(m_pTask->GetID()).arg(m_nID).arg(p->nID); QString strFileName = strName + "_in" + ".bmp"; QString strFileName2 = strFileName; @@ -880,8 +880,8 @@ bool CDetectorAlgorithm::SerializeFromJson(QJsonObject* pJsonObject) } case LP_MAT: { - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + LP_DETECTOR_BUSSINESS_IN_PARAM_FILE_DIR; + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strFilePath = m_pTask->GetPath(); //strExePath + LP_DETECTOR_BUSSINESS_IN_PARAM_FILE_DIR; QString strFileName = jsonObject.value("param_file_path").toString(); strFilePath += strFileName; QFile file(strFilePath); @@ -1195,8 +1195,8 @@ bool CDetectorAlgorithm::Load(QString dllPath) } else { - QString strExePath = QCoreApplication::applicationDirPath(); - QString strDefaultFilePath = strExePath + LP_DETECTOR_BUSSINESS_CONFIG_ALGO_DIR + strFileName; + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strDefaultFilePath = m_pTask->GetPath();// strExePath + LP_DETECTOR_BUSSINESS_CONFIG_ALGO_DIR + strFileName; QFile defaultFile(strDefaultFilePath); if (defaultFile.exists()) @@ -1849,8 +1849,8 @@ bool CDetectorAlgorithm::ImportParam(QJsonArray paramArray)//导入参数 LP_DETECTOR_ROI_DATA roiData; - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strFilePath = m_pTask->GetPath(); //strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; QString strFileName = strFilePath + QString::number(param.nID) + ".bmp"; std::string strpath = strFileName.toLocal8Bit().toStdString(); roiData.img = cv::imread(strpath, CV_LOAD_IMAGE_UNCHANGED); @@ -1973,7 +1973,7 @@ QByteArray CDetectorAlgorithm::ExportParam() { cv::Mat matResult = p->value.value(); - QString strExePath = QCoreApplication::applicationDirPath(); + QString strExePath = m_pTask->GetPath(); //QCoreApplication::applicationDirPath(); QString strFilePath = strExePath + "/" + "paramfiles/"; QString strFileName = strFilePath + QString::number(p->nID) + ".bmp"; std::string strpath = strFileName.toLocal8Bit().toStdString(); @@ -1988,8 +1988,8 @@ QByteArray CDetectorAlgorithm::ExportParam() LP_DETECTOR_ROI_DATA roiData = p->value.value(); - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + "/" + "images/"; + QString strExePath = m_pTask->GetPath(); //QCoreApplication::applicationDirPath(); + QString strFilePath = m_pTask->GetPath()+"/"; //strExePath + "/" + "images/"; QString strFileName = strFilePath + QString::number(p->nID) + ".bmp"; std::string strpath = strFileName.toLocal8Bit().toStdString(); if (!roiData.img.empty() && !cv::imwrite(strpath, roiData.img)) @@ -2136,8 +2136,8 @@ bool CDetectorAlgorithm::ImportOutParam(QJsonArray outParamArray)//导入参数 LP_DETECTOR_ROI_DATA roiData; - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strFilePath = m_pTask->GetPath()+"/"; //strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; QString strFileName = strFilePath + QString::number(param.nID) + ".bmp"; std::string strpath = strFileName.toLocal8Bit().toStdString(); roiData.img = cv::imread(strpath, CV_LOAD_IMAGE_UNCHANGED); @@ -2263,8 +2263,8 @@ QByteArray CDetectorAlgorithm::ExportOutParam()//导出参数 { cv::Mat matResult = p->value.value(); - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + "/" + "paramfiles/"; + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strFilePath = m_pTask->GetPath()+"/"; //strExePath + "/" + "paramfiles/"; QString strFileName = strFilePath + QString::number(p->nID) + ".bmp"; std::string strpath = strFileName.toLocal8Bit().toStdString(); if (!matResult.empty() && !cv::imwrite(strpath, matResult)) diff --git a/src/lpbengine/CDetectorEngine.cpp b/src/lpbengine/CDetectorEngine.cpp index f23b85e..1d78380 100644 --- a/src/lpbengine/CDetectorEngine.cpp +++ b/src/lpbengine/CDetectorEngine.cpp @@ -39,6 +39,49 @@ IDetectorSolutionMgr* CDetectorEngine::getSolutionMgr() const return (IDetectorSolutionMgr*)&m_SolutionMgr; } +bool CDetectorEngine::detect(cv::Mat srcImg, QString modeName, AlgResultCallBack func) +{ + IDetectorSolution* pSolution = m_SolutionMgr.GetRunSolution(); + if (pSolution) + { + IDetectorTask* pTask = pSolution->GetTask(modeName); + if (pTask) + { + pTask->GetTaskInfo()->detectImg = srcImg; + IDetectorAlgorithm* pAlgo = pTask->GetRunAlgo(); + if (pAlgo) { + pAlgo->Exec(); + int nOutParam = pAlgo->EnumOutParam(NULL, 0); + if (nOutParam > 0) + { + QVariantMap map; + map.clear(); + LP_ALGORITHM_PARAM** lppOutParam = new LP_ALGORITHM_PARAM*[nOutParam]; + nOutParam = pAlgo->EnumOutParam(lppOutParam, nOutParam); + + for (int j = 0; j < nOutParam; j++) + { + if (lppOutParam[j]) + { + map.insert(lppOutParam[j]->strName, lppOutParam[j]->value); + } + } + map.insert("taskID", pTask->GetID()); + map.insert("originImage", EngineBase::convMat2QImage(srcImg)); + map.insert("tasktime", pTask->ExecTime()); + + if (func) + { + func(map); + } + delete[] lppOutParam; + } + } + } + } + return false; +} + bool CDetectorEngine::CheckConfigFolder() { QString strExePath = QCoreApplication::applicationDirPath(); diff --git a/src/lpbengine/CDetectorEngine.h b/src/lpbengine/CDetectorEngine.h index a1f81ea..bdc7d40 100644 --- a/src/lpbengine/CDetectorEngine.h +++ b/src/lpbengine/CDetectorEngine.h @@ -10,8 +10,9 @@ class CDetectorEngine:public IDetectorEngine public: CDetectorEngine(); ~CDetectorEngine(); - IAlgorithmLibMgr* getAlgorithmLibMgr() const; - IDetectorSolutionMgr* getSolutionMgr() const; + virtual IAlgorithmLibMgr* getAlgorithmLibMgr() const; + virtual IDetectorSolutionMgr* getSolutionMgr() const; + virtual bool detect(cv::Mat srcImg, QString modeName, AlgResultCallBack func); bool Initialize(); virtual bool Save(); virtual bool SaveTasks(QStringList strTaskNames); diff --git a/src/lpbengine/Solution.cpp b/src/lpbengine/Solution.cpp index 286e060..03602f2 100644 --- a/src/lpbengine/Solution.cpp +++ b/src/lpbengine/Solution.cpp @@ -1,21 +1,20 @@ #include "Solution.h" #include "Task.h" -CDetectorSolution::CDetectorSolution() : m_mutex(QMutex::Recursive) +Solution::Solution() : m_mutex(QMutex::Recursive) { m_nID = LP_DETECTOR_INVALID_ID; m_nBaseID = 0; m_bIsRun = false; m_bIsModify = false; - } -CDetectorSolution::~CDetectorSolution() +Solution::~Solution() { CleanUp(); } -bool CDetectorSolution::Initialize(IAlgorithmLibMgr* pAlgoLibMgr) +bool Solution::Initialize(IAlgorithmLibMgr* pAlgoLibMgr) { if (!pAlgoLibMgr) return false; @@ -25,7 +24,7 @@ bool CDetectorSolution::Initialize(IAlgorithmLibMgr* pAlgoLibMgr) return true; } -bool CDetectorSolution::SetSolutionInfo(const PLP_DETECTOR_SOLUTION pSolution) +bool Solution::SetSolutionInfo(const PLP_DETECTOR_SOLUTION pSolution) { if (NULL == pSolution) return false; @@ -36,12 +35,12 @@ bool CDetectorSolution::SetSolutionInfo(const PLP_DETECTOR_SOLUTION pSolution) return true; } -PLP_DETECTOR_SOLUTION CDetectorSolution::GetSolutionInfo() +PLP_DETECTOR_SOLUTION Solution::GetSolutionInfo() { return &m_tSolutionInfo; } -IDetectorTask* CDetectorSolution::AddTask(const PLP_DETECTOR_TASK pTask, QString strPath) +IDetectorTask* Solution::AddTask(const PLP_DETECTOR_TASK pTask, QString strPath) { if (NULL == pTask) return NULL; @@ -63,7 +62,7 @@ IDetectorTask* CDetectorSolution::AddTask(const PLP_DETECTOR_TASK pTask, QString return NULL; } -bool CDetectorSolution::AddTaskByCopy(IDetectorTask* pSrc) +bool Solution::AddTaskByCopy(IDetectorTask* pSrc) { if (pSrc == nullptr) return false; @@ -82,7 +81,7 @@ bool CDetectorSolution::AddTaskByCopy(IDetectorTask* pSrc) return false; } -IDetectorTask* CDetectorSolution::AddTask(const PLP_DETECTOR_TASK pTask, bool bRet /*= true*/) +IDetectorTask* Solution::AddTask(const PLP_DETECTOR_TASK pTask, bool bRet /*= true*/) { if (NULL == pTask) return NULL; @@ -101,7 +100,7 @@ IDetectorTask* CDetectorSolution::AddTask(const PLP_DETECTOR_TASK pTask, bool bR return NULL; } -bool CDetectorSolution::SetRunTask(int nCameraID, QString strTaskName) +bool Solution::SetRunTask(int nCameraID, QString strTaskName) { QMap::iterator it = m_TaskMapByName.find(strTaskName); if (it != m_TaskMapByName.end()) @@ -112,7 +111,7 @@ bool CDetectorSolution::SetRunTask(int nCameraID, QString strTaskName) return false; } -bool CDetectorSolution::DeleteTask(int nTaskID) +bool Solution::DeleteTask(int nTaskID) { QMap::iterator it = m_TaskMapByID.find(nTaskID); if (it != m_TaskMapByID.end()){ @@ -126,7 +125,7 @@ bool CDetectorSolution::DeleteTask(int nTaskID) } return true; } -bool CDetectorSolution::DeleteTask(QString strName) +bool Solution::DeleteTask(QString strName) { QMap::iterator its = m_TaskMapByName.find(strName); if (its != m_TaskMapByName.end()) @@ -141,7 +140,7 @@ bool CDetectorSolution::DeleteTask(QString strName) return false; } -IDetectorTask* CDetectorSolution::GetTask(int nTaskID) +IDetectorTask* Solution::GetTask(int nTaskID) { QMap::iterator it = m_TaskMapByID.find(nTaskID); if (it != m_TaskMapByID.end()){ @@ -154,7 +153,7 @@ IDetectorTask* CDetectorSolution::GetTask(int nTaskID) return nullptr; } -IDetectorTask* CDetectorSolution::GetTask(QString strName) +IDetectorTask* Solution::GetTask(QString strName) { QMap::iterator its = m_TaskMapByName.find(strName); if (its != m_TaskMapByName.end()) @@ -164,46 +163,27 @@ IDetectorTask* CDetectorSolution::GetTask(QString strName) return nullptr; } -int CDetectorSolution::EnumTask(IDetectorTask** lppTask, int nCount) -{ -// if (!lppTask || nCount < m_vecTask.size()) -// return m_vecTask.size(); - - int nIndex = 0; -// for (QVector::iterator iter = m_vecTask.begin(); -// iter != m_vecTask.end(); ++iter) -// { -// if (*iter) -// { -// lppTask[nIndex] = *iter; -// nIndex++; -// } -// } - - return nIndex; -} - -void CDetectorSolution::SetID(int nID) +void Solution::SetID(int nID) { m_nID = nID; } -int CDetectorSolution::GetID() const +int Solution::GetID() const { return m_nID; } -int CDetectorSolution::GetTaskBaseID() const +int Solution::GetTaskBaseID() const { return m_nBaseID; } -void CDetectorSolution::Release() +void Solution::Release() { delete this; } -void CDetectorSolution::CleanUp() +void Solution::CleanUp() { for (QMap::iterator it = m_TaskMapByID.begin(); it != m_TaskMapByID.end(); ++it) { @@ -215,7 +195,7 @@ void CDetectorSolution::CleanUp() m_CurRunTaskMap.clear(); } -bool CDetectorSolution::CheckTask(int nTaskID, QString strTaskName) +bool Solution::CheckTask(int nTaskID, QString strTaskName) { QMap::iterator it = m_TaskMapByName.find(strTaskName); if (it != m_TaskMapByName.end()) @@ -224,7 +204,7 @@ bool CDetectorSolution::CheckTask(int nTaskID, QString strTaskName) return false; } -bool CDetectorSolution::SaveFileEx(const QString& strPath, QStringList sTaskNames) +bool Solution::SaveFileEx(const QString& strPath, QStringList sTaskNames) { QDir dir; if (!dir.exists(strPath)) @@ -234,22 +214,27 @@ bool CDetectorSolution::SaveFileEx(const QString& strPath, QStringList sTaskName dir.setPath(strPath); - foreach(QString strObj, sTaskNames){ + foreach(QString strObj, sTaskNames) { + CDetectorTask *p = (CDetectorTask*)m_TaskMapByName.value(strObj); if (p) { - QString strTaskFilePath = strPath + "/" + QString::number(p->GetID()) + "_" + p->GetTaskInfo()->strName + ".json"; + QString taskPath = strPath + "/" + strObj; + if (!dir.exists(taskPath)) { + dir.mkpath(taskPath); + } + + QString strTaskFilePath = taskPath + "/" + /*QString::number(p->GetID()) + "_" + p->GetTaskInfo()->strName*/ + "taskinfo.json"; if (!p->SaveFile(strTaskFilePath)) { qWarning("save task:%s fail", p->GetTaskInfo()->strName); } } } - return true; } -bool CDetectorSolution::SaveFileEx(const QString& strPath) +bool Solution::SaveFileEx(const QString& strPath) { QDir dir; if (!dir.exists(strPath)) @@ -258,35 +243,18 @@ bool CDetectorSolution::SaveFileEx(const QString& strPath) } dir.setPath(strPath); -// -// QJsonDocument document; -// QJsonObject jsonObject; -// -// jsonObject.insert("solution_name", m_tSolutionInfo.strName); -// jsonObject.insert("solution_type", m_tSolutionInfo.nType); -// jsonObject.insert("solution_description", m_tSolutionInfo.strDescription); -// jsonObject.insert("solution_id", m_nID); -// -// document.setObject(jsonObject); -// QByteArray byteArray = document.toJson(); -// if (byteArray.isEmpty()) -// return false; -// -// QString strFilePath = strPath + "/" + "info" + ".json"; -// QFile file(strFilePath); -// if (file.open(QFile::WriteOnly | QFile::Text)) -// { -// file.write(byteArray); -// file.flush(); -// file.close(); -// } - for (QMap::iterator iter = m_TaskMapByID.begin(); iter != m_TaskMapByID.end(); ++iter) - { - if (*iter) - { + for (QMap::iterator iter = m_TaskMapByID.begin(); iter != m_TaskMapByID.end(); ++iter) { + if (*iter) { + CDetectorTask *p = (CDetectorTask*)*iter; - QString strTaskFilePath = strPath + "/" + QString::number(p->GetID()) + "_" + p->GetTaskInfo()->strName + ".json"; + + QString taskPath = strPath + "/" + p->GetTaskInfo()->strName; + if (!dir.exists(taskPath)) { + dir.mkpath(taskPath); + } + + QString strTaskFilePath = taskPath + "/" + /*QString::number(p->GetID()) + "_" + p->GetTaskInfo()->strName +*/ "taskinfo.json"; if (!p->SaveFile(strTaskFilePath)) { qWarning("save task:%s fail", p->GetTaskInfo()->strName); @@ -322,70 +290,62 @@ bool CDetectorSolution::SaveFileEx(const QString& strPath) return true; } +/* +加载solution目录下的task作业 -bool CDetectorSolution::LoadFileEx(const QString& strPath) +文件夹结构如下: +solution_1 ---------- info.json // + ---------- Task1(目录) -----taskinfo.json + -----image.jpg // 图像 + -----param.ts //标定模板参数 + + ---------- Task2(目录) -----taskinfo.json + -----image.jpg // 图像 + -----param.ts //标定模板参数 + ---------- 。。。。 +*/ +bool Solution::LoadFileEx(const QString& strPath) { - QByteArray byteArray; QDir dir(strPath); + if (!dir.exists()) { + return false; + } - QJsonDocument document; - QJsonParseError parse_error; - - if (!dir.exists()) - { + QString strInfoFile = strPath + "/info.json"; + + QFile infoFile(strInfoFile); + if (!infoFile.open(QFile::ReadOnly)) { return false; } + QByteArray infoByteArray = infoFile.readAll(); + QJsonObject infoObj = QJsonDocument::fromJson(infoByteArray).object(); + if (infoObj.isEmpty()) + return false; + //解析solution基本信息 + m_tSolutionInfo.strName = infoObj.value("solution_name").toString(); + m_tSolutionInfo.nType = infoObj.value("solution_type").toInt(0); + m_tSolutionInfo.strDescription = infoObj.value("solution_description").toString(); + m_nID = infoObj.value("solution_id").toInt(); + QJsonArray childTask = infoObj.value("tasklist").toArray(); + int nBaseID = 0; - bool bCheckInfo = false; - dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); - dir.setSorting(QDir::Size | QDir::Reversed); - QFileInfoList fileList = dir.entryInfoList(); - for (int i = 0; i < fileList.size(); i++) + for (QJsonArray::iterator it = childTask.begin(); it != childTask.end(); ++it) { - QString strFile = strPath + "/" + fileList.at(i).fileName(); - QFile file(strFile); - if (fileList.at(i).fileName() == "." || fileList.at(i).fileName() == "..") - continue; - - if (!file.open(QFile::ReadOnly)) - { - continue; - } - byteArray = file.readAll(); - if (byteArray.isEmpty()) - { + QString taskName = it->toString(); + if(taskName.isEmpty()) continue; - } - - if (fileList.at(i).fileName() == "info.json") - { - document = QJsonDocument::fromJson(byteArray, &parse_error); - if (parse_error.error == QJsonParseError::NoError) - { - if (!document.isEmpty() && !document.isNull()) - { - if (document.isObject()) - { - QJsonObject solution = document.object(); - - m_tSolutionInfo.strName = solution.value("solution_name").toString(); - m_tSolutionInfo.nType = solution.value("solution_type").toInt(0); - m_tSolutionInfo.strDescription = solution.value("solution_description").toString(); - m_nID = solution.value("solution_id").toInt(); - bCheckInfo = true; - } - } - } - + if(m_tasklist.contains(taskName)) continue; - } + m_tasklist.append(taskName); + QString strTaskPath = strPath + "/" + taskName; LP_DETECTOR_TASK Task; - CDetectorTask* pTask = (CDetectorTask*)AddTask(&Task,strFile); + Task.strName = taskName; + CDetectorTask* pTask = (CDetectorTask*)AddTask(&Task, strTaskPath);//有隐藏bug if (!pTask) { - qWarning("load task: %s fail", strFile); + qWarning("load task: %s fail", strTaskPath); DeleteTask(pTask->GetID()); pTask = NULL; continue; @@ -393,78 +353,75 @@ bool CDetectorSolution::LoadFileEx(const QString& strPath) if (pTask) nBaseID = pTask->GetID() > nBaseID ? pTask->GetID() : nBaseID; - - file.close(); } m_nBaseID = nBaseID; - return bCheckInfo; - -} - -bool CDetectorSolution::SaveFile(const QString& strPath) -{ - QJsonDocument document; - QJsonObject jsonObject; - - if (!SerializeToJson(jsonObject)) - { - return false; - } - - document.setObject(jsonObject); - QByteArray byteArray = document.toJson(); - if (byteArray.isEmpty()) - return false; - - QFile file(strPath); - if (file.open(QFile::WriteOnly | QFile::Text)) - { - file.write(byteArray); - file.flush(); - file.close(); - return true; - } - - return false; + infoFile.close(); + return true; } -bool CDetectorSolution::LoadFile(const QString& strPath) -{ - QJsonDocument document; - QJsonParseError parse_error; - - QFile solutionFile(strPath); - if (!solutionFile.open(QFile::ReadOnly)) - { - return false; - } - - QByteArray byteArray; - byteArray = solutionFile.readAll(); - if (byteArray.isEmpty()) - return false; - - document = QJsonDocument::fromJson(byteArray, &parse_error); - if (parse_error.error == QJsonParseError::NoError) - { - if (!document.isEmpty() && !document.isNull()) - { - if (document.isObject()) - { - QJsonObject solutionJsonObject = document.object(); - if (!SerializeFromJson(&solutionJsonObject)) - { - return false; - } - } - } - } +// bool Solution::SaveFile(const QString& strPath) +// { +// QJsonDocument document; +// QJsonObject jsonObject; +// +// if (!SerializeToJson(jsonObject)) { +// return false; +// } +// +// document.setObject(jsonObject); +// QByteArray byteArray = document.toJson(); +// if (byteArray.isEmpty()) +// return false; +// +// QFile file(strPath); +// if (file.open(QFile::WriteOnly | QFile::Text)) +// { +// file.write(byteArray); +// file.flush(); +// file.close(); +// return true; +// } +// +// return false; +// } - return true; -} +// bool Solution::LoadFile(const QString& strPath) +// { +// QJsonDocument document; +// QJsonParseError parse_error; +// +// QFile solutionFile(strPath); +// if (!solutionFile.open(QFile::ReadOnly)) +// { +// return false; +// } +// +// QByteArray byteArray; +// byteArray = solutionFile.readAll(); +// if (byteArray.isEmpty()) +// return false; +// +// document = QJsonDocument::fromJson(byteArray, &parse_error); +// if (parse_error.error == QJsonParseError::NoError) +// { +// if (!document.isEmpty() && !document.isNull()) +// { +// if (document.isObject()) +// { +// QJsonObject solutionJsonObject = document.object(); +// if (!SerializeFromJson(&solutionJsonObject)) +// { +// return false; +// } +// } +// } +// } +// +// return true; +// } -bool CDetectorSolution::SerializeToJson(QJsonObject& jsonObject) +bool Solution::SerializeToJson(QJsonObject& jsonObject) { jsonObject.insert("solution_name", m_tSolutionInfo.strName); jsonObject.insert("solution_type", m_tSolutionInfo.nType); @@ -472,7 +429,6 @@ bool CDetectorSolution::SerializeToJson(QJsonObject& jsonObject) jsonObject.insert("solution_id", m_nID); QJsonArray TaskArray; - for (QMap::iterator iter = m_TaskMapByID.begin(); iter != m_TaskMapByID.end(); ++iter){ if (*iter) { @@ -488,41 +444,48 @@ bool CDetectorSolution::SerializeToJson(QJsonObject& jsonObject) if (TaskArray.size() > 0) jsonObject.insert("taskArray", TaskArray); - return true; -} - -bool CDetectorSolution::SerializeFromJson(QJsonObject* pJsonObject) -{ - if (!pJsonObject) - return false; - - m_tSolutionInfo.strName = pJsonObject->value("solution_name").toString(); - m_tSolutionInfo.nType = pJsonObject->value("solution_type").toInt(0); - m_tSolutionInfo.strDescription = pJsonObject->value("solution_description").toString(); - m_nID = pJsonObject->value("solution_id").toInt(); - - int nBaseID = 0; - QJsonArray TaskArray = pJsonObject->value("taskArray").toArray(); - for (int i = 0; i < TaskArray.size(); i++) + QJsonArray tasklist; + foreach(QString var, m_tasklist) { - LP_DETECTOR_TASK Task; - QJsonObject jsonObject = TaskArray[i].toObject(); - - CDetectorTask* pTask = (CDetectorTask*)AddTask(&Task); - if (!pTask->SerializeFromJson(&jsonObject)) - return false; - - nBaseID = pTask->GetID() > nBaseID ? pTask->GetID() : nBaseID; + tasklist.append(var); } + jsonObject.insert("tasklist", tasklist); - m_nBaseID = nBaseID; return true; } -IDetectorSolution* CDetectorSolution::Copy() +// bool Solution::SerializeFromJson(QJsonObject* pJsonObject) +// { +// if (!pJsonObject) +// return false; +// +// m_tSolutionInfo.strName = pJsonObject->value("solution_name").toString(); +// m_tSolutionInfo.nType = pJsonObject->value("solution_type").toInt(0); +// m_tSolutionInfo.strDescription = pJsonObject->value("solution_description").toString(); +// m_nID = pJsonObject->value("solution_id").toInt(); +// +// int nBaseID = 0; +// QJsonArray TaskArray = pJsonObject->value("taskArray").toArray(); +// for (int i = 0; i < TaskArray.size(); i++) +// { +// LP_DETECTOR_TASK Task; +// QJsonObject jsonObject = TaskArray[i].toObject(); +// +// CDetectorTask* pTask = (CDetectorTask*)AddTask(&Task); +// if (!pTask->SerializeFromJson(&jsonObject)) +// return false; +// +// nBaseID = pTask->GetID() > nBaseID ? pTask->GetID() : nBaseID; +// } +// +// m_nBaseID = nBaseID; +// return true; +// } + +IDetectorSolution* Solution::Copy() { QMutexLocker locker(&m_mutex); - CDetectorSolution* pNewSolution = new CDetectorSolution(); + Solution* pNewSolution = new Solution(); pNewSolution->Initialize(m_pAlgoLibMgr); pNewSolution->SetID(m_nID); @@ -546,27 +509,27 @@ IDetectorSolution* CDetectorSolution::Copy() return pNewSolution; } -void CDetectorSolution::SetRunState(bool bRun) +void Solution::SetRunState(bool bRun) { m_bIsRun = bRun; } -bool CDetectorSolution::GetRunState() +bool Solution::GetRunState() { return m_bIsRun; } -void CDetectorSolution::SetModifyFlag(bool bModify) +void Solution::SetModifyFlag(bool bModify) { m_bIsModify = bModify; } -bool CDetectorSolution::GetModifyFlag() +bool Solution::GetModifyFlag() { return m_bIsModify; } -IDetectorTask* CDetectorSolution::GetTaskByCameraID(int nCameraID) +IDetectorTask* Solution::GetTaskByCameraID(int nCameraID) { QMap::iterator iter = m_CurRunTaskMap.find(nCameraID); if (iter != m_CurRunTaskMap.end()) @@ -577,7 +540,7 @@ IDetectorTask* CDetectorSolution::GetTaskByCameraID(int nCameraID) return nullptr; } -bool CDetectorSolution::Copy(IDetectorSolution* pSrcSolution, bool bRet /* = true */) +bool Solution::Copy(IDetectorSolution* pSrcSolution, bool bRet /* = true */) { if (!pSrcSolution) return false; @@ -588,34 +551,12 @@ bool CDetectorSolution::Copy(IDetectorSolution* pSrcSolution, bool bRet /* = tru if (!SetSolutionInfo(pSrcSolution->GetSolutionInfo())) return false; -// int nTaskCount = pSrcSolution->EnumTask(NULL, 0); -// if (nTaskCount > 0) -// { -// IDetectorTask** lppTask = new IDetectorTask*[nTaskCount]; -// nTaskCount = pSrcSolution->EnumTask(lppTask, nTaskCount); -// -// for (int i = 0; i < nTaskCount; i++) -// { -// if (lppTask[i]) -// { -// CDetectorTask* pNewTask = (CDetectorTask*)AddTask(lppTask[i]->GetTaskInfo()); -// if (pNewTask && !pNewTask->Copy(lppTask[i])) -// { -// return false; -// } -// } -// } -// -// delete[] lppTask; -// } m_nBaseID = pSrcSolution->GetTaskBaseID(); - - return true; } -IDetectorTask* CDetectorSolution::AddAndCopyTask(IDetectorTask* pSrcTask, LP_DETECTOR_TASK tTaskInfo) +IDetectorTask* Solution::AddAndCopyTask(IDetectorTask* pSrcTask, LP_DETECTOR_TASK tTaskInfo) { if (!pSrcTask) return NULL; @@ -634,43 +575,8 @@ IDetectorTask* CDetectorSolution::AddAndCopyTask(IDetectorTask* pSrcTask, LP_DET return pNewTask; } -bool CDetectorSolution::ExportData(QString strFileName, QString strStarTime, QString strEndTime) -{ - return false; -} - -bool CDetectorSolution::GenerateDataTable() -{ - return false; -} - -bool CDetectorSolution::InsertTaskOrder(int nID, int nIndex) -{ -// if (nIndex < 0 || nIndex > m_vecTask.count() - 1) -// return false; -// -// IDetectorTask* pTask = NULL; -// -// for (QVector::iterator iter = m_vecTask.begin(); -// iter != m_vecTask.end(); ++iter) -// { -// IDetectorTask* p = *iter; -// -// if (NULL != p && p->GetID() == nID) -// { -// pTask = p; -// iter = m_vecTask.erase(iter); -// break; -// } -// } -// -// if (pTask) -// m_vecTask.insert(nIndex, pTask); - - return true; -} -void CDetectorSolution::LoadUserParamValue() +void Solution::LoadUserParamValue() { for (QMap::iterator iter = m_TaskMapByID.begin(); iter != m_TaskMapByID.end(); ++iter) { @@ -682,7 +588,7 @@ void CDetectorSolution::LoadUserParamValue() } } -void CDetectorSolution::SaveUserParamValue() +void Solution::SaveUserParamValue() { for (QMap::iterator iter = m_TaskMapByID.begin(); iter != m_TaskMapByID.end(); ++iter) { @@ -694,7 +600,7 @@ void CDetectorSolution::SaveUserParamValue() } } -void CDetectorSolution::ClearUserParamValue() +void Solution::ClearUserParamValue() { for (QMap::iterator iter = m_TaskMapByID.begin(); iter != m_TaskMapByID.end(); ++iter) { @@ -706,12 +612,14 @@ void CDetectorSolution::ClearUserParamValue() } } -QStringList CDetectorSolution::GetAllTaskNames() +QStringList Solution::GetAllTaskNames() { return m_TaskMapByName.keys(); } -QMap CDetectorSolution::GetRunningTask() +QMap Solution::GetRunningTask() { return m_CurRunTaskMap; } + + diff --git a/src/lpbengine/Solution.h b/src/lpbengine/Solution.h index a1d2589..2442449 100644 --- a/src/lpbengine/Solution.h +++ b/src/lpbengine/Solution.h @@ -3,11 +3,11 @@ #include "lpbengine.h" -class CDetectorSolution : public IDetectorSolution +class Solution : public IDetectorSolution { public: - CDetectorSolution(); - virtual ~CDetectorSolution(); + Solution(); + virtual ~Solution(); virtual bool SetSolutionInfo(const PLP_DETECTOR_SOLUTION pSolution); virtual PLP_DETECTOR_SOLUTION GetSolutionInfo(); virtual IDetectorTask* AddTask(const PLP_DETECTOR_TASK pTask, bool bRet = true); @@ -18,7 +18,6 @@ public: bool DeleteTask(QString strName); virtual IDetectorTask* GetTask(int nTaskID); IDetectorTask* GetTask(QString strName); - virtual int EnumTask(IDetectorTask** lppTask, int nCount); virtual void Release(); virtual int GetID() const; void SetID(int nID); @@ -30,16 +29,11 @@ public: virtual void SetModifyFlag(bool bModify); virtual IDetectorTask* GetTaskByCameraID(int nCameraID); - bool Initialize(/*IAlgorithmShare* pAlgoShare,*/ IAlgorithmLibMgr* pAlgoLibMgr); + bool Initialize(IAlgorithmLibMgr* pAlgoLibMgr); void CleanUp(); virtual IDetectorSolution* Copy(); virtual bool Copy(IDetectorSolution* pSrcSolution, bool bRet = true); virtual IDetectorTask* AddAndCopyTask(IDetectorTask* pSrcTask, LP_DETECTOR_TASK tTaskInfo); - virtual bool GenerateDataTable(); - virtual bool ExportData(QString strFileName, QString strStarTime = "", QString strEndTime = ""); - - virtual bool InsertTaskOrder(int nID, int nIndex); - virtual void SaveUserParamValue(); virtual void LoadUserParamValue(); virtual void ClearUserParamValue(); @@ -51,8 +45,8 @@ public: virtual bool SaveFileEx(const QString& strPath); virtual bool SaveFileEx(const QString& strPath, QStringList sTaskNames); virtual bool LoadFileEx(const QString& strPath); - virtual bool SaveFile(const QString& strPath); - virtual bool LoadFile(const QString& strPath); + //virtual bool SaveFile(const QString& strPath); +// virtual bool LoadFile(const QString& strPath); bool SerializeToJson(QJsonObject& jsonObject); bool SerializeFromJson(QJsonObject* pJsonObject); private: @@ -64,11 +58,10 @@ private: QMap m_TaskMapByName; QMap m_TaskMapByID; QMap m_CurRunTaskMap;//CamID(int),TaskPtr(IDetectorTask*) - -// IAlgorithmShare* m_pAlgoShare; IAlgorithmLibMgr* m_pAlgoLibMgr; - QMutex m_mutex; + + QStringList m_tasklist;//task名列表 }; #endif // SOLUTION_H \ No newline at end of file diff --git a/src/lpbengine/SolutionMgr.cpp b/src/lpbengine/SolutionMgr.cpp index ef0746a..be2e2f0 100644 --- a/src/lpbengine/SolutionMgr.cpp +++ b/src/lpbengine/SolutionMgr.cpp @@ -24,7 +24,7 @@ IDetectorSolution* CDetectorSolutionMgr::AddSolution(const PLP_DETECTOR_SOLUTION if (NULL == pSolution) return NULL; - CDetectorSolution* p = new CDetectorSolution(); + Solution* p = new Solution(); if (p->Initialize(m_pAlgoLibMgr) && p->SetSolutionInfo(pSolution)) { @@ -37,7 +37,7 @@ IDetectorSolution* CDetectorSolutionMgr::AddSolution(const PLP_DETECTOR_SOLUTION return NULL; } -bool CDetectorSolutionMgr::DeleteSolution(int nSolutionID) +bool CDetectorSolutionMgr::DeleteSolutionByID(int nSolutionID) { if (m_nRunSolutionID == nSolutionID) m_nRunSolutionID = LP_DETECTOR_INVALID_ID; @@ -51,8 +51,10 @@ bool CDetectorSolutionMgr::DeleteSolution(int nSolutionID) return false; } -IDetectorSolution* CDetectorSolutionMgr::GetSolution(int nSolutionID) +IDetectorSolution* CDetectorSolutionMgr::GetSolutionByID(int nSolutionID) { + if (nSolutionID == 0) + return m_vecSolution.first(); QMap::iterator it = m_vecSolution.find(nSolutionID); if (it != m_vecSolution.end()) { @@ -62,6 +64,16 @@ IDetectorSolution* CDetectorSolutionMgr::GetSolution(int nSolutionID) return NULL; } +int CDetectorSolutionMgr::GetSolutionCount() +{ + return m_vecSolution.size(); +} + +QMap CDetectorSolutionMgr::GetAllSolutions() +{ + return m_vecSolution; +} + bool CDetectorSolutionMgr::CheckSolution(int nSolutionID, QString strSolutionName) { for (QMap::iterator iter = m_vecSolution.begin(); @@ -78,25 +90,6 @@ bool CDetectorSolutionMgr::CheckSolution(int nSolutionID, QString strSolutionNam return false; } -int CDetectorSolutionMgr::EnumSolution(IDetectorSolution** lppSolution, int nCount) -{ - if (!lppSolution || nCount < m_vecSolution.size()) - return m_vecSolution.size(); - - int nIndex = 0; - for (QMap::iterator iter = m_vecSolution.begin(); - iter != m_vecSolution.end(); ++iter) - { - if (NULL != *iter) - { - lppSolution[nIndex] = *iter; - nIndex++; - } - } - - return nIndex; -} - void CDetectorSolutionMgr::CleanUp() { for (QMap::iterator iter = m_vecSolution.begin(); @@ -121,7 +114,7 @@ bool CDetectorSolutionMgr::Save() { if (*iter) { - CDetectorSolution* p = (CDetectorSolution*)*iter; + Solution* p = (Solution*)*iter; if (p->GetSolutionInfo()->nType == SolutionType::LP_EXTRA) continue; @@ -179,7 +172,7 @@ bool CDetectorSolutionMgr::SaveByNames(QStringList strNames) { if (*iter) { - CDetectorSolution* p = (CDetectorSolution*)*iter; + Solution* p = (Solution*)*iter; if (p->GetSolutionInfo()->nType == SolutionType::LP_EXTRA) continue; @@ -225,7 +218,7 @@ bool CDetectorSolutionMgr::SaveByNames(QStringList strNames) } return true; } - +//加载配置文件 bool CDetectorSolutionMgr::Load() { QString strExePath = QCoreApplication::applicationDirPath(); @@ -236,7 +229,7 @@ bool CDetectorSolutionMgr::Load() solutionDir.mkdir(strSolutionDirPath); } - m_nRunSolutionID = 1; + m_nRunSolutionID = 0; solutionDir.setFilter(QDir::Dirs | QDir::Hidden | QDir::NoSymLinks); solutionDir.setSorting(QDir::Size | QDir::Reversed); @@ -248,43 +241,26 @@ bool CDetectorSolutionMgr::Load() if (dirList.at(i).fileName() == "." || dirList.at(i).fileName() == "..") continue; + //加载解决方案文件夹 QString strSolutionFile = strSolutionDirPath + dirList.at(i).fileName(); - LP_DETECTOR_SOLUTION solutionInfo; - - CDetectorSolution* pSolution = (CDetectorSolution*)AddSolution(&solutionInfo); - if (!pSolution->LoadFileEx(strSolutionFile)) - { - qErrnoWarning("load solution: %s fail", strSolutionFile.toLocal8Bit().data()); - DeleteSolution(pSolution->GetID()); - pSolution = NULL; - } - if (pSolution) - nBaseID = pSolution->GetID() > nBaseID ? pSolution->GetID() : nBaseID; - } - - //兼容老版本的solution处理 - solutionDir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); - solutionDir.setSorting(QDir::Size | QDir::Reversed); - QFileInfoList fileList = solutionDir.entryInfoList(); - for (int i = 0; i < fileList.size(); i++) - { - if (fileList.at(i).fileName() == "." || fileList.at(i).fileName() == "..") + QString path = strSolutionFile + "/info.json"; + QFileInfo finfo(path); + if(false == finfo.exists()) continue; - QString strSolutionFile = strSolutionDirPath + fileList.at(i).fileName(); + LP_DETECTOR_SOLUTION solutionInfo; - CDetectorSolution* pSolution = (CDetectorSolution*)AddSolution(&solutionInfo); - if (!pSolution->LoadFile(strSolutionFile)) - { + Solution* pSolution = (Solution*)AddSolution(&solutionInfo); + if (!pSolution->LoadFileEx(strSolutionFile)) + {//有bug qErrnoWarning("load solution: %s fail", strSolutionFile.toLocal8Bit().data()); - DeleteSolution(pSolution->GetID()); + DeleteSolutionByID(pSolution->GetID());// pSolution = NULL; } if (pSolution) nBaseID = pSolution->GetID() > nBaseID ? pSolution->GetID() : nBaseID; } - m_nBaseID = nBaseID; return true; @@ -308,14 +284,14 @@ bool CDetectorSolutionMgr::ReLoad() bool CDetectorSolutionMgr::SetRunSolution(int nSolutionID) { m_nRunSolutionID = nSolutionID; - IDetectorSolution* pRunSolution = GetSolution(nSolutionID); + IDetectorSolution* pRunSolution = GetSolutionByID(nSolutionID); return true; } IDetectorSolution* CDetectorSolutionMgr::GetRunSolution() { - return GetSolution(m_nRunSolutionID); + return GetSolutionByID(m_nRunSolutionID); } IDetectorSolution* CDetectorSolutionMgr::AddAndCopySolution(IDetectorSolution* pSrcSolution) diff --git a/src/lpbengine/SolutionMgr.h b/src/lpbengine/SolutionMgr.h index 23afb77..fd229c7 100644 --- a/src/lpbengine/SolutionMgr.h +++ b/src/lpbengine/SolutionMgr.h @@ -9,9 +9,11 @@ public: CDetectorSolutionMgr(); virtual ~CDetectorSolutionMgr(); IDetectorSolution* AddSolution(const PLP_DETECTOR_SOLUTION pSolution, bool bRet = true); - bool DeleteSolution(int nSolutionID); - IDetectorSolution* GetSolution(int nSolutionID); - int EnumSolution(IDetectorSolution** lppSolution, int nCount); + bool DeleteSolutionByID(int nSolutionID); + IDetectorSolution* GetSolutionByID(int nSolutionID); + int GetSolutionCount(); + QMap GetAllSolutions(); + void CleanUp(); bool Initialize(IAlgorithmLibMgr* pAlgoLibMgr); diff --git a/src/lpbengine/Task.cpp b/src/lpbengine/Task.cpp index c65de07..283f0d4 100644 --- a/src/lpbengine/Task.cpp +++ b/src/lpbengine/Task.cpp @@ -342,13 +342,13 @@ bool CDetectorTask::SerializeToJson(QJsonObject& jsonObject) return true; } - +/*解析json数据*/ bool CDetectorTask::SerializeFromJson(QJsonObject* pJsonObject) { if (!pJsonObject) return false; - m_tTask.strName = pJsonObject->value("task_name").toString(); + //m_tTask.strName = pJsonObject->value("task_name").toString(); m_tTask.nCameraID = pJsonObject->value("task_cameraID").toInt(); m_tTask.strDescription = pJsonObject->value("task_description").toString(); m_tTask.strDirPath = pJsonObject->value("task_default_dir").toString(); @@ -356,24 +356,21 @@ bool CDetectorTask::SerializeFromJson(QJsonObject* pJsonObject) m_tTask.bIsRun = pJsonObject->value("task_run").toBool(true); m_nID = pJsonObject->value("task_id").toInt(); m_nRunAlgoID = pJsonObject->value("task_algo_run_id").toInt(); - - - { - //加载默认图片 - QString strExePath = QCoreApplication::applicationDirPath(); - QString strImagePath = strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; - QString strImageName = strImagePath + QString::number(m_pSolution->GetID()) + "_" + QString::number(m_nID) + ".bmp"; - std::string strpath = strImageName.toLocal8Bit().toStdString(); - m_tTask.templateImg = cv::imread(strpath/*strImageName.toLatin1().data()*/, CV_LOAD_IMAGE_UNCHANGED); - _strPath = strpath; - strtempImgPath = strImageName; - } - - - + + //加载模板标定图片 + //QString strExePath = QCoreApplication::applicationDirPath(); + QString strImagePath = m_taskPath;// strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; + QString strImageName = strImagePath + "/template.png";// QString::number(m_pSolution->GetID()) + "_" + QString::number(m_nID) + ".bmp"; + std::string strpath = strImageName.toLocal8Bit().toStdString(); + m_tTask.templateImg = cv::imread(strpath, CV_LOAD_IMAGE_UNCHANGED); + _strPath = strpath; + strtempImgPath = strImageName; + + //加载扩展参数 if (!SerializePropertyFromJson(pJsonObject)) return false; + //加载算法参数 QJsonArray algoArray = pJsonObject->value("algoArray").toArray(); for (int i = 0; i < algoArray.size(); i++) { @@ -414,8 +411,8 @@ bool CDetectorTask::SaveFile(const QString& strPath) if (m_pSolution && !m_tTask.templateImg.empty()) { - QString strExePath = QCoreApplication::applicationDirPath(); - QString strFilePath = strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; + //QString strExePath = m_taskPath;// QCoreApplication::applicationDirPath(); + QString strFilePath = m_taskPath;// strExePath + LP_DETECTOR_BUSSINESS_IMAGE_DIR; QDir dir; if (!dir.exists(strFilePath)) { @@ -423,7 +420,7 @@ bool CDetectorTask::SaveFile(const QString& strPath) return false; } - QString strFileName = strFilePath + QString::number(m_pSolution->GetID()) + "_" + QString::number(m_nID) + ".bmp"; + QString strFileName = strFilePath + /*QString::number(m_pSolution->GetID()) + "_" + QString::number(m_nID)*/ + "template.png"; std::string strpath = strFileName.toLocal8Bit().toStdString(); if (!cv::imwrite(strpath/*strFileName.toLatin1().data()*/, m_tTask.templateImg)) @@ -451,11 +448,12 @@ bool CDetectorTask::SaveFile(const QString& strPath) bool CDetectorTask::LoadFile(const QString& strPath) { - strParamFilePath = strPath; + m_taskPath = strPath; + strParamFilePath = strPath +"/taskinfo.json"; QJsonDocument document; QJsonParseError parse_error; - QFile taskFile(strPath); + QFile taskFile(strParamFilePath); if (!taskFile.open(QFile::ReadOnly)) { return false; @@ -470,15 +468,11 @@ bool CDetectorTask::LoadFile(const QString& strPath) } document = QJsonDocument::fromJson(byteArray, &parse_error); - if (parse_error.error == QJsonParseError::NoError) - { - if (!document.isEmpty() && !document.isNull()) - { - if (document.isObject()) - { + if (parse_error.error == QJsonParseError::NoError) { + if (!document.isEmpty() && !document.isNull()) { + if (document.isObject()) { QJsonObject taskJsonObject = document.object(); - if (!SerializeFromJson(&taskJsonObject)) - { + if (!SerializeFromJson(&taskJsonObject)) { taskFile.close(); return false; } @@ -560,8 +554,6 @@ void CDetectorTask::CleanUp() if (!m_tTask.templateImg.empty()) { m_tTask.templateImg.release(); - //cvReleaseImage(&m_tTask.pImg); - //m_tTask.pImg = NULL; } for (QVector::iterator iter = m_vecROI.begin(); diff --git a/src/lpbengine/Task.h b/src/lpbengine/Task.h index dab3cd3..d7f0e6a 100644 --- a/src/lpbengine/Task.h +++ b/src/lpbengine/Task.h @@ -68,6 +68,8 @@ public: virtual double ExecTime() const { return m_dExecTime; } virtual bool SyncMapResult(const QVariantMap& vMap); + + virtual QString GetPath() { return m_taskPath; } protected: int GetProductCount(); @@ -81,7 +83,6 @@ private: QVector m_vecAlgorithm; IDetectorSolution* m_pSolution; - //IAlgorithmShare* m_pAlgoShare; IAlgorithmLibMgr* m_pAlgoLibMgr; bool m_bRunning; @@ -91,6 +92,7 @@ private: QString strtempImgPath; QString strParamFilePath; QStringList strPathList; + QString m_taskPath; }; #endif // RTask_H \ No newline at end of file diff --git a/tpvs17/caliCenter/algEg.cpp b/tpvs17/caliCenter/algEg.cpp new file mode 100644 index 0000000..d24b4b9 --- /dev/null +++ b/tpvs17/caliCenter/algEg.cpp @@ -0,0 +1,79 @@ +#include "algEg.h" +#include "caliCenter.h" +#include "qtcvutils.h" + +using namespace luffy_base; +algEg::algEg() +{ +} + +algEg::~algEg() +{ + +} + +bool algEg::Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm) +{ + qDebug() << "start cali center"; + //GetParamValue("ROI", LP_ROI).value(); + int nID = lpTask->GetTaskInfo()->nCameraID; + + Mat gray; + if (!lpTask->GetTaskInfo()->detectImg.empty()) { + luffy_imageProc::createImage(lpTask->GetTaskInfo()->detectImg, gray, luffy_imageProc::emCreateGray); + } + + if (gray.empty()) { + qWarning() << "cali center, gray is empty"; + return false; + } + if (gray.size() != paramInput.roi.img.size()) + { + qWarning() << "img size not compare"; + return false; + } + Mat mask; + luffy_imageProc::createImage(gray, mask, luffy_imageProc::emCreateColor); + m_objDetect.detect(gray, paramInput, paramOutput, mask); + QPointF pt(paramOutput.ptCenter.x, paramOutput.ptCenter.y); + lpAlgorithm->SetOutParamValue("center", pt); + lpAlgorithm->SetOutParamValue("image", EngineBase::convMat2QImage(mask)); + QVariant getCenterRoi; + getCenterRoi.setValue(paramOutput.centerRoi); + lpAlgorithm->SetOutParamValue("centerRoi", getCenterRoi); + qDebug() << "finish cali center"; + return true; +} + +bool algEg::Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm) +{ + LP_ALGORITHM_PARAM param1("ROI", LP_ROI, QVariant(), QObject::tr("圆心模板")); + lpAlgorithm->AddParam(¶m1, 1); + + LP_ALGORITHM_PARAM param2("center", LP_POINTF); + lpAlgorithm->AddOutParam(¶m2, 1); + + LP_ALGORITHM_PARAM param3("image", LP_IMAGE); + lpAlgorithm->AddOutParam(¶m3, 1); + + LP_ALGORITHM_PARAM param4("centerRoi", LP_MAT); + lpAlgorithm->AddOutParam(¶m4, 1); + + + return true; +} + + +void LpAlgoNewInstance(IAlgo** lppAlgo) +{ + *lppAlgo = (IAlgo*)new algEg(); +} + +bool LpAlgoDeleteInstance() +{ + return true; +} \ No newline at end of file diff --git a/tpvs17/caliCenter/algEg.h b/tpvs17/caliCenter/algEg.h new file mode 100644 index 0000000..4c93418 --- /dev/null +++ b/tpvs17/caliCenter/algEg.h @@ -0,0 +1,23 @@ +#ifndef _ALG_EG_H_ +#define _ALG_EG_H_ + +#include ".\lpbengine.h" +#include ".\lpalgorithm.h" + + + + +class algEg : IAlgo +{ +public: + algEg(); + ~algEg(); + virtual bool Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm); + virtual bool Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm); +private: + + +}; + + +#endif // _ALG_EG_H_ diff --git a/tpvs17/caliCenter/algEg_global.h b/tpvs17/caliCenter/algEg_global.h new file mode 100644 index 0000000..0eb7f01 --- /dev/null +++ b/tpvs17/caliCenter/algEg_global.h @@ -0,0 +1,12 @@ +#ifndef _ALG_EG_GLOBAL_H_ +#define _ALG_EG_GLOBAL_H_ + +#include + +#ifdef ALG_EG_LIB +# define ALG_EG_EXPORT Q_DECL_EXPORT +#else +# define ALG_EG_EXPORT Q_DECL_IMPORT +#endif + +#endif // _ALG_EG_GLOBAL_H_ diff --git a/tpvs17/caliCenter/caliCenter.cpp b/tpvs17/caliCenter/caliCenter.cpp new file mode 100644 index 0000000..cb4323c --- /dev/null +++ b/tpvs17/caliCenter/caliCenter.cpp @@ -0,0 +1,70 @@ +#include "caliCenter.h" +#include "lpbengine.h" +using namespace luffy_base; +CaliCenter::CaliCenter() +{ +} + + +CaliCenter::~CaliCenter() +{ +} + +cv::Mat createCenterRoi(Mat &src, const Point2f ¢er, const float & radius) +{ + Mat srcImg = src.clone(); + //Mat centerMask(srcImg.size(), src.type(), Scalar::all(0)); + if ((center.x - radius) < 0 || (center.y - radius) < 0 || (center.x - radius + 2 * radius) > srcImg.cols || (center.y - radius + 2 * radius) > srcImg.rows) + return Mat(); + return srcImg(Rect(center.x - radius, center.y - radius, 2*radius, 2*radius)); +} + +bool CaliCenter::detect(Mat & imgSrc, InputParam ¶mIn, OutputParam ¶mOut, Mat &imgDst /*= Mat()*/) +{ + Record_List records = paramIn.roi.records; + int nCircleCount = records.size(); + + if (nCircleCount == 0) { + qWarning() << "no circle count"; + return false; + } + if (nCircleCount >= 2) { + qWarning() << "circle count is more than 1"; + } + + luffy_base::luffyCircle realCircle; + for (int i = 0; i < nCircleCount; i++) + { + Item_List item = records.at(i); + Feature_List feature = item.at(0); + + if (1 == feature.first) { + realCircle.ptCenter = Point2f(feature.second.at(0), feature.second.at(1)); + realCircle.fRadius = feature.second.at(2); + break; + } + } + + //bob add abs() fRadius会出现负数 + realCircle.fRadius = abs(realCircle.fRadius); + + Mat centerRoi = createCenterRoi(imgSrc, realCircle.ptCenter, realCircle.fRadius); + paramOut.centerRoi = centerRoi; + /*Mat imgBinary; + cv::threshold(imgSrc, imgBinary, paramIn.nGray, 255.0, THRESH_BINARY); + Mat imgHit; + vector vecHits; + luffy_hit::firstHit4Circle(imgBinary, imgHit, vecHits, realCircle.ptCenter, 10, realCircle.fRadius + 100, 60, luffy_hit::emHitIn2Out); + + vector vecRes = luffy_imageProc::fitModelbyRansac(vecHits, luffy_imageProc::emModelCircle, 0.4, 3, 20, 20, 30); + luffy_imageProc::lsCircleFit(vecRes, realCircle.fRadius, realCircle.ptCenter);*/ + + paramOut.ptCenter = realCircle.ptCenter; + if (!imgDst.empty()) { + + cv::circle(imgDst, realCircle.ptCenter, realCircle.fRadius, LP_COLOR_RED, 2); + cv::circle(imgDst, realCircle.ptCenter, 5, LP_COLOR_BLUE, -1); + } + + return true; +} diff --git a/tpvs17/caliCenter/caliCenter.h b/tpvs17/caliCenter/caliCenter.h new file mode 100644 index 0000000..2174f67 --- /dev/null +++ b/tpvs17/caliCenter/caliCenter.h @@ -0,0 +1,29 @@ +#ifndef LP_VALVE_DETECTOR_H +#define LP_VALVE_DETECTOR_H + + +#include "Luffy.h" +#include "lpbengine.h" +using namespace luffy_base; + +struct InputParam +{ + LP_DETECTOR_ROI_DATA roi; +}; + +struct OutputParam +{ + Point2f ptCenter; + Mat centerRoi; +}; + +class CaliCenter +{ +public: + CaliCenter(); + ~CaliCenter(); + + bool detect(Mat & imgSrc, InputParam ¶mIn, OutputParam ¶mOut, Mat &imgDst = Mat()); +}; + +#endif //LP_VALVE_DETECTOR_H \ No newline at end of file diff --git a/tpvs17/caliCenter/caliCenter.vcxproj b/tpvs17/caliCenter/caliCenter.vcxproj new file mode 100644 index 0000000..cbbd534 --- /dev/null +++ b/tpvs17/caliCenter/caliCenter.vcxproj @@ -0,0 +1,106 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE} + Qt4VSv1.0 + caliCenter + 10.0.16299.0 + + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + + + + + + + + + + + <_ProjectFileVersion>12.0.30501.0 + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(ProjectName) + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + _UNICODE;_UNICODE;_UNICODE;ALGO_LIB;QT_CORE_LIB;QT_GUI_LIB;UNICODE;WIN32;WIN64;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;.\..\..\3part\tadpole\include\tpBase;.\..\..\3part\opencv3.4.1\include;.\..\..\3part\opencv3.4.1\include\opencv;.\..\..\3part\opencv3.4.1\include\opencv2;.\..\..\..\Cyclops\include;.\..\..\3part\Cyclops\include;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(SolutionDir)..\runner17\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\3part\opencv3.4.1\x64\vc15\lib;..\..\3part\Cyclops\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Widgetsd.lib;Qt5Guid.lib;luffyd.lib;cyclopsd.lib;opencv_world341d.lib;%(AdditionalDependencies) + MachineX64 + /SUBSYSTEM:WINDOWS + + + + + _UNICODE;_UNICODE;_UNICODE;ALGO2_LIB;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_NO_DEBUG;UNICODE;WIN32;WIN64;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;.\..\..\3part\tadpole\include\tpBase;.\..\..\3part\opencv3.4.1\include;.\..\..\3part\opencv3.4.1\include\opencv;.\..\..\3part\opencv3.4.1\include\opencv2;.\..\..\..\Cyclops\include;.\..\..\3part\Cyclops\include;%(AdditionalIncludeDirectories) + + + MultiThreadedDLL + true + + + Windows + $(SolutionDir)..\runner17\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\3part\opencv3.4.1\x64\vc15\lib;..\..\3part\Cyclops\lib;%(AdditionalLibraryDirectories) + false + qtmain.lib;Qt5Core.lib;Qt5Widgets.lib;Qt5Gui.lib;luffy.lib;cyclops.lib;opencv_world341.lib;%(AdditionalDependencies) + MachineX64 + /SUBSYSTEM:WINDOWS + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/caliCenter/caliCenter.vcxproj.filters b/tpvs17/caliCenter/caliCenter.vcxproj.filters new file mode 100644 index 0000000..9526b7e --- /dev/null +++ b/tpvs17/caliCenter/caliCenter.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;cxx;c;def + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C} + ts + false + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Translation Files + + + \ No newline at end of file diff --git a/tpvs17/caliValve/algEg.cpp b/tpvs17/caliValve/algEg.cpp new file mode 100644 index 0000000..cca0e7e --- /dev/null +++ b/tpvs17/caliValve/algEg.cpp @@ -0,0 +1,190 @@ +#include "algEg.h" +#include "CaliValve.h" +#include "qtcvutils.h" +using namespace luffy_base; +#pragma execution_character_set("utf-8") +algEg::algEg() +{ + luffy_triangle::createNewTrigValue(360); +} + +algEg::~algEg() +{ + +} + +bool algEg::Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm) +{ + qDebug() << "start cali valve"; + //GetTaskInfo()->nCameraID; + QString strObj = lpTask->GetTaskInfo()->strName; + if (strObj.isEmpty()) { + qWarning() << "cali valve, obj is empty"; + return false; + } + + paramInput.roi = lpAlgorithm->GetParamValue("ROI", LP_ROI).value(); + paramInput.barROI = lpAlgorithm->GetParamValue("barROI", LP_ROI).value(); + paramInput.barNum = lpAlgorithm->GetParamValue("barNum", LP_INT).toInt(); + paramInput.flagCircle = lpAlgorithm->GetParamValue("flagCircle", LP_INT).toInt(); + paramInput.backgroundThresh = lpAlgorithm->GetParamValue("backgroundThresh", LP_INT).toInt(); + paramInput.ifClasify = lpAlgorithm->GetParamValue("ifClasify", LP_INT).toInt(); + paramInput.ibackground = lpAlgorithm->GetParamValue("ibackground", LP_INT).toInt(); + QPointF pt = lpAlgorithm->GetParamValue("center", LP_POINTF).toPointF(); + paramInput.ptCenter = Point2f(pt.x(), pt.y()); + if (pt.x()==0 || pt.y() == 0) { + qWarning() << "cali valve, center is zero"; + } + Mat mask;Mat gray; + if (!lpTask->GetTaskInfo()->detectImg.empty()) { + luffy_imageProc::createImage(lpTask->GetTaskInfo()->detectImg, gray, luffy_imageProc::emCreateGray); + } +// else { +// luffy_imageProc::createImage(paramInput.roi.img, gray, luffy_imageProc::emCreateGray); +// } + + if (gray.empty()) { + qWarning() << "cali valve, gray is empty"; + return false; + } + if (gray.size() != paramInput.roi.img.size()) + { + qWarning() << "img size not compare"; + return false; + } + //if (paramInput.ifClasify == 1) + if (paramInput.ibackground == 1) + { + QString str = qApp->applicationDirPath() + QString("\\backGround\\%1.BMP").arg(nID);//imread("E:\\1.BMP"); + if (str.isEmpty()) + { + qDebug() << "cali valve : cannot background dir "; + return false; + } + else + { + std::string starName = str.toLocal8Bit().toStdString(); + paramOutput.background = imread(starName,0); + } + if (paramOutput.background.empty()) + { + qDebug() << "cali valve : background image is empty"; + //return false; + } + } + + luffy_imageProc::createImage(gray, mask, luffy_imageProc::emCreateColor); + + m_objDetect.detect(gray, paramInput, paramOutput, mask); + QVariant img, barImg, baseImg, weightMat, backgroundImage; + img.setValue(paramOutput.imgTemplate); + barImg.setValue(paramOutput.barTemplate); + baseImg.setValue(paramOutput.baseImage); + weightMat.setValue(paramOutput.weightMat); + backgroundImage.setValue(paramOutput.background); + lpAlgorithm->SetOutParamValue("valveTemplate", img); + lpAlgorithm->SetOutParamValue("image", lp::QtCVUtils::cvMatToQImage(mask)); + lpAlgorithm->SetOutParamValue("center", pt); + lpAlgorithm->SetOutParamValue("valveDis", paramOutput.fValveDis); + lpAlgorithm->SetOutParamValue("valveWidth", paramOutput.fValveWidth); + lpAlgorithm->SetOutParamValue("valveOffset", paramOutput.nValveOffset); + lpAlgorithm->SetOutParamValue("barTemplate", barImg); + lpAlgorithm->SetOutParamValue("withinOffset", paramOutput.withinOffset); + lpAlgorithm->SetOutParamValue("barNum", paramInput.barNum); + lpAlgorithm->SetOutParamValue("flagCircle", paramInput.flagCircle); + lpAlgorithm->SetOutParamValue("baseImage", baseImg); + lpAlgorithm->SetOutParamValue("weightMat", weightMat); + lpAlgorithm->SetOutParamValue("backgroundThresh", paramInput.backgroundThresh); + lpAlgorithm->SetOutParamValue("background", backgroundImage); + qDebug() << "finish cali valve"; + return true; +} + +bool algEg::Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm) +{ + LP_ALGORITHM_PARAM param1("center", LP_POINTF, QVariant(), QObject::tr("轮毂中心坐标,绑定圆心定位")); + lpAlgorithm->AddParam(¶m1, 1); + LP_ALGORITHM_PARAM param2("ROI", LP_ROI, QVariant(), QObject::tr("气门芯模板")); + lpAlgorithm->AddParam(¶m2, 1); + LP_ALGORITHM_PARAM param3("barROI", LP_ROI, QVariant(), QObject::tr("辐条模板")); + lpAlgorithm->AddParam(¶m3, 1); + + LP_ALGORITHM_PARAM param4("flagCircle", LP_INT, 0, QObject::tr("无气门芯识别")); + lpAlgorithm->AddParam(¶m4, 1); + + LP_ALGORITHM_PARAM param5("backgroundThresh", LP_INT, 15, QObject::tr("背景剪除阈值")); + lpAlgorithm->AddParam(¶m5, 1); + + LP_ALGORITHM_PARAM param6("ifClasify", LP_INT, 0, QObject::tr("型号判定,0关闭,1打开")); + lpAlgorithm->AddParam(¶m6, 1); + + LP_ALGORITHM_PARAM param61("ibackground", LP_INT, 0, QObject::tr("背景图启用,0关闭,1打开")); + lpAlgorithm->AddParam(¶m61, 1); + + LP_ALGORITHM_PARAM param7("barNum", LP_INT, 0, QObject::tr("辐条数量")); + lpAlgorithm->AddParam(¶m7, 1); + + LP_ALGORITHM_PARAM param8("center", LP_POINTF); + lpAlgorithm->AddOutParam(¶m8, 1); + + LP_ALGORITHM_PARAM param9("image", LP_IMAGE); + lpAlgorithm->AddOutParam(¶m9, 1); + + LP_ALGORITHM_PARAM param10("valveDis", LP_DOUBLE); + lpAlgorithm->AddOutParam(¶m10, 1); + + LP_ALGORITHM_PARAM param11("valveWidth", LP_DOUBLE); + lpAlgorithm->AddOutParam(¶m11, 1); + + LP_ALGORITHM_PARAM param12("valveOffset", LP_INT); + lpAlgorithm->AddOutParam(¶m12, 1); + + LP_ALGORITHM_PARAM param13("valveTemplate", LP_MAT); + lpAlgorithm->AddOutParam(¶m13, 1); + + + LP_ALGORITHM_PARAM param14("barTemplate", LP_MAT); + lpAlgorithm->AddOutParam(¶m14, 1); + + LP_ALGORITHM_PARAM param15("withinOffset", LP_INT); + lpAlgorithm->AddOutParam(¶m15, 1); + + LP_ALGORITHM_PARAM param16("barNum", LP_INT); + lpAlgorithm->AddOutParam(¶m16, 1); + + LP_ALGORITHM_PARAM param17("flagCircle", LP_INT); + lpAlgorithm->AddOutParam(¶m17, 1); + + + LP_ALGORITHM_PARAM param18("baseImage", LP_MAT); + lpAlgorithm->AddOutParam(¶m18, 1); + + + LP_ALGORITHM_PARAM param19("weightMat", LP_MAT); + lpAlgorithm->AddOutParam(¶m19, 1); + + + LP_ALGORITHM_PARAM param20("backgroundThresh", LP_INT); + lpAlgorithm->AddOutParam(¶m20, 1); + + + LP_ALGORITHM_PARAM param21("background", LP_MAT); + lpAlgorithm->AddOutParam(¶m21, 1); + + return true; +} + + +void LpAlgoNewInstance(IAlgo** lppAlgo) +{ + *lppAlgo = (IAlgo*)new algEg(); +} + +bool LpAlgoDeleteInstance() +{ + return true; +} diff --git a/tpvs17/caliValve/algEg.h b/tpvs17/caliValve/algEg.h new file mode 100644 index 0000000..adeabda --- /dev/null +++ b/tpvs17/caliValve/algEg.h @@ -0,0 +1,23 @@ +#ifndef _ALG_EG_H_ +#define _ALG_EG_H_ + +#include ".\lpbengine.h" +#include ".\lpalgorithm.h" + + + + +class algEg : IAlgo +{ +public: + algEg(); + virtual ~algEg(); + virtual bool Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm); + virtual bool Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm); +private: + + +}; + + +#endif // _ALG_EG_H_ diff --git a/tpvs17/caliValve/algEg_global.h b/tpvs17/caliValve/algEg_global.h new file mode 100644 index 0000000..0eb7f01 --- /dev/null +++ b/tpvs17/caliValve/algEg_global.h @@ -0,0 +1,12 @@ +#ifndef _ALG_EG_GLOBAL_H_ +#define _ALG_EG_GLOBAL_H_ + +#include + +#ifdef ALG_EG_LIB +# define ALG_EG_EXPORT Q_DECL_EXPORT +#else +# define ALG_EG_EXPORT Q_DECL_IMPORT +#endif + +#endif // _ALG_EG_GLOBAL_H_ diff --git a/tpvs17/caliValve/caliValve.cpp b/tpvs17/caliValve/caliValve.cpp new file mode 100644 index 0000000..e8b3ae0 --- /dev/null +++ b/tpvs17/caliValve/caliValve.cpp @@ -0,0 +1,502 @@ +#include "CaliValve.h" +#define VIEW_INTERNAL_MAT +using namespace luffy_base; +CaliValve::CaliValve() +{ +} + + +CaliValve::~CaliValve() +{ +} +double disOfPoint(const Point2f& p1, const Point2f& p2) +{ + return norm(p1 - p2); +} +void CaliValve::preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold) +{ + + if (img.type() != CV_32FC1) + { + img.convertTo(img, CV_32FC1); + } + + Mat gaussImg; + GaussianBlur(img, gaussImg, Size(3, 3), 5.0); + img = gaussImg; + + Mat dilatedMask; + dilate(mask, dilatedMask, Mat::ones(Size(3, 3), CV_32FC1)); + Mat hightlightsMask = img < highlightsThreshold; + Mat imgMask = hightlightsMask & (mask > 0); + + Scalar meanScalar, stddevScalar; + meanStdDev(img, meanScalar, stddevScalar, imgMask); + img = (img - meanScalar.val[0]) * dstStddev / stddevScalar.val[0] + dstMean; + imgMask.convertTo(imgMask, CV_32FC1); + imgMask /= 255.0; + Mat imgNorm = cocentricNorm(img, Point2f(img.cols / 2.0, img.rows / 2.0), + imgMask, 125); +#ifdef DEBUG_VIEW_INTERNAL_MAT + Mat vImgNorm = imgNorm / 255.0; +#endif + img = imgNorm; +} + +cv::Mat CaliValve::genMask(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; + } + if (outterR == -1) + { + // default is max radius - 10 + outterR = img.rows*0.425; + } + circle(mask, center, outterR, Scalar(255), -1); + circle(mask, center, innerR, Scalar(0), -1); + if (type != CV_8UC1) + { + mask.convertTo(mask, type); + mask /= 255; + } + return mask; +} + +cv::Mat CaliValve::cocentricNorm(Mat& img, Point2f center, const Mat& weightMat, float dstMeanVal) +{ + assert(weightMat.empty() || weightMat.type() == CV_32FC1); + + int w = img.cols; + int h = img.rows; + vector corners; + corners.push_back(Point2f(0, 0)); + corners.push_back(Point2f(0, h)); + corners.push_back(Point2f(w, h)); + corners.push_back(Point2f(w, 0)); + vector cornerDisVec; + for_each(corners.begin(), corners.end(), [&](const Point2f& pt) + { + double dis = disOfPoint(center, pt); + cornerDisVec.push_back(dis); + }); + + auto farthestCornerDis = max_element(cornerDisVec.begin(), cornerDisVec.end()); + float maxRadius = *farthestCornerDis; + + int radiusNum = floorf(maxRadius); + //radiusNum = 20; + float radiusStep = (maxRadius / radiusNum); + Mat cocentricSumMat = Mat::zeros(1, radiusNum, CV_32FC1); + float* pSumData = (float*)cocentricSumMat.data; + Mat cocentricWeightSumMat = Mat::zeros(1, radiusNum, CV_32FC1); + float* pWeightSumData = (float*)cocentricWeightSumMat.data; + Mat radiusMat(img.rows, img.cols, CV_32FC1); + + for (int y = 0; y < h; y++) + { + const Mat& imgRow = img.row(y); + float* pImgRowData = (float*)imgRow.data; + float* pRadiusRowData = (float*)radiusMat.row(y).data; + + float* pWeightRowData = NULL; + if (!weightMat.empty()) + { + pWeightRowData = (float*)weightMat.row(y).data; + } + + for (int x = 0; x < w; x++) + { + //std::cout << x << " " << y << std::endl; + float weight; + if (pWeightRowData) + { + weight = pWeightRowData[x]; + } + else + { + weight = 1.0; + } + float val = pImgRowData[x] * weight; + float radius = disOfPoint(Point2f(x, y), center); + pRadiusRowData[x] = radius; + int radiusIdx0 = (int)(radius / radiusStep); + assert(radiusIdx0 >= 0); + int radiusIdx1 = radiusIdx0 + 1; + if (radiusIdx0 >= radiusNum - 1) + { + pSumData[radiusNum - 1] += val; + pWeightSumData[radiusNum - 1] += weight; + } + else + { + float s = (radius - radiusStep*radiusIdx0) / radiusStep; + pSumData[radiusIdx0] += val*s; + pSumData[radiusIdx1] += val*(1 - s); + pWeightSumData[radiusIdx0] += s*weight; + pWeightSumData[radiusIdx1] += (1 - s)*weight; + } + } + // CvPlot::plot("sum", pSumData, radiusNum); + // CvPlot::plot("count", pCountData, radiusNum); + // waitKey(); + } + + for (int i = 0; i < radiusNum; ++i) + { + //float radius = (i*radiusStep + radiusStep) / 2; + if (pWeightSumData[i] == 0) + { + + } + else + { + pSumData[i] /= pWeightSumData[i]; + } + } + + Mat retMat = Mat::zeros(img.rows, img.cols, img.type()); + for (int y = 0; y < h; y++) + { + float* pImgRowData = (float*)img.row(y).data; + float* pRetRowData = (float*)retMat.row(y).data; + float* pRadiusData = (float*)radiusMat.row(y).data; + for (int x = 0; x < w; x++) + { + float val = pImgRowData[x]; + float radius = pRadiusData[x]; + float mean = interpolate(pSumData, radiusNum, radiusStep, radius); + if (mean == 0) + { + continue; + } + float newVal = (float)val * dstMeanVal / mean; + pRetRowData[x] = newVal; + } + } + + return retMat; +} + +float CaliValve::interpolate(float* pY, int n, float stepX, float x) +{ + int lIdx = (int)(x / stepX); + int rIdx = lIdx + 1; + if (rIdx > n - 1) + { + return pY[n - 1]; + } + assert(lIdx >= 0 && lIdx < n && rIdx >= 0 && rIdx < n); + float s = (x - lIdx*stepX) / stepX; + float ly = pY[lIdx]; + float ry = pY[rIdx]; + return ly + (ry - ly)*s; +} + + +Mat CaliValve::extractForegroundWheel(const Mat &background, const Mat &src) +{ + Mat resizedGroundImage = background.clone(); + if (resizedGroundImage.size() != src.size()) + { + resize(background, resizedGroundImage, src.size()); + } + + return (src - resizedGroundImage); +} + +Mat CaliValve::findWheelObject(Mat src, Mat backGroundImg, int thresh) +{ + + + if (src.empty() || backGroundImg.empty() || src.cols < 500) + { + return Mat(); + } + assert(backGroundImg.type() == CV_8UC1); + const cv::Size size = cv::Size(416, floor(416.0 / src.cols * src.rows)); + Mat resizedImage; + resizedImage.setTo(0); + resize(src, resizedImage, size); + Mat foregroundImg = extractForegroundWheel(backGroundImg, resizedImage); + using namespace luffy_base; + Mat imgBinary; + imgBinary.setTo(0); + luffy_threshold::Threshold(foregroundImg, imgBinary, thresh);//0421 + //luffy_threshold::Threshold(imgTmp, imgBinary, nThres); + + Mat dilatedImgBin; + dilate(imgBinary, dilatedImgBin, Mat::ones(7, 7, CV_32FC1)); + erode(dilatedImgBin, imgBinary, Mat::ones(7, 7, CV_32FC1)); + //openOper(imgBinary, Mat::ones(1, 13, CV_32FC1)); + + vector> conts; + cv::findContours(imgBinary, conts, RETR_EXTERNAL, CHAIN_APPROX_NONE); + imgBinary.setTo(0); + for (int i = 0; i < conts.size(); i++) { + const vector &pt = conts.at(i); + if (pt.size() < 20) { + continue; + } + Rect rt = boundingRect(pt); + if (rt.width < 5 || rt.height < 5) { + continue; + } + drawContours(imgBinary, conts, i, Scalar::all(255), -1); + } + Mat hit; vector pts; + luffy_hit::firstHit4Circle(imgBinary, hit, pts, Point(size.width / 2, size.height / 2), 0, size.width / 2, 360, luffy_hit::emHitOut2In); + + //luffy_imageProc::RansacParam rs(0.02, 2.5, 70, 100, 220); + luffy_imageProc::RansacParam rs(0.01, 3, 150, 100, 240);//0421 + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); +#ifdef _DEBUG + Mat imgColor; + cv::cvtColor(resizedImage, imgColor, CV_GRAY2BGR); + for (int i = 0; i < pts.size(); i++) { + imgColor.at(pts.at(i))[0] = 255;//B + imgColor.at< cv::Vec3b >(pts.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts.at(i))[2] = 0;//R + } + for (int i = 0; i < pts2.size(); i++) { + imgColor.at(pts2.at(i))[0] = 0;//B + imgColor.at< cv::Vec3b >(pts2.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts2.at(i))[2] = 255;//R + } +#endif + + float fRadius; + Point2f ptCenter; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); + + if (!bFind) { + return Mat(); + } + Mat dst; + const int nOffset = 1; + fRadius += nOffset; + Rect rt(ptCenter.x - fRadius + nOffset, ptCenter.y - fRadius + nOffset, 2 * fRadius, 2 * fRadius); + rt &= Rect(0, 0, resizedImage.cols, resizedImage.rows); + resizedImage(rt).copyTo(dst); + Mat finalDst(dst.size(), dst.type(), Scalar::all(0)); + cv::circle(finalDst, Point(finalDst.cols / 2, finalDst.rows / 2), fRadius, Scalar::all(1), -1); + dst = dst.mul(finalDst); + return dst; +} + + + + +bool CaliValve::cutValve(Mat & img2Rect, Mat &imgTemplate, Rect rtCut, int nAngleMax) +{ + if (rtCut.x < 0) { + imgTemplate.create(Size(rtCut.width, rtCut.height), img2Rect.type()); + Rect rtLeft(nAngleMax + rtCut.x, rtCut.y, -rtCut.x, rtCut.height); + Rect rtRight(0, rtCut.y, rtCut.width - rtLeft.width, rtCut.height); + + img2Rect(rtLeft).copyTo(imgTemplate(Rect(0, 0, rtLeft.width, rtLeft.height))); + img2Rect(rtRight).copyTo(imgTemplate(Rect(rtLeft.width, 0, rtRight.width, rtLeft.height))); + return true; + } + else if (rtCut.x + rtCut.width >= nAngleMax) { + imgTemplate.create(Size(rtCut.width, rtCut.height), img2Rect.type()); + + Rect rtLeft(rtCut.x, rtCut.y, nAngleMax-rtCut.x, rtCut.height); + Rect rtRight(0, rtCut.y, rtCut.width - rtLeft.width, rtCut.height); + + img2Rect(rtLeft).copyTo(imgTemplate(Rect(0, 0, rtLeft.width, rtLeft.height))); + img2Rect(rtRight).copyTo(imgTemplate(Rect(rtLeft.width, 0, rtRight.width, rtLeft.height))); + return true; + } + + luffy_math::checkRoiRect(Size(img2Rect.cols, img2Rect.rows), rtCut); + img2Rect(rtCut).copyTo(imgTemplate); + + return true; +} +bool CaliValve::detect(Mat & imgSrc, InputParam ¶mIn, OutputParam ¶mOut, Mat &imgDst /*= Mat()*/) +{ + Record_List records = paramIn.roi.records; + Record_List barRecords = paramIn.barROI.records; + int nCircleCount = records.size(); + int barCircleCount = barRecords.size(); + if (nCircleCount == 0 && barCircleCount ==0) { + return false; + } + luffy_base::luffyCircle realCircle; + realCircle.ptCenter = Point2f(0, 0); + realCircle.fRadius = 10000000000000.0; + for (int i = 0; i < nCircleCount; i++) { + Item_List item = records.at(i); + Feature_List feature = item.at(0); + + if (1 == feature.first) { + int size = feature.second.size(); + if (size < 3) + { + continue; + } + Point2f p = Point2f(feature.second.at(0), feature.second.at(1)); + float r = abs(feature.second.at(2)); + if (r < realCircle.fRadius) + { + realCircle.fRadius = r; + realCircle.ptCenter = p; + } + continue; + } + } + + luffy_base::luffyCircle barCircle; + for (int i = 0; i < barCircleCount; i++) { + Item_List circleItem = barRecords.at(i); + Feature_List circleFeature = circleItem.at(0); + + if (1 == circleFeature.first) { + int size = circleFeature.second.size(); + if (size < 3) + { + continue; + } + barCircle.ptCenter = Point2f(circleFeature.second.at(0), circleFeature.second.at(1)); + barCircle.fRadius = abs(circleFeature.second.at(2)); + break; + } + } + + cv::circle(imgDst, realCircle.ptCenter, realCircle.fRadius, LP_COLOR_RED, 2); + cv::circle(imgDst, realCircle.ptCenter, 2, LP_COLOR_BLUE, 2); + cv::circle(imgDst, barCircle.ptCenter, barCircle.fRadius, LP_COLOR_RED, 2); + cv::circle(imgDst, barCircle.ptCenter, 2, LP_COLOR_BLUE, 2); + cv::circle(imgDst, paramIn.ptCenter, 2, LP_COLOR_RED, 2); + + float fRadius = luffy_math::disofPoints(realCircle.ptCenter, paramIn.ptCenter); + int offset = 30; + int nImgHeight = realCircle.fRadius * 2 + 2 * offset; + Mat img2Rect; + luffy_math::polar2rect(imgSrc, img2Rect, paramIn.ptCenter, + fRadius - nImgHeight / 2, fRadius + nImgHeight / 2, paramIn.nAngleMax); + + + if (paramIn.flagCircle > 0) + { + qWarning() << "outPut param flagCircle :" << paramIn.flagCircle; + paramOut.nValveOffset = luffy_math::caculAngle(paramIn.ptCenter, barCircle.ptCenter) / 360.0 * paramIn.nAngleMax; + Rect rTargetRoi(paramOut.nValveOffset - barCircle.fRadius, offset, 2 * barCircle.fRadius, 2 * realCircle.fRadius); + cutValve(img2Rect, paramOut.barTemplate, rTargetRoi, paramIn.nAngleMax); + paramOut.fValveWidth = realCircle.fRadius; + paramOut.fValveDis = fRadius; + paramOut.withinOffset = 0; + } + else + { + // -T && paramOut.nValveOffset - barCircleOffset < 0) || + (paramOut.nValveOffset - barCircleOffset >(paramIn.barNum - 1) * T) + ) + { + barCircleOffset = barCircleOffset - T; + } + + int interval = luffy_math::mod(paramOut.nValveOffset - barCircleOffset, paramIn.nAngleMax); + paramOut.withinOffset = interval; + paramOut.fValveWidth = realCircle.fRadius; + paramOut.fValveDis = fRadius; + } + + ///////for test + // + //Mat circleRoi; + //float startx = realCircle.ptCenter.x - realCircle.fRadius; + //float starty = realCircle.ptCenter.y - realCircle.fRadius; + //imgSrc(Rect(startx, starty, realCircle.fRadius * 2, realCircle.fRadius * 2)).copyTo(circleRoi); + //paramOut.imgTemplate = circleRoi; + if (paramIn.ifClasify) + { + Mat grayImage; + grayImage.setTo(0); + colorConvert(paramOut.background, grayImage); + Mat gray = imgSrc.clone(); + Mat foreGround = findWheelObject(gray, grayImage, paramIn.backgroundThresh); + if (foreGround.empty()) + { + return false; + } + int repeatNum = paramIn.barNum; + Mat weightMat(foreGround.size(), foreGround.type()); + selfRotateMin(foreGround, weightMat, repeatNum); + Mat mask = genMask(foreGround, Point(foreGround.cols / 2, foreGround.rows / 2), -1, -1, CV_32FC1); + weightMat.convertTo(weightMat, CV_32FC1); + weightMat = weightMat.mul(mask); + weightMat.setTo(0, weightMat < 20); + preProcessImage(foreGround, mask, 127.0, 20.0, 256); +#ifdef VIEW_INTERNAL_MAT + Mat m_weightMat = weightMat / 255.0; + Mat baseImage = foreGround / 255.0; +#endif + paramOut.baseImage = foreGround; + paramOut.weightMat = weightMat; + paramOut.background = grayImage; + } + else + { + paramOut.baseImage = Mat(); + paramOut.weightMat = Mat(); + } + + return true; +} + +void CaliValve::selfRotateMin(const Mat& src, Mat &dst, int repeatNum) +{ + Point2f center(src.cols / 2.0, src.rows / 2.0); + float angleStep = 360.0 / repeatNum; + Mat dstMat = Mat::ones(src.size(), src.type())*255; + for (int i = 0; i < repeatNum; ++i) + { + Mat rotateParamMat = getRotationMatrix2D(center, angleStep*i, 1.0); + Mat rImg; + warpAffine(src, rImg, rotateParamMat, src.size(), INTER_CUBIC, BORDER_CONSTANT); + Mat dialitedMat; + dilate(rImg, dialitedMat, Mat::ones(3, 3, CV_32FC1)); + dstMat = min(dstMat, dialitedMat); + } + dst = dstMat; +} + + +void CaliValve::colorConvert(const Mat& src, Mat & dst) +{ + if (src.channels() == 1) + { + dst = src.clone(); + } + else if (src.channels() == 3) + { + cvtColor(src, dst, CV_RGB2GRAY); + } + else if (src.channels() == 4) + { + cvtColor(src, dst, CV_RGBA2GRAY); + } +} \ No newline at end of file diff --git a/tpvs17/caliValve/caliValve.h b/tpvs17/caliValve/caliValve.h new file mode 100644 index 0000000..d327c75 --- /dev/null +++ b/tpvs17/caliValve/caliValve.h @@ -0,0 +1,58 @@ +#ifndef LP_VALVE_DETECTOR_H +#define LP_VALVE_DETECTOR_H +#include "Luffy.h" +#include "lpbengine.h" + +using namespace luffy_base; + +struct InputParam +{ + LP_DETECTOR_ROI_DATA roi; + LP_DETECTOR_ROI_DATA barROI; + int flagCircle; + + Point2f ptCenter; + int barNum; + const int nAngleMax = 3600; + int backgroundThresh; + int ifClasify; + int ibackground; +}; + +struct OutputParam +{ + float fValveDis; + float fValveWidth; + Mat imgTemplate; + int nValveOffset; + Mat barTemplate; + int withinOffset; + int barNum; + int flagCircle; + Mat baseImage; + Mat background; + Mat weightMat; +}; + +class CaliValve +{ +public: + CaliValve(); + ~CaliValve(); + + bool detect(Mat & imgSrc, InputParam ¶mIn, OutputParam ¶mOut, Mat &imgDst = Mat()); + bool cutValve(Mat & img2Rect, Mat &imgTemplate, Rect rtCut, int nAngleMax); + void preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold); + Mat genMask(const Mat& img, Point2f center, float innerR = -1, + float outterR = -1, + int type = CV_32FC1); + cv::Mat cocentricNorm(Mat& img, Point2f center, const Mat& weightMat, float dstMeanVal); + float interpolate(float* pY, int n, float stepX, float x); + Mat extractForegroundWheel(const Mat& background, const Mat& src); + Mat findWheelObject(Mat src, Mat backGroundImg, int thresh); + void selfRotateMin(const Mat& src, Mat &dst, int repeatNum); + Mat rotateImage(const Mat& img, Point2f center, float degree); + void colorConvert(const Mat& src, Mat & dst); +}; + +#endif //LP_VALVE_DETECTOR_H \ No newline at end of file diff --git a/tpvs17/caliValve/caliValve.vcxproj b/tpvs17/caliValve/caliValve.vcxproj new file mode 100644 index 0000000..7f945af --- /dev/null +++ b/tpvs17/caliValve/caliValve.vcxproj @@ -0,0 +1,106 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A} + Qt4VSv1.0 + caliValve + 10.0.16299.0 + + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + + + + + + + + + + + <_ProjectFileVersion>12.0.30501.0 + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(ProjectName) + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + _UNICODE;ALGO_LIB;QT_CORE_LIB;QT_GUI_LIB;UNICODE;WIN32;WIN64;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;.\..\..\3part\tadpole\include\tpBase;.\..\..\3part\opencv3.4.1\include;.\..\..\3part\opencv3.4.1\include\opencv;.\..\..\3part\opencv3.4.1\include\opencv2;.\..\..\..\Cyclops\include;.\..\..\3part\Cyclops\include;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(SolutionDir)..\runner17\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\3part\opencv3.4.1\x64\vc15\lib;..\..\3part\Cyclops\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Widgetsd.lib;Qt5Guid.lib;luffyd.lib;cyclopsd.lib;opencv_world341d.lib;%(AdditionalDependencies) + MachineX64 + /SUBSYSTEM:WINDOWS + + + + + _UNICODE;ALGO2_LIB;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_NO_DEBUG;UNICODE;WIN32;WIN64;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;.\..\..\3part\tadpole\include\tpBase;.\..\..\3part\opencv3.4.1\include;.\..\..\3part\opencv3.4.1\include\opencv;.\..\..\3part\opencv3.4.1\include\opencv2;.\..\..\..\Cyclops\include;.\..\..\3part\Cyclops\include;%(AdditionalIncludeDirectories) + + + MultiThreadedDLL + true + + + Windows + $(SolutionDir)..\runner17\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\3part\opencv3.4.1\x64\vc15\lib;..\..\3part\Cyclops\lib;%(AdditionalLibraryDirectories) + false + qtmain.lib;Qt5Core.lib;Qt5Widgets.lib;Qt5Gui.lib;luffy.lib;cyclops.lib;opencv_world341.lib;%(AdditionalDependencies) + MachineX64 + /SUBSYSTEM:WINDOWS + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/caliValve/caliValve.vcxproj.filters b/tpvs17/caliValve/caliValve.vcxproj.filters new file mode 100644 index 0000000..3d755cb --- /dev/null +++ b/tpvs17/caliValve/caliValve.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;cxx;c;def + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C} + ts + false + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Translation Files + + + \ No newline at end of file diff --git a/tpvs17/tpMain/lpMainWin.cpp b/tpvs17/tpMain/lpMainWin.cpp index 3c076db..a2d1320 100644 --- a/tpvs17/tpMain/lpMainWin.cpp +++ b/tpvs17/tpMain/lpMainWin.cpp @@ -62,6 +62,7 @@ lpMainWin::lpMainWin(QWidget *parent) connect(ui.action_connect_mode, SIGNAL(triggered()), this, SLOT(onActionClicked())); connect(ui.action_checkdata, SIGNAL(triggered()), this, SLOT(onActionClicked())); connect(ui.action_modelmgr, SIGNAL(triggered()), this, SLOT(onActionClicked())); + connect(ui.action_designer, SIGNAL(triggered()), this, SLOT(onActionClicked())); connect(ui.actionSystemSeting, SIGNAL(triggered()), this, SLOT(onActionClicked())); connect(ui.actioncamSetting, SIGNAL(triggered()), this, SLOT(onActionClicked())); @@ -168,49 +169,49 @@ lpMainWin::lpMainWin(QWidget *parent) m_screen.ShowMsg(tr("系统初始化完成...")); } - { - onSetModel(); - /*网络通信加载*/ - m_pNet = ((WheelCtrl*)m_pCtrl)->getNet(); - connect(m_pNet, SIGNAL(sgShow2UI(QString, bool)), this, SLOT(onTcpConnet(QString, bool)));//net - connect(m_pNet, SIGNAL(sgClientConnect(QString, bool)), this, SLOT(onClientConnect(QString, bool)));//net - //connect(m_pNet, SIGNAL(sgRecv(const QString &)), this, SLOT(onTcpRecv(const QString &)));// net显示 - connect(m_pNet, SIGNAL(sgThickness(double)), this, SLOT(onThickness(double)));//xy height - connect(m_pNet, SIGNAL(sgRecvDetectState(int, int)), this, SLOT(onDetectStateRecv(int, int)));//xy check - connect(m_pNet, SIGNAL(sgClearRev(bool)), this, SLOT(onClearLibRev(bool)));//xy clearlib - connect(m_pNet, SIGNAL(sgPulseRev()), this, SLOT(onPulseRev())); -// connect(m_pNet, SIGNAL(sgResultRev()), this, SLOT(onResultRev())); - connect(m_pNet, SIGNAL(sgRecvTrigPara()), this, SLOT(onRecvTrigPara())); - connect(m_pNet, SIGNAL(sgReadDetectState(int, QString)), this, SLOT(onReadDetectState(int, QString))); - connect(m_pNet, SIGNAL(sgReadDetectStateASK()), this, SLOT(onReadDetectStateASK())); - connect(m_pNet, SIGNAL(sgCameraTrig(int)), this, SLOT(onTrigRecv(int))); - connect(m_pNet, SIGNAL(sgServerState(QString, int, bool)), this, SLOT(onServerState(QString, int, bool))); - connect(m_pNet, SIGNAL(sgShutDownComputer()), this, SLOT(onShutDownComputer())); - connect(m_pNet, SIGNAL(sgLibRev(bool)), SendModelLibTask, SLOT(WaitSingleIn(bool)));//xy lib - -// connect(m_pNet, SIGNAL(sgChangeOnlineState(int)), m_pUi, SLOT(onSwitchOnlineModel(int)));//强制在线 离线 - - QTimer::singleShot(500, m_pNet, SLOT(onOpenServer()));//延迟2s打开网络TCP服务 - } - { - connect(&m_PulseTimer, SIGNAL(timeout()), this, SLOT(onPulseTimer()));//心跳包 - connect(&m_wfPulseTimer, SIGNAL(timeout()), this, SLOT(onwfPulseTimer()));//心跳包 - connect(&m_ThicknessTimer, SIGNAL(timeout()), this, SLOT(onThicknessTimer()));// 厚度查询 - connect(&m_ReadLibTimer, SIGNAL(timeout()), this, SLOT(onSendReadOnlineLib())); - - connect(this, SIGNAL(sgTickTsk()), this, SLOT(onPulseTimer())); - connect(this, SIGNAL(sgShowMsg(QString, bool)), this, SLOT(onTcpConnet(QString, bool))); - connect(this, SIGNAL(sgTaskSendModels(int, QString, double, double)), this, SLOT(onTaskSendModels(int, QString, double, double)));//用于发送莫板库 - connect(this, SIGNAL(sgTskSendDetectState(int, QString, int)), this, SLOT(onTaskSendDetectState(int, QString, int)));//离线检测发送 用于发送检测状态 - connect(this, SIGNAL(sgTskSendCheck(int, int, QString)), this, SLOT(onTaskCheck(int, int, QString)));//在线检测状态查询 用于查询线程 -// connect(this, SIGNAL(sgCheckEnd()), this, SLOT(onCheckEnd())); - connect(this, SIGNAL(sgShowImgState(QString)), this, SLOT(onShowImgState(QString))); - connect(this, SIGNAL(sgGetImg()), this, SLOT(onGetImg())); - connect(this, SIGNAL(sgShowMsgdlg(QString)), this, SLOT(onShowMsg(QString))); - connect(this, SIGNAL(sgSendDisLib(int, QString)), this, SLOT(onSendDisLib(int, QString))); - connect(this, SIGNAL(sgSendDisLibDone()), this, SLOT(onSendDisLibDone())); - connect(this, SIGNAL(sgShowChannelRes(QString)), this, SLOT(onShowChannel(QString))); - } +// { +// onSetModel(); +// /*网络通信加载*/ +// m_pNet = ((WheelCtrl*)m_pCtrl)->getNet(); +// connect(m_pNet, SIGNAL(sgShow2UI(QString, bool)), this, SLOT(onTcpConnet(QString, bool)));//net +// connect(m_pNet, SIGNAL(sgClientConnect(QString, bool)), this, SLOT(onClientConnect(QString, bool)));//net +// //connect(m_pNet, SIGNAL(sgRecv(const QString &)), this, SLOT(onTcpRecv(const QString &)));// net显示 +// connect(m_pNet, SIGNAL(sgThickness(double)), this, SLOT(onThickness(double)));//xy height +// connect(m_pNet, SIGNAL(sgRecvDetectState(int, int)), this, SLOT(onDetectStateRecv(int, int)));//xy check +// connect(m_pNet, SIGNAL(sgClearRev(bool)), this, SLOT(onClearLibRev(bool)));//xy clearlib +// connect(m_pNet, SIGNAL(sgPulseRev()), this, SLOT(onPulseRev())); +// // connect(m_pNet, SIGNAL(sgResultRev()), this, SLOT(onResultRev())); +// connect(m_pNet, SIGNAL(sgRecvTrigPara()), this, SLOT(onRecvTrigPara())); +// connect(m_pNet, SIGNAL(sgReadDetectState(int, QString)), this, SLOT(onReadDetectState(int, QString))); +// connect(m_pNet, SIGNAL(sgReadDetectStateASK()), this, SLOT(onReadDetectStateASK())); +// connect(m_pNet, SIGNAL(sgCameraTrig(int)), this, SLOT(onTrigRecv(int))); +// connect(m_pNet, SIGNAL(sgServerState(QString, int, bool)), this, SLOT(onServerState(QString, int, bool))); +// connect(m_pNet, SIGNAL(sgShutDownComputer()), this, SLOT(onShutDownComputer())); +// connect(m_pNet, SIGNAL(sgLibRev(bool)), SendModelLibTask, SLOT(WaitSingleIn(bool)));//xy lib +// +// // connect(m_pNet, SIGNAL(sgChangeOnlineState(int)), m_pUi, SLOT(onSwitchOnlineModel(int)));//强制在线 离线 +// +// QTimer::singleShot(500, m_pNet, SLOT(onOpenServer()));//延迟2s打开网络TCP服务 +// } +// { +// connect(&m_PulseTimer, SIGNAL(timeout()), this, SLOT(onPulseTimer()));//心跳包 +// connect(&m_wfPulseTimer, SIGNAL(timeout()), this, SLOT(onwfPulseTimer()));//心跳包 +// connect(&m_ThicknessTimer, SIGNAL(timeout()), this, SLOT(onThicknessTimer()));// 厚度查询 +// connect(&m_ReadLibTimer, SIGNAL(timeout()), this, SLOT(onSendReadOnlineLib())); +// +// connect(this, SIGNAL(sgTickTsk()), this, SLOT(onPulseTimer())); +// connect(this, SIGNAL(sgShowMsg(QString, bool)), this, SLOT(onTcpConnet(QString, bool))); +// connect(this, SIGNAL(sgTaskSendModels(int, QString, double, double)), this, SLOT(onTaskSendModels(int, QString, double, double)));//用于发送莫板库 +// connect(this, SIGNAL(sgTskSendDetectState(int, QString, int)), this, SLOT(onTaskSendDetectState(int, QString, int)));//离线检测发送 用于发送检测状态 +// connect(this, SIGNAL(sgTskSendCheck(int, int, QString)), this, SLOT(onTaskCheck(int, int, QString)));//在线检测状态查询 用于查询线程 +// // connect(this, SIGNAL(sgCheckEnd()), this, SLOT(onCheckEnd())); +// connect(this, SIGNAL(sgShowImgState(QString)), this, SLOT(onShowImgState(QString))); +// connect(this, SIGNAL(sgGetImg()), this, SLOT(onGetImg())); +// connect(this, SIGNAL(sgShowMsgdlg(QString)), this, SLOT(onShowMsg(QString))); +// connect(this, SIGNAL(sgSendDisLib(int, QString)), this, SLOT(onSendDisLib(int, QString))); +// connect(this, SIGNAL(sgSendDisLibDone()), this, SLOT(onSendDisLibDone())); +// connect(this, SIGNAL(sgShowChannelRes(QString)), this, SLOT(onShowChannel(QString))); +// } { /*启动之后就一直发送心跳包和厚度查询*/ if (DetectState::instance()->m_AutoSendTick2Net) @@ -422,7 +423,6 @@ bool lpMainWin::onInitEngineCtrl() m_pEngineCtrl = m_pDllEngineCtrl->m_pDE; } - } if (m_pDllDesigner == nullptr) @@ -905,6 +905,11 @@ Q_SLOT void lpMainWin::onActionClicked() m_CamSettingDlg->show(); } } + else if ("action_designer" == strObj) { + if (m_pDesigner) { + m_pDesigner->ShowMainFrame(); + } + } } Q_SLOT void lpMainWin::onButtonClicked() diff --git a/tpvs17/tpMain/lpMainWin.ui b/tpvs17/tpMain/lpMainWin.ui index 68c0ca2..d768a4e 100644 --- a/tpvs17/tpMain/lpMainWin.ui +++ b/tpvs17/tpMain/lpMainWin.ui @@ -860,7 +860,7 @@ background-color: rgb(170, 170, 127); - + @@ -1032,7 +1032,11 @@ background-color: rgb(170, 170, 127); - + + + + :/ToolBarPic/ToolBarpic/app8.png:/ToolBarPic/ToolBarpic/app8.png + 设计 diff --git a/tpvs17/valveDetector/BatchTest4Alg.cpp b/tpvs17/valveDetector/BatchTest4Alg.cpp new file mode 100644 index 0000000..1495ff9 --- /dev/null +++ b/tpvs17/valveDetector/BatchTest4Alg.cpp @@ -0,0 +1,104 @@ +#include "BatchTest4Alg.h" +#include "cv.h" +#include "highgui.h" +#include "Luffy.h" +#include "qstringlist.h" +#include "qfile.h" +#include "qdatetime.h" + +using namespace cv; + +struct Region { + cv::Scalar color; + int id; + std::vector points; + void write(cv::FileStorage& fs) const { + fs << "{" << "id" << id << "points" << points << "}"; + } + void read(const cv::FileNode& node) { + //node["color"] >> color; + node["id"] >> id; + node["points"] >> points; + } +}; + +inline std::vector> read_points_info(std::string path) { + cv::FileStorage fs; + fs.open(path, cv::FileStorage::READ); + int count{ -1 }; + int id{ -1 }; + std::vector>> regions{}; + std::vector> defect_regions{ std::vector < cv::Point > {} }; + cv::FileNode node = fs.getFirstTopLevelNode(); + std::vector> dst; + while (1) { + Region re_load; + re_load.read(fs["region" + std::to_string(++count)]); + //fs["region" + std::to_string(++count)] >> re_load; + auto region = re_load.points; + if (region.empty()) { + if (!defect_regions.empty())regions.push_back(defect_regions); + fs.release(); + break; + } + if (id != re_load.id) { + if (id != -1)regions.push_back(defect_regions); + while (re_load.id > int(regions.size())) { + regions.push_back(std::vector < std::vector > {std::vector < cv::Point > {}}); + } + id = re_load.id; + + defect_regions.clear(); + } + dst.push_back(re_load.points); + //defect_regions.push_back(region); + } + return dst; +} + +BatchTest4Alg::BatchTest4Alg() +{ +} + + +BatchTest4Alg::~BatchTest4Alg() +{ +} + +bool BatchTest4Alg::batchTest(QString strModel, Point pt, int nError, QString strBase, QString strFile) +{ + QString m = strModel.split("##").last(); + QString str = strFile.replace(m, m + "-out"); + str = str.left(str.length() - 3) + "xml"; + Point ptCali = getCaliPosition(str); + double dis = luffy_base::luffy_math::disofPoints(ptCali, pt); + dis = sqrt(dis); + return dis < 10; +} + +cv::Point BatchTest4Alg::getCaliPosition(QString strFile) +{ + std::string str = strFile.toLocal8Bit().data(); + FileStorage fs(strFile.toLocal8Bit().data(), FileStorage::READ); + if (!fs.isOpened()) { + return Point(); + } + vector> pts = read_points_info(strFile.toLocal8Bit().data()); + if (pts.size() == 0) { + return Point(); + } + Rect rt = cv::boundingRect(pts[0]); + return Point(rt.x + rt.width / 2, rt.y + rt.height / 2); +} + +bool BatchTest4Alg::saveResult(QString strModel, int nError, QString modelFile, QString saveFile) +{ + QFile qFile(saveFile); + qFile.open(QIODevice::Append | QIODevice::WriteOnly); + QString str = "time:%1, model:%2, result:%3, file:%4\r\n"; + str = str.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss zzz")).arg(strModel).arg(nError).arg(modelFile); + qFile.write(str.toLocal8Bit().data()); + qFile.close(); + + return true; +} diff --git a/tpvs17/valveDetector/BatchTest4Alg.h b/tpvs17/valveDetector/BatchTest4Alg.h new file mode 100644 index 0000000..e231def --- /dev/null +++ b/tpvs17/valveDetector/BatchTest4Alg.h @@ -0,0 +1,14 @@ +#pragma once +#include "qstring.h" +#include "core\core.hpp" +class BatchTest4Alg +{ +public: + BatchTest4Alg(); + ~BatchTest4Alg(); + + static bool batchTest(QString strModel, cv::Point pt, int nError, QString strBase, QString strFile); + static cv::Point getCaliPosition(QString strFile); + static bool saveResult(QString strModel, int nError, QString modelFile, QString saveFile); +}; + diff --git a/tpvs17/valveDetector/algEg.cpp b/tpvs17/valveDetector/algEg.cpp new file mode 100644 index 0000000..0979034 --- /dev/null +++ b/tpvs17/valveDetector/algEg.cpp @@ -0,0 +1,307 @@ +#include "algEg.h" +#include "ValveDetector.h" +#include "qmap.h" +#include "qtcvutils.h" +#include "BatchTest4Alg.h" +#include "modelVerfication.h" +#pragma execution_character_set("utf-8") +using namespace luffy_base; +static QMap listModes; +algEg::algEg() +{ + luffy_triangle::createNewTrigValue(360); + luffy_triangle::createNewTrigValue(3600); + +} + +algEg::~algEg() +{ + +} +const int nAngleMax = 3600; + +bool algEg::Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm) +{ + //GetParamValue("scoreTh", LP_DOUBLE).toDouble(); + paramInput.nBarScore = lpAlgorithm->GetParamValue("barScore", LP_INT).toDouble(); + paramInput.nBarScore = paramInput.nBarScore > 50 ? paramInput.nBarScore : 50; + paramInput.withinOffset = lpAlgorithm->GetParamValue("withinOffset", LP_INT).toInt(); + paramInput.barNum = lpAlgorithm->GetParamValue("barNum", LP_INT).toInt(); + paramOutput.bIsFind = false; + paramOutput.dScore = 0; + paramOutput.showMatchScore = -1; + paramInput.nMaxAngle = nAngleMax; + paramOutput.dAngle = 361; + paramOutput.nErrorType = 0; + paramInput.flagCircle = lpAlgorithm->GetParamValue("flagCircle", LP_INT).toInt(); + paramInput.roi = lpAlgorithm->GetParamValue("cirlceArea", LP_ROI).value(); + paramInput.cMatchScore = lpAlgorithm->GetParamValue("cMatchScore", LP_DOUBLE).toDouble(); + paramInput.wheelType = lpAlgorithm->GetParamValue("wheelType", LP_INT).toInt(); + paramInput.backgroundThresh = lpAlgorithm->GetParamValue("backgroundThresh", LP_INT).toInt(); + Mat mask; Mat gray; + if (!lpTask->GetTaskInfo()->detectImg.empty()) { + luffy_imageProc::createImage(lpTask->GetTaskInfo()->detectImg, gray, luffy_imageProc::emCreateGray); + qDebug() << "luffy_imageProc::createImage"; + } + if (gray.empty()) { + paramOutput.nErrorType += 1; + qWarning() << "valve detect, gray is empty"; + return false; + } +// if (gray.size() != paramInput.roi.img.size()) +// { +// qWarning() << "img size not compare"; +// return false; +// } + luffy_imageProc::createImage(gray, mask, luffy_imageProc::emCreateColor); + QString strObj = paramInput.strObj = lpTask->GetTaskInfo()->strName; + bool bExist = true; + if (strObj.isEmpty()) { + bExist = false; + paramOutput.nErrorType += 2; + } + + Mat centerRoi = lpAlgorithm->GetParamValue("centerRoi", LP_MAT).value(); + + if (!centerRoi.empty()) { + qDebug() << "valve detection: creating CenterRoi"; + luffy_imageProc::createImage(centerRoi, paramInput.centerRoi, luffy_imageProc::emCreateGray); + } + else { + qWarning() << "valve detection: fail to get CenterRoi"; + bExist = false; + } + + //保护 防止越界 + QPointF pt = lpAlgorithm->GetParamValue("center", LP_POINTF).toPointF(); + if (pt.x() > gray.size().width||pt.y()>gray.size().height) + { + qWarning() << "center point big "; + return false; + } + + // add original center + paramInput.originalPoint = Point2f(pt.x(), pt.y()); + paramInput.nCenterAlg = lpAlgorithm->GetParamValue("centerAlg", LP_INT).toInt(); + // add background + paramInput.backGround = lpAlgorithm->GetParamValue("background", LP_MAT).value(); + luffy_imageProc::createImage(paramInput.backGround, paramInput.backGround, luffy_imageProc::emCreateGray); + + Mat rstMat; + if (bExist) + { + qDebug() << "valve detection: found CenterRoi, trying to get the center points"; + paramInput.ptCenter = m_objDetect.getCenterPoints(gray, centerRoi, paramInput, Point(pt.x(), pt.y()), rstMat); + } + + if (paramInput.ptCenter.x == 0) { + bExist = false; + qWarning() << "valve detection: center point is null, background is empty"; + } + else + { + float dis = luffy_math::disofPoints(paramInput.originalPoint, paramInput.ptCenter); + if (dis > 25) + { + bExist = false; + paramOutput.nErrorType += 8; + paramOutput.flag = 1; + } + } + paramInput.nValveOffset = lpAlgorithm->GetParamValue("valveOffset", LP_INT).toInt(); + paramInput.fValveWidth = lpAlgorithm->GetParamValue("valveWidth", LP_DOUBLE).toDouble(); + paramInput.fValveDis = lpAlgorithm->GetParamValue("valveDis", LP_DOUBLE).toDouble(); + Mat tmp = lpAlgorithm->GetParamValue("valveTemplate", LP_MAT).value(); + Mat barTemp = lpAlgorithm->GetParamValue("barTemplate", LP_MAT).value(); +/////// + Mat weightMat = lpAlgorithm->GetParamValue("weightMat", LP_MAT).value(); + Mat baseImage = lpAlgorithm->GetParamValue("baseImage", LP_MAT).value(); + int num = lpTask->GetSystemInfoValue("station").toInt(); + if (num == 2) + { + if (!baseImage.empty() && !weightMat.empty()) + { + if (baseImage.size() != weightMat.size()) + { + paramOutput.showMatchScore = 366; + paramOutput.nErrorType += 16; + bExist = false; + } + else + { + modelVerfication verObj(20, 127); + verObj.setWeightMat(weightMat); + bool ok = verObj.objectVerification(rstMat, baseImage, paramInput.cMatchScore, 360, paramOutput.showMatchScore); + if (!ok) + { + paramOutput.nErrorType += 16; + bExist = false; + } + } + + } + } + + if (!tmp.empty() && !barTemp.empty()) { + luffy_imageProc::createImage(tmp, paramInput.imgTemplate, luffy_imageProc::emCreateGray); + luffy_imageProc::createImage(barTemp, paramInput.barTemplate, luffy_imageProc::emCreateGray); + } + else { + if (!barTemp.empty() && paramInput.flagCircle == 1) + { + luffy_imageProc::createImage(barTemp, paramInput.barTemplate, luffy_imageProc::emCreateGray); + } + else + { + qWarning() << "valve detection: can not get template for detecting"; + bExist = false; + } + + } + + if (bExist) { + qDebug() << "valve detection: try finding"; + m_objDetect.detect(gray, paramInput, paramOutput, mask); + } + else { + qWarning() << "valve detection: some param is missing"; + } + if (lpTask->GetSystemInfoValue("wf_batch_test").toBool()) { + int nAngle = paramOutput.dAngle; + nAngle = nAngle >= paramInput.nMaxAngle ? 0 : nAngle; + + int tmpX = paramInput.ptCenter.x + paramInput.fValveDis * luffy_base::luffy_triangle::getCos(paramInput.nMaxAngle, nAngle); + int tmpY = paramInput.ptCenter.y - paramInput.fValveDis * luffy_base::luffy_triangle::getSin(paramInput.nMaxAngle, nAngle); + + + Point ptValve(tmpX, tmpY); + QString strBase = lpTask->GetSystemInfoValue("folderBase").toString(); + QString strFile = lpTask->GetSystemInfoValue("fileName").toString(); + bool b = BatchTest4Alg::batchTest(strObj, ptValve, paramOutput.nErrorType, strBase, lpTask->GetTaskInfo()->strImageName); + BatchTest4Alg::saveResult(strObj, b, lpTask->GetTaskInfo()->strImageName, strBase + "\\" + strFile); + } + QVariantMap vMap = lpTask->GetTaskInfo()->property.toMap(); + vMap.insert("model_cali", true); + lpTask->GetTaskInfo()->property = vMap; + + paramOutput.dAngleRes = (paramOutput.dAngle - paramInput.nValveOffset) / paramInput.nMaxAngle * 360.0; + paramOutput.dAngleRes = m_objDetect.ruleData(paramOutput.dAngleRes, paramOutput.nErrorType); + paramOutput.strResultTip = m_objDetect.genResultTip(paramOutput.strResultTip, paramOutput.nErrorType); + + paramOutput.dTime = (double)(cv::getTickCount() - nStart) / cv::getTickFrequency() * 1000.0; + m_objDetect.drawResult(mask, paramInput, paramOutput); + m_objDetect.saveResult(gray, paramInput, paramOutput, strObj); + lpAlgorithm->SetOutParamValue("image", EngineBase::convMat2QImage(mask)); + lpAlgorithm->SetOutParamValue("score", paramOutput.dScore); + lpAlgorithm->SetOutParamValue("angle", paramOutput.dAngleRes); + lpAlgorithm->SetOutParamValue("error", paramOutput.nErrorType); + + QString cLetter = paramOutput.strResultTip + "/" + QString::number(paramInput.dScoreThres); + lpAlgorithm->SetOutParamValue("resultTip", cLetter); + //lpAlgorithm->SetOutParamValue("resultTip", paramOutput.strResultTip); + QString strImgName = lpTask->GetTaskInfo()->strImageName; + lpAlgorithm->SetOutParamValue("imageName", lpTask->GetTaskInfo()->strImageName); + qDebug() << "finish alg valve detect"; + return true; +} + +bool algEg::Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm) +{ + + LP_ALGORITHM_PARAM param1_1("backgroundThresh", LP_INT, 15, QObject::tr("背景差异性阈值")); + lpAlgorithm->AddParam(¶m1_1, 1); + + LP_ALGORITHM_PARAM param1("scoreTh", LP_DOUBLE, 90, QObject::tr("相似度评价阈值,在0~100之间")); + lpAlgorithm->AddParam(¶m1, 1); + + LP_ALGORITHM_PARAM param2_1("wheelType", LP_INT, 0, QObject::tr("轮毂类型,0摩伦,1汽轮")); + lpAlgorithm->AddParam(¶m2_1, 1); + + LP_ALGORITHM_PARAM param3("flagCircle", LP_INT, 0, QObject::tr("0:无气门芯标识,绑定气门芯标定")); + lpAlgorithm->AddParam(¶m3, 1); + + LP_ALGORITHM_PARAM param3_1("centerAlg", LP_INT, 0, QObject::tr("是否开启中心定位,0关闭,1开启")); + lpAlgorithm->AddParam(¶m3_1, 1); + + LP_ALGORITHM_PARAM param3_2("center", LP_POINTF, QVariant(), QObject::tr("轮毂中心坐标,绑定气门芯标定")); + lpAlgorithm->AddParam(¶m3_2, 1); + + LP_ALGORITHM_PARAM param3_3("centerRoi", LP_MAT, QVariant(), QObject::tr("轮毂中心模板, 绑定圆定位")); + lpAlgorithm->AddParam(¶m3_3, 1); + + LP_ALGORITHM_PARAM param3_6("cirlceArea", LP_ROI, QVariant(), QObject::tr("轮毂区域框选")); + lpAlgorithm->AddParam(¶m3_6, 1); + + LP_ALGORITHM_PARAM param3_7("cMatchScore", LP_DOUBLE, 0.2000, QObject::tr("轮毂型号匹配分值")); + lpAlgorithm->AddParam(¶m3_7, 1); + + LP_ALGORITHM_PARAM param3_9("barScore", LP_INT, 0, QObject::tr("辐条得分值")); + lpAlgorithm->AddParam(¶m3_9, 1); + + LP_ALGORITHM_PARAM param13_1("withinOffset", LP_INT, 0, QObject::tr(" ")); + lpAlgorithm->AddParam(¶m13_1, 1); + + LP_ALGORITHM_PARAM param13_2("barNum", LP_INT, 0, QObject::tr(" ")); + lpAlgorithm->AddParam(¶m13_2, 1); + + LP_ALGORITHM_PARAM param13("valveOffset", LP_INT, 0, QObject::tr(" ")); + lpAlgorithm->AddParam(¶m13, 1); + + LP_ALGORITHM_PARAM param23("valveWidth", LP_DOUBLE, 0, QObject::tr(" ")); + lpAlgorithm->AddParam(¶m23, 1); + + LP_ALGORITHM_PARAM param33("valveDis", LP_DOUBLE, 0, QObject::tr(" ")); + lpAlgorithm->AddParam(¶m33, 1); + + LP_ALGORITHM_PARAM param43("valveTemplate", LP_MAT, QVariant(), QObject::tr(" ")); + lpAlgorithm->AddParam(¶m43, 1); + + LP_ALGORITHM_PARAM param44("barTemplate", LP_MAT, QVariant(), QObject::tr(" ")); + lpAlgorithm->AddParam(¶m44, 1); + + LP_ALGORITHM_PARAM param45("weightMat", LP_MAT, QVariant(), QObject::tr(" ")); + lpAlgorithm->AddParam(¶m45, 1); + + LP_ALGORITHM_PARAM param46("baseImage", LP_MAT, QVariant(), QObject::tr(" ")); + lpAlgorithm->AddParam(¶m46, 1); + + LP_ALGORITHM_PARAM param4_1("background", LP_MAT, QVariant(), QObject::tr(" ")); + lpAlgorithm->AddParam(¶m4_1, 1); + + LP_ALGORITHM_PARAM param6("image", LP_IMAGE); + lpAlgorithm->AddOutParam(¶m6, 1); + + LP_ALGORITHM_PARAM param7("score", LP_DOUBLE, 0, QObject::tr("相似度得分")); + lpAlgorithm->AddOutParam(¶m7, 1); + + LP_ALGORITHM_PARAM param8("angle", LP_DOUBLE, 0, QObject::tr("结果角度")); + lpAlgorithm->AddOutParam(¶m8, 1); + + LP_ALGORITHM_PARAM param9("error", LP_INT, 0, QObject::tr("错误类型")); + lpAlgorithm->AddOutParam(¶m9, 1); + + LP_ALGORITHM_PARAM param10("resultTip", LP_STRING, 0, QObject::tr("结果提示")); + lpAlgorithm->AddOutParam(¶m10, 1); + + QString AlgoName = QObject::tr("检测"); + QString AlgoName2 = QObject::tr("圆心定位"); + QString AlgoName3 = QObject::tr("气门芯标定"); + return true; +} + + + +void LpAlgoNewInstance(IAlgo** lppAlgo) +{ + *lppAlgo = (IAlgo*)new algEg(); +} + +bool LpAlgoDeleteInstance() +{ + return true; +} \ No newline at end of file diff --git a/tpvs17/valveDetector/algEg.h b/tpvs17/valveDetector/algEg.h new file mode 100644 index 0000000..f94fe87 --- /dev/null +++ b/tpvs17/valveDetector/algEg.h @@ -0,0 +1,23 @@ +#ifndef _ALG_EG_H_ +#define _ALG_EG_H_ + +#include ".\lpbengine.h" +#include ".\lpalgorithm.h" + + + + +class algEg : IAlgo +{ +public: + algEg(); + ~algEg(); + virtual bool Exec(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm); + virtual bool Init(IDetectorTask *lpTask, IDetectorAlgorithm* lpAlgorithm); + cv::Mat background; +private: + +}; + + +#endif // _ALG_EG_H_ diff --git a/tpvs17/valveDetector/algEg_global.h b/tpvs17/valveDetector/algEg_global.h new file mode 100644 index 0000000..0eb7f01 --- /dev/null +++ b/tpvs17/valveDetector/algEg_global.h @@ -0,0 +1,12 @@ +#ifndef _ALG_EG_GLOBAL_H_ +#define _ALG_EG_GLOBAL_H_ + +#include + +#ifdef ALG_EG_LIB +# define ALG_EG_EXPORT Q_DECL_EXPORT +#else +# define ALG_EG_EXPORT Q_DECL_IMPORT +#endif + +#endif // _ALG_EG_GLOBAL_H_ diff --git a/tpvs17/valveDetector/modelVerfication.cpp b/tpvs17/valveDetector/modelVerfication.cpp new file mode 100644 index 0000000..dc0e3c1 --- /dev/null +++ b/tpvs17/valveDetector/modelVerfication.cpp @@ -0,0 +1,407 @@ +#include "modelVerfication.h" + +//#define VIEW_DEBUG_IMG +modelVerfication::modelVerfication(double tarStddevVal, double tarMeanVal) : + tarStddev(tarStddevVal) + , tarMean(tarMeanVal) +{ + +} + +modelVerfication::~modelVerfication() +{ + +} + +double disOfPoint(const Point2f& p1, const Point2f& p2) +{ + return norm(p1 - p2); +} + +float modelVerfication::interpolate(float* pY, int n, float stepX, float x) +{ + int lIdx = (int)(x / stepX); + int rIdx = lIdx + 1; + if (rIdx > n - 1) + { + return pY[n - 1]; + } + assert(lIdx >= 0 && lIdx < n && rIdx >= 0 && rIdx < n); + float s = (x - lIdx*stepX) / stepX; + float ly = pY[lIdx]; + float ry = pY[rIdx]; + return ly + (ry - ly)*s; +} +bool modelVerfication::objectVerification(const Mat &img, Mat& baseImage, double modelValidThresh, int endAngle, double & s) +{ + int diff = abs(img.cols - baseImage.cols); + if (diff >=5) + { + qDebug() << "model verification : model possibly is not match"; + s = 365; + return false; + } + if (baseImage.type()!=CV_32FC1) + { + baseImage.convertTo(baseImage, CV_32FC1); + } + Mat resizedImage(baseImage.size(), baseImage.type(), Scalar::all(0)); + if (img.size()!= baseImage.size()) + { + resize(img, resizedImage, baseImage.size()); + } + else + { + resizedImage = img; + } + + Mat mask = genMask(resizedImage, Point(resizedImage.cols / 2, resizedImage.rows / 2), -1, -1, CV_8UC1); + m32fMaskImg = genMask(resizedImage, Point2f(resizedImage.cols / 2, resizedImage.rows / 2)); + preProcessImage(resizedImage, mask, tarMean, tarStddev, 256); + RData* pData = new RData(); + rotateMatchData(resizedImage, baseImage, pData, 1, 0, endAngle); + + double result = 0; + Mat rstImg, showImage, Ibase; + + if (pData->mDisValVec.empty()) + { + delete pData; + qDebug() << "model verification : the distance of model is empty"; + result = FLT_MAX; + } + else + { + size_t bestIndex = min_element(pData->mDisValVec.begin(), pData->mDisValVec.end()) - pData->mDisValVec.begin(); + + result = pData->mDisValVec[bestIndex]; + rstImg = pData->mRImgVec[bestIndex]; +#ifdef VIEW_DEBUG_IMG + showImage = rstImg / 255; + Ibase = baseImage / 255; +#endif // VIEW_DEBUG_IMG + qDebug() << "model verification : found the minimal value model:" << result; + delete pData; + } + + if (result < modelValidThresh) + { + qDebug() << "model verification : image is valid"; + s = result; + return true; + } + else + { + qDebug() << "model verification : image is not valid"; + s = result; + return false; + } + + + //Mat image = croppedImage / 255.0; +} +Mat modelVerfication::extractForegroundWheel(const Mat &background, const Mat &src) +{ + Mat resizedGroundImage = background.clone(); + if (resizedGroundImage.size() != src.size()) + { + resize(background, resizedGroundImage, src.size()); + } + + return (src - resizedGroundImage); +} + +Mat modelVerfication::findWheelObject(Mat src, Mat backGroundImg, int thresh) +{ + + + if (src.empty() || backGroundImg.empty() || src.cols < 500) + { + return Mat(); + } + assert(backGroundImg.type() == CV_8UC1); + const cv::Size size = cv::Size(416, floor(416.0 / src.cols * src.rows)); + Mat resizedImage; + resizedImage.setTo(0); + resize(src, resizedImage, size); + Mat foregroundImg = extractForegroundWheel(backGroundImg, resizedImage); + using namespace luffy_base; + Mat imgBinary; + imgBinary.setTo(0); + luffy_threshold::Threshold(foregroundImg, imgBinary, thresh);//0421 + //luffy_threshold::Threshold(imgTmp, imgBinary, nThres); + + Mat dilatedImgBin; + dilate(imgBinary, dilatedImgBin, Mat::ones(7, 7, CV_32FC1)); + erode(dilatedImgBin, imgBinary, Mat::ones(7, 7, CV_32FC1)); + //openOper(imgBinary, Mat::ones(1, 13, CV_32FC1)); + + vector> conts; + cv::findContours(imgBinary, conts, RETR_EXTERNAL, CHAIN_APPROX_NONE); + imgBinary.setTo(0); + for (int i = 0; i < conts.size(); i++) { + const vector &pt = conts.at(i); + if (pt.size() < 20) { + continue; + } + Rect rt = boundingRect(pt); + if (rt.width < 5 || rt.height < 5) { + continue; + } + drawContours(imgBinary, conts, i, Scalar::all(255), -1); + } + Mat hit; vector pts; + luffy_hit::firstHit4Circle(imgBinary, hit, pts, Point(size.width / 2, size.height / 2), 0, size.width / 2, 360, luffy_hit::emHitOut2In); + + //luffy_imageProc::RansacParam rs(0.02, 2.5, 70, 100, 220); + luffy_imageProc::RansacParam rs(0.01, 3, 150, 100, 240);//0421 + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); +#ifdef _DEBUG + Mat imgColor; + cv::cvtColor(resizedImage, imgColor, CV_GRAY2BGR); + for (int i = 0; i < pts.size(); i++) { + imgColor.at(pts.at(i))[0] = 255;//B + imgColor.at< cv::Vec3b >(pts.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts.at(i))[2] = 0;//R + } + for (int i = 0; i < pts2.size(); i++) { + imgColor.at(pts2.at(i))[0] = 0;//B + imgColor.at< cv::Vec3b >(pts2.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts2.at(i))[2] = 255;//R + } +#endif + + float fRadius; + Point2f ptCenter; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); + + if (!bFind) { + return Mat(); + } + Mat dst; + const int nOffset = 1; + fRadius += nOffset; + Rect rt(ptCenter.x - fRadius + nOffset, ptCenter.y - fRadius + nOffset, 2 * fRadius, 2 * fRadius); + rt &= Rect(0, 0, resizedImage.cols, resizedImage.rows); + resizedImage(rt).copyTo(dst); + Mat finalDst(dst.size(), dst.type(), Scalar::all(0)); + cv::circle(finalDst, Point(finalDst.cols / 2, finalDst.rows / 2), fRadius, Scalar::all(1), -1); + dst = dst.mul(finalDst); + return dst; +} + +void ImageCompareModel2::operator()(const cv::Range& range) const +{ + int i0 = range.start; + int i1 = range.end; + assert(abs(i1 - i0) == 1); + model->parallelDetect(i0, m_pData, templ); +} + +void modelVerfication::parallelDetect(int index, void *p, Mat templ) +{ + RData *pData = (RData *)p; + Mat t = getRotationMatrix2D(pData->mCenter, pData->angle(index), 1.0); + Mat rImg; + warpAffine(pData->mImgSrc, rImg, t, pData->mImgSrc.size()); + if (rImg.size() != templ.size()) + { + resize(rImg, rImg, templ.size()); + } + Mat imgRes = abs(templ - rImg); + imgRes = imgRes.mul(m32fMaskImg).mul(weightMat); + float s = sum(weightMat).val[0]; + double val = norm(imgRes) / s; + pData->mDisValVec[index] = val; + pData->mRImgVec[index] = rImg; +} + +void modelVerfication::rotateMatchData(const Mat& _img, const Mat &baseImage, RData* pData, float angleStep, float startAngle, float endAngle) +{ + Mat img = _img.clone(); + Point2f center(img.cols / 2.0, img.rows / 2.0); + int nNum = (endAngle - startAngle) / angleStep; + RData& data = *pData; + data.init(_img, center, angleStep, nNum); + data.mStartAngle = startAngle; + data.mEndAngle = endAngle; + qDebug() << "start parallel test"; + parallel_for_(Range(0, nNum), ImageCompareModel2(this, pData, baseImage)); +} + +void modelVerfication::preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold) +{ + + if (img.type() != CV_32FC1) + { + img.convertTo(img, CV_32FC1); + } + + Mat gaussImg; + GaussianBlur(img, gaussImg, Size(3, 3), 5.0); + img = gaussImg; + + Mat dilatedMask; + dilate(mask, dilatedMask, Mat::ones(Size(3, 3), CV_32FC1)); + + Mat hightlightsMask = img < highlightsThreshold; + Mat imgMask = hightlightsMask & dilatedMask; + //imgMask.convertTo(imgMask, CV_32FC1); + Scalar meanScalar, stddevScalar; + meanStdDev(img, meanScalar, stddevScalar, imgMask); + img = (img - meanScalar.val[0]) * dstStddev / stddevScalar.val[0] + dstMean; + + imgMask.convertTo(imgMask, CV_32FC1); + imgMask /= 255.0; + Mat imgNorm = cocentricNorm(img, Point2f(img.cols / 2.0, img.rows / 2.0), + imgMask, 125); +#ifdef DEBUG_VIEW_INTERNAL_MAT + Mat vImgNorm = imgNorm / 255.0; +#endif + img = imgNorm; +} + +cv::Mat modelVerfication::genMask(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; + } + if (outterR == -1) + { + // default is max radius - 10 + outterR = img.rows * 0.425; + } + circle(mask, center, outterR, Scalar(255), -1); + circle(mask, center, innerR, Scalar(0), -1); + if (type != CV_8UC1) + { + mask.convertTo(mask, type); + mask /= 255; + } + return mask; +} + +cv::Mat modelVerfication::cocentricNorm(Mat& img, Point2f center, const Mat& weightMat, float dstMeanVal) +{ + assert(weightMat.empty() || weightMat.type() == CV_32FC1); + + int w = img.cols; + int h = img.rows; + vector corners; + corners.push_back(Point2f(0, 0)); + corners.push_back(Point2f(0, h)); + corners.push_back(Point2f(w, h)); + corners.push_back(Point2f(w, 0)); + vector cornerDisVec; + for_each(corners.begin(), corners.end(), [&](const Point2f& pt) + { + double dis = disOfPoint(center, pt); + cornerDisVec.push_back(dis); + }); + + auto farthestCornerDis = max_element(cornerDisVec.begin(), cornerDisVec.end()); + float maxRadius = *farthestCornerDis; + + int radiusNum = floorf(maxRadius); + //radiusNum = 20; + float radiusStep = (maxRadius / radiusNum); + Mat cocentricSumMat = Mat::zeros(1, radiusNum, CV_32FC1); + float* pSumData = (float*)cocentricSumMat.data; + Mat cocentricWeightSumMat = Mat::zeros(1, radiusNum, CV_32FC1); + float* pWeightSumData = (float*)cocentricWeightSumMat.data; + Mat radiusMat(img.rows, img.cols, CV_32FC1); + + for (int y = 0; y < h; y++) + { + const Mat& imgRow = img.row(y); + float* pImgRowData = (float*)imgRow.data; + float* pRadiusRowData = (float*)radiusMat.row(y).data; + + float* pWeightRowData = NULL; + if (!weightMat.empty()) + { + pWeightRowData = (float*)weightMat.row(y).data; + } + + for (int x = 0; x < w; x++) + { + //std::cout << x << " " << y << std::endl; + float weight; + if (pWeightRowData) + { + weight = pWeightRowData[x]; + } + else + { + weight = 1.0; + } + float val = pImgRowData[x] * weight; + float radius = disOfPoint(Point2f(x, y), center); + pRadiusRowData[x] = radius; + int radiusIdx0 = (int)(radius / radiusStep); + assert(radiusIdx0 >= 0); + int radiusIdx1 = radiusIdx0 + 1; + if (radiusIdx0 >= radiusNum - 1) + { + pSumData[radiusNum - 1] += val; + pWeightSumData[radiusNum - 1] += weight; + } + else + { + float s = (radius - radiusStep*radiusIdx0) / radiusStep; + pSumData[radiusIdx0] += val*s; + pSumData[radiusIdx1] += val*(1 - s); + pWeightSumData[radiusIdx0] += s*weight; + pWeightSumData[radiusIdx1] += (1 - s)*weight; + } + } + // CvPlot::plot("sum", pSumData, radiusNum); + // CvPlot::plot("count", pCountData, radiusNum); + // waitKey(); + } + + for (int i = 0; i < radiusNum; ++i) + { + //float radius = (i*radiusStep + radiusStep) / 2; + if (pWeightSumData[i] == 0) + { + + } + else + { + pSumData[i] /= pWeightSumData[i]; + } + } + + Mat retMat = Mat::zeros(img.rows, img.cols, img.type()); + for (int y = 0; y < h; y++) + { + float* pImgRowData = (float*)img.row(y).data; + float* pRetRowData = (float*)retMat.row(y).data; + float* pRadiusData = (float*)radiusMat.row(y).data; + for (int x = 0; x < w; x++) + { + float val = pImgRowData[x]; + float radius = pRadiusData[x]; + float mean = interpolate(pSumData, radiusNum, radiusStep, radius); + if (mean == 0) + { + continue; + } + float newVal = (float)val * dstMeanVal / mean; + pRetRowData[x] = newVal; + } + } + +#ifdef DEBUG_VIEW_INTERNAL_MAT + Mat viewRetMat = retMat / 255.0; +#endif + + return retMat; +} + + diff --git a/tpvs17/valveDetector/modelVerfication.h b/tpvs17/valveDetector/modelVerfication.h new file mode 100644 index 0000000..0745561 --- /dev/null +++ b/tpvs17/valveDetector/modelVerfication.h @@ -0,0 +1,108 @@ +#pragma once +#include "Luffy.h" +#include "lpbengine.h" +using namespace cv; +class RData +{ +public: + RData() {}; + RData(const Mat &img, Point pt, double dAngleStep, int size) + : mImgSrc(img) + , mStartAngle(0) + , mEndAngle(360) + { + init(img, pt, dAngleStep, size); + }; + void init(const Mat& img, Point pt, double dAngleStep, int size) + { + mImgSrc = img; + mStartAngle = 0; + mEndAngle = 360.0; + mRImgVec.clear(); + mRImgVec.resize(size); + mDisValVec.clear(); + mDisValVec.resize(size, FLT_MAX); + mCenter = pt; + mAngleStep = dAngleStep; + } + double angle(int index) + { + return index*mAngleStep + mStartAngle; + } + double bestAngle() + { + if (mDisValVec.empty()) + { + return -DBL_MAX; + } + size_t bestIndex = min_element(mDisValVec.begin(), + mDisValVec.end()) - mDisValVec.begin(); + double bestAngle = angle(bestIndex); + return bestAngle; + } + Mat bestRImg() + { + if (mRImgVec.empty()) + { + return Mat(); + } + size_t bestIndex = min_element(mDisValVec.begin(), + mDisValVec.end()) - mDisValVec.begin(); + return mRImgVec[bestIndex]; + } + double mAngleStep; + Mat mImgSrc; + Point mCenter; + vector mRImgVec; + vector mDisValVec; + + float mStartAngle, mEndAngle; +}; + +class modelVerfication +{ + + public: + modelVerfication(double tarStddevVal, double tarMeanVal); + ~modelVerfication(); + + Mat extractForegroundWheel(const Mat& background, const Mat& src); + Mat findWheelObject(Mat src, Mat backGroundImg, int thresh); + void rotateMatchData(const Mat& _img, const Mat &baseImage, RData* pData, float angleStep, float startAngle, float endAngle); + void parallelDetect(int index, void *p, Mat templ); + void preProcessImage(Mat& img, const Mat& mask, double dstMean, double dstStddev, int highlightsThreshold); + Mat genMask(const Mat& img, Point2f center, float innerR = -1, + float outterR = -1, + int type = CV_32FC1); + cv::Mat cocentricNorm(Mat& img, Point2f center, const Mat& weightMat, float dstMeanVal); + float interpolate(float* pY, int n, float stepX, float x); + bool objectVerification(const Mat &img, Mat& baseImage, double modelValidThresh, int endAngle, double & s); + void setWeightMat(const Mat& img) + { + weightMat = img; + weightMat.convertTo(weightMat, CV_32FC1); + } + + static int h; + private: + Mat weightMat; + Mat m32fMaskImg; + double tarStddev; + double tarMean; +}; + + + +class ImageCompareModel2 : public cv::ParallelLoopBody +{ +public: + ImageCompareModel2(modelVerfication *m, void* pData, Mat T) + : m_pData(pData), model(m), templ(T) + {} +private: + void *m_pData; + modelVerfication* model; + Mat templ; + virtual void operator() (const cv::Range& range) const; +}; + diff --git a/tpvs17/valveDetector/valveDetector.cpp b/tpvs17/valveDetector/valveDetector.cpp new file mode 100644 index 0000000..1cd65ce --- /dev/null +++ b/tpvs17/valveDetector/valveDetector.cpp @@ -0,0 +1,1810 @@ +#include "ValveDetector.h" +#include +#include "patterndetector.h" +using namespace luffy_base; +ValveDetector::ValveDetector() +{ + luffy_triangle::createNewTrigValue(3600); +} + + +ValveDetector::~ValveDetector() +{ +} + +enum detectMode +{ + shootWheelExist = 0, + shootTargetMatch = 1 +}; +void remove(Mat &img, int fValveWidth) { + + int nStep = 20; + int nOffset = 30; + float fThres = 0.8; + Mat imgDst; + cv::threshold(img, imgDst, 1, 255.0, THRESH_OTSU); + Mat imgHalf; + Rect ret = Rect(0, imgDst.rows / 2 + nOffset, imgDst.cols, imgDst.rows / 2 - nOffset); + if (ret.y > imgDst.rows || (imgDst.rows / 2 + nOffset + imgDst.rows / 2 - nOffset) > imgDst.rows) + return; + imgDst(ret).copyTo(imgHalf); + + Mat imgProj; + luffy_projection::project2axis(imgHalf, imgProj, luffy_projection::emProjX, cv::NORM_MINMAX); + + Mat imgBlob(1, imgProj.cols, CV_8UC1); + imgBlob.setTo(0); + float *pProj = imgProj.ptr(0); + uchar *pBlob = imgBlob.ptr(0); + for (int i = 0; i < imgProj.cols; i++) { + if (pProj[i] >= fThres) { + pBlob[i] = 255; + + int offset = 120; + int nIndex = 0; + bool bLineMode = false; + for (int j = 0; j < offset; j++) { + int nX = i + offset - j; + nX = nX % imgProj.cols; + + if (bLineMode) { + pBlob[nX] = 255; + } + else { + if (pProj[nX] >= fThres) { + bLineMode = true; + nIndex = i + offset - j; + } + } + } + + if (bLineMode) { + if (nIndex >= imgProj.cols) { + break; + } + else { + i = nIndex; + } + } + } + } + + for (int i = 0; i < imgProj.cols; i++){ + if (pBlob[i] != 0) { + img.col(i).setTo(0); + } + } +} + +Point getNextMinMax(Mat *img, Point maxLoc, double minVal, InputParam InputParameter) +{ + int templateH = InputParameter.barTemplate.rows; + int templateW = InputParameter.barTemplate.cols; + + int startX = maxLoc.x - templateW / 2; + int startY = 0; + + int endX = maxLoc.x + templateW / 2; + int endY = img->rows - 1; + if (startX < 0 || startY < 0) + { + startX = 0; + startY = 0; + } + if (endX > img->cols - 1 || endY >img->rows - 1) + { + endX = img->cols - 1; + endY = img->rows - 1; + } + for (int y = startY; y < endY + 1; y++) + { + float* fPtr = (float*)img->row(y).data; + for (int x = startX; x <= endX; x++) + { + fPtr[x] = minVal; + } + } + double minValue, maxValue; + Point iminLoc, imaxLoc; + minMaxLoc(*img, &minValue, &maxValue, &iminLoc, &imaxLoc); + return imaxLoc; +} +void findCandidateValsInMat(const Mat &_img, vector &canPoints, InputParam InputParameter) +{ + Mat result = _img.clone(); + double minVal, maxVal; + Point minLoc, maxLoc; + minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); + canPoints.push_back(maxLoc); + int barNum = InputParameter.barNum; + if (barNum <=0) + { + qWarning() << "burNum cannot be negatIve or ZERO"; + return; + } + int maxLength = InputParameter.nMaxAngle; + int interval = maxLength / barNum; + for (int i = 1; i < barNum; i++) + { + int nextLoc = maxLoc.x + (i*interval); + if (nextLoc >= maxLength) + { + nextLoc = nextLoc % maxLength; + } + canPoints.push_back(Point(nextLoc, 0)); + } + + /*Point next_maxPoint; + next_maxPoint = getNextMinMax(&result, maxLoc, minVal, InputParameter); + canPoints.push_back(next_maxPoint); + next_maxPoint = getNextMinMax(&result, next_maxPoint, minVal, InputParameter); + canPoints.push_back(next_maxPoint); + next_maxPoint = getNextMinMax(&result, next_maxPoint, minVal, InputParameter); + canPoints.push_back(next_maxPoint); + next_maxPoint = getNextMinMax(&result, next_maxPoint, minVal, InputParameter); + canPoints.push_back(next_maxPoint);*/ + /*next_maxPoint = getNextMinMax(&result, next_maxPoint, minVal, InputParameter); + canPoints.push_back(next_maxPoint);*/ +} + +void findOffsets(InputParam in, const vector & canVec, vector & detectOffset) +{ + int barNum = in.barNum; + if (barNum <=0) + { + qWarning() << "barNum cannot be negative or ZERO"; + return; + } + int maxLength = in.nMaxAngle; + int withinOffset = in.withinOffset; + int width = in.barTemplate.cols; + for (int i = 0; i < barNum; i++) + { + float barX = canVec[i].x + width / 2.0; + float holeX = barX + withinOffset; + if (holeX > maxLength) + { + //holeX = holeX % maxLength; + holeX = fmod(holeX, (double)maxLength); + } + detectOffset.push_back(holeX); + } + +} + +void creatMask(const Mat &img2Rect, const vector &offsetVec, InputParam paramIn, Mat &iMask) +{ + int smallMove = 20; + + for (int i = 0; i < offsetVec.size(); i++) + { + int holeX = offsetVec[i]; + int width = paramIn.imgTemplate.cols + 2*smallMove; + + int startX = holeX - paramIn.imgTemplate.cols / 2 - smallMove; + + if (startX < 0) + { + int offset = abs(startX); + startX = paramIn.nMaxAngle - offset; + //iMask(Rect(startX, 0, offset, img2Rect.rows)).setTo(255); + } + if (startX + paramIn.imgTemplate.cols + 2*smallMove> paramIn.nMaxAngle) + { + width = paramIn.nMaxAngle - startX; + int offset = startX + paramIn.imgTemplate.cols + 2*smallMove- paramIn.nMaxAngle; + iMask(Rect(0, 0, offset, img2Rect.rows)).setTo(255); + } + + Rect candidateRoi(startX, 0, width, img2Rect.rows); + iMask(candidateRoi).setTo(255); + } +} +void genSobelImage1(Mat& img, Mat* pSobelx /*= NULL*/, Mat* pSobely /*= NULL*/) +{ + Mat sobelx, sobely; + Sobel(img, sobelx, CV_32FC1, 1, 0); + Sobel(img, sobely, CV_32FC1, 0, 1); + img = sobelx.mul(sobelx) + sobely.mul(sobely); + Mat tempImg; + img.convertTo(tempImg, CV_32FC1); + Mat tempImg0; + sqrt(tempImg, tempImg0); + img = tempImg0; + + if (pSobelx) + { + *pSobelx = sobelx; + } + if (pSobely) + { + *pSobely = sobely; + } +} + +cv::Mat getSobelDir(const Mat& sobelX, const Mat& sobelY) +{ + Mat img(sobelX.rows, sobelX.cols, CV_16UC1); + for (int i = 0; i < img.rows; ++i) + { + Mat row = img.row(i); + float* pDataX = (float*)sobelX.row(i).data; + float* pDataY = (float*)sobelY.row(i).data; + ushort* pData = (ushort*)row.data; + for (int j = 0; j < img.cols; ++j) + { + float dx = pDataX[j]; + float dy = pDataY[j]; + float angle = 0; + if (dx == 0 && dy == 0) + { + angle = 0; + } + else + { + angle = atan2f(dy, dx); + if (angle < 0) + { + angle += 2.0 * M_PI; + } + } + pData[j] = floorf((angle / M_PI) * 180); + } + } + return img; +} +void genSobelDir1(Mat& img) +{ + Mat srcImg = img.clone(); + Mat sobelX, sobelY; + genSobelImage1(srcImg, &sobelX, &sobelY); + img = getSobelDir(sobelX, sobelY); +} + + +void histMeanStddev(const Mat& hist, double* pMean, double* pStddev) +{ + float * pData = (float*)hist.data; + double sum = 0; + int count = 0; + for (int i = 0; i < hist.cols; ++i) + { + if (!pData[i]) + { + continue; + } + count += pData[i]; + sum += pData[i] * i; + } + if (count == 1) + { + if (pMean) + { + *pMean = sum; + } + if (pStddev) + { + *pStddev = 0; + } + return; + } + *pMean = sum / (double)count; + sum = 0; + for (int i = 0; i < hist.cols; ++i) + { + if (!pData[i]) + { + continue; + } + double d = i - *pMean; + sum += d*d*pData[i]; + } + *pStddev = sqrt(sum / (double)(count - 1)); +} + +//void rotateMatchData(const Mat& _img, Mat &templ, RotateData* pData, float angleStep, float startAngle, float endAngle) +//{ +// 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, center, angleStep, nNum); +// data.mStartAngle = startAngle; +// data.mEndAngle = endAngle; +// +// parallel_for_(Range(0, nNum), ImageCompareModelInvoker(templ, pData)); +//} +// +//void parallelDetect(int index, void *p, Mat templ) +//{ +// RotateData *pData = (RotateData *)p; +// Mat t = getRotationMatrix2D(pData->mCenter, pData->angle(index), 1.0); +// Mat rImg; +// warpAffine(pData->mImgSrc, rImg, t, pData->mImgSrc.size()); +// +// Mat imgRes = templ - rImg; +// double val = norm(imgRes); +// pData->mDisValVec[index] = val; +// pData->mRImgVec[index] = rImg; +//} +//void ImageCompareModelInvoker::operator()(const cv::Range& range) const +//{ +// int i0 = range.start; +// int i1 = range.end; +// assert(abs(i1 - i0) == 1); +// parallelDetect(i0, m_pData, temp); +//} + +double tempScoreShoot(Mat &_img, Mat &template_img, detectMode mode) +{ + qDebug() << "tempScoreShoot"; + double dis = 0.0; + Mat templateDir = template_img.clone(); + Mat temporaryDir = _img.clone(); + + //temporaryDir = temporaryDir(Rect(0, 30, temporaryDir.cols, temporaryDir.rows - 30)); + Mat normTemplateDir, normTemporaryDir; + Mat blurredTempl, blurredTempo; + cv::GaussianBlur(templateDir, blurredTempl, Size(3, 3), 5.0); + cv::GaussianBlur(temporaryDir, blurredTempo, Size(3, 3), 5.0); + + luffy_imageProc::meanvarnorm(blurredTempl, normTemplateDir, 120, 50); + luffy_imageProc::meanvarnorm(blurredTempo, normTemporaryDir, 120, 50); + +// normTemplateDir.convertTo(normTemplateDir, CV_16UC1); +// normTemporaryDir.convertTo(normTemporaryDir, CV_16UC1); + normTemplateDir.convertTo(normTemplateDir, CV_32F); + normTemporaryDir.convertTo(normTemporaryDir, CV_32F); + genSobelDir1(normTemplateDir); + genSobelDir1(normTemporaryDir); + + Mat templateHist, temporaryHist, magHist; + float range[] = { 0, 360 }; + const float * histRange = { range }; + int histSize = 36; + + calcHist(&normTemplateDir, 1, 0, Mat(), templateHist, 1, &histSize, &histRange, true, false); + calcHist(&normTemporaryDir, 1, 0, Mat(), temporaryHist, 1, &histSize, &histRange, true, false); + + +#ifdef VEIW_HISTGRAM + + Mat dstImage = Mat::zeros(512, 800, CV_8UC3); + //normalize(templateHist, templateHist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); + //normalize(temporaryHist, temporaryHist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); + double max = 0; + double max1 = 0; + minMaxLoc(templateHist, NULL, &max, 0, 0); + minMaxLoc(temporaryHist, NULL, &max1, 0, 0); + max = MAX(max, max1); + + double bin_w = (double)dstImage.cols / histSize; // the interval of every bin + double bin_u = (double)dstImage.rows / max; //// the maximal height + + // draw histGram + for (int i = 0; i < histSize; i++) + { + Point p0 = Point(i*bin_w, dstImage.rows); + + int val = templateHist.at(i); + int val1 = temporaryHist.at(i); + Point p1 = Point((i + 1)*bin_w, dstImage.rows - val*bin_u); + Point p2 = Point((i + 1)*bin_w, dstImage.rows - val1*bin_u); + rectangle(dstImage, p0, p1, Scalar(0, 255), 1, 8, 0); + rectangle(dstImage, p0, p2, Scalar(0, 0, 255), 1, 8, 0); + //imshow("image", dstImage); + } + + char string[12]; + int yAxis = 0; + for (int i = 1; yAxis < max; i++) + { + yAxis = i*max / 10; + itoa(yAxis, string, 10); + cv::putText(dstImage, string, Point(0, dstImage.rows - yAxis*bin_u), 1, 1, Scalar(0, 255, 255)); + } + int xAxis = 0; + for (int i = 1; xAxis < 360; i++) + { + xAxis = i * 20; + itoa(xAxis, string, 10); + cv::putText(dstImage, string, Point(xAxis*(dstImage.cols / 360), dstImage.rows), 1, 1, Scalar(0, 255, 255)); + } + +#endif // VEIW_HISTGRAM + switch (mode) + { + case shootWheelExist: + { + + /* double templMean, templStddev, tempoMean, tempoStddev; + transpose(templateHist, templateHist); + transpose(temporaryHist, temporaryHist); + histMeanStddev(templateHist, &templMean, &templStddev); + histMeanStddev(temporaryHist, &tempoMean, &tempoStddev); + double meanDiff = abs(templMean - tempoMean); + double stddevDiff = abs(templStddev - tempoStddev); + if (meanDiff > 1.5 || stddevDiff > 1.5) + { + qDebug() << "there is no wheel exist"; + return 0; + } + else + { + qDebug() << "wheel exists"; + return 1; + }*/ + } + case shootTargetMatch: + { + qDebug() << "start get matchScore:" ; + double templCount = cv::sum(templateHist.rowRange(12, 25)).val[0]; + double temporCount = cv::sum(temporaryHist.rowRange(12, 25)).val[0]; + dis = temporCount / templCount; + if (dis > 0.60) + { + + if (dis > 1) + { + dis = 1; + qDebug() << "matchScore:" << dis; + return dis; + } + else + { + qDebug() << "matchScore:" << dis; + return dis; + } + } + qDebug() << "fail to find the targetMatch"; + return 0; + } + } + qDebug() << "end tempScoreShoot"; + return 0; +} +//template +//double pointDis(const _Point& i, const _Point& j) +//{ +// return norm(i - j); +//} + +//float interpolate(float* pY, int n, float stepX, float x) +//{ +// int lIdx = (int)(x / stepX); +// int rIdx = lIdx + 1; +// if (rIdx > n - 1) +// { +// return pY[n - 1]; +// } +// assert(lIdx >= 0 && lIdx < n && rIdx >= 0 && rIdx < n); +// float s = (x - lIdx*stepX) / stepX; +// float ly = pY[lIdx]; +// float ry = pY[rIdx]; +// return ly + (ry - ly)*s; +//} +//cv::Mat cocentricNorm( Mat& img, Point2f center, const Mat& weightMat, float dstMeanVal) +//{ +// assert(weightMat.empty() || weightMat.type() == CV_32FC1); +// +// int w = img.cols; +// int h = img.rows; +// vector corners; +// corners.push_back(Point2f(0, 0)); +// corners.push_back(Point2f(0, h)); +// corners.push_back(Point2f(w, h)); +// corners.push_back(Point2f(w, 0)); +// vector cornerDisVec; +// for_each(corners.begin(), corners.end(), [&](const Point2f& pt) +// { +// double dis = pointDis(center, pt); +// cornerDisVec.push_back(dis); +// }); +// +// auto farthestCornerDis = max_element(cornerDisVec.begin(), cornerDisVec.end()); +// float maxRadius = *farthestCornerDis; +// +// int radiusNum = floorf(maxRadius); +// //radiusNum = 20; +// float radiusStep = (maxRadius / radiusNum); +// Mat cocentricSumMat = Mat::zeros(1, radiusNum, CV_32FC1); +// float* pSumData = (float*)cocentricSumMat.data; +// Mat cocentricWeightSumMat = Mat::zeros(1, radiusNum, CV_32FC1); +// float* pWeightSumData = (float*)cocentricWeightSumMat.data; +// Mat radiusMat(img.rows, img.cols, CV_32FC1); +// +// for (int y = 0; y < h; y++) +// { +// const Mat& imgRow = img.row(y); +// float* pImgRowData = (float*)imgRow.data; +// float* pRadiusRowData = (float*)radiusMat.row(y).data; +// +// float* pWeightRowData = NULL; +// if (!weightMat.empty()) +// { +// pWeightRowData = (float*)weightMat.row(y).data; +// } +// +// for (int x = 0; x < w; x++) +// { +// //std::cout << x << " " << y << std::endl; +// float weight; +// if (pWeightRowData) +// { +// weight = pWeightRowData[x]; +// } +// else +// { +// weight = 1.0; +// } +// float val = pImgRowData[x] * weight; +// float radius = pointDis(Point2f(x, y), center); +// pRadiusRowData[x] = radius; +// int radiusIdx0 = (int)(radius / radiusStep); +// assert(radiusIdx0 >= 0); +// int radiusIdx1 = radiusIdx0 + 1; +// if (radiusIdx0 >= radiusNum - 1) +// { +// pSumData[radiusNum - 1] += val; +// pWeightSumData[radiusNum - 1] += weight; +// } +// else +// { +// float s = (radius - radiusStep*radiusIdx0) / radiusStep; +// pSumData[radiusIdx0] += val*s; +// pSumData[radiusIdx1] += val*(1 - s); +// pWeightSumData[radiusIdx0] += s*weight; +// pWeightSumData[radiusIdx1] += (1 - s)*weight; +// } +// } +// // CvPlot::plot("sum", pSumData, radiusNum); +// // CvPlot::plot("count", pCountData, radiusNum); +// // waitKey(); +// } +// +// for (int i = 0; i < radiusNum; ++i) +// { +// //float radius = (i*radiusStep + radiusStep) / 2; +// if (pWeightSumData[i] == 0) +// { +// +// } +// else +// { +// pSumData[i] /= pWeightSumData[i]; +// } +// } +// +// Mat retMat = Mat::zeros(img.rows, img.cols, CV_32FC1); +// for (int y = 0; y < h; y++) +// { +// float* pImgRowData = (float*)img.row(y).data; +// float* pRetRowData = (float*)retMat.row(y).data; +// float* pRadiusData = (float*)radiusMat.row(y).data; +// for (int x = 0; x < w; x++) +// { +// float val = pImgRowData[x]; +// float radius = pRadiusData[x]; +// float mean = interpolate(pSumData, radiusNum, radiusStep, radius); +// if (mean == 0) +// { +// continue; +// } +// float newVal = (float)val * dstMeanVal / mean; +// pRetRowData[x] = newVal; +// } +// } +// +// Mat viewRetMat = retMat / 255.0; +// +// +// return retMat; +//} + + +//bool ValveDetector::isValid(Mat target, Mat templ, Point2f pt, int validThresh) +//{ +// qDebug() << "detect if image is valid"; +// if (target.type() != CV_32FC1) +// { +// target.convertTo(target, CV_32FC1); +// } +// templ.convertTo(templ, CV_32FC1); +// int templW = templ.cols; +// int templH = templ.rows; +// Mat imgRoi; +// target(Rect(pt.x - templW / 2, pt.y - templH / 2, templW, templH)).copyTo(imgRoi); +// Mat circleMask(imgRoi.size(), CV_32FC1, Scalar::all(0)); +// cv::circle(circleMask, Point(imgRoi.cols / 2, imgRoi.rows / 2), imgRoi.cols / 2, Scalar(1), -1); +// imgRoi = imgRoi.mul(circleMask); +// templ = templ.mul(circleMask); +// +// resize(imgRoi, imgRoi, Size(imgRoi.cols / 2, imgRoi.cols / 2), INTER_LINEAR); +// resize(templ, templ, Size(templ.cols / 2, templ.cols / 2), INTER_LINEAR); +// +// Mat bullredTempl, blurredRoi; +// cv::GaussianBlur(imgRoi, bullredTempl, Size(3, 3), 5.0); +// cv::GaussianBlur(templ, blurredRoi, Size(3, 3), 5.0); +// Mat innerMask(bullredTempl.size(), CV_8UC1, Scalar::all(0)); +// cv::circle(innerMask, Point(bullredTempl .cols / 2, bullredTempl.rows / 2), bullredTempl.cols / 2, Scalar(255), -1); +// Mat normTempl, normRoi; +// luffy_imageProc::meanvarnorm(bullredTempl, normTempl, 60, 30, innerMask); // 50 +// luffy_imageProc::meanvarnorm(blurredRoi, normRoi, 60, 30, innerMask); +// innerMask.convertTo(innerMask, CV_32FC1); +// +// RotateData* pData = new RotateData(); +// rotateMatchData(normRoi, normTempl, pData, 1, 0, 90); +// +// double result = 0; +// Mat rstImg; +// if (pData->mDisValVec.empty()) +// { +// delete pData; +// qDebug() << "the distance of centers is empty"; +// result = FLT_MAX; +// } +// else +// { +// size_t bestIndex = min_element(pData->mDisValVec.begin(), pData->mDisValVec.end()) - pData->mDisValVec.begin(); +// +// result = pData->mDisValVec[bestIndex]; +// qDebug() << "found the minimal value of distance:" << result; +// delete pData; +// } +// if (result < validThresh) +// { +// qDebug() << "image is valid"; +// return true; +// } +// else +// { +// qDebug() << "image is not valid"; +// return false; +// } +//} + +cv::Mat LoopRoi(Mat &src, int x, int nWidth) { + Mat dst; + if (x + nWidth > src.cols) { + + if (src.type() == CV_8UC1) + { + dst.create(Size(nWidth, src.rows), CV_8UC1); + } + else + { + dst.create(Size(nWidth, src.rows), CV_32FC1); + } + src(Rect(x, 0, src.cols - x, src.rows)).copyTo(dst(Rect(0, 0, src.cols - x, src.rows))); + src(Rect(0, 0, nWidth - src.cols + x, src.rows)).copyTo(dst(Rect(src.cols - x, 0, nWidth - src.cols + x, src.rows))); + } + else { + Rect roi(x, 0, nWidth, src.rows); + src(roi).copyTo(dst); + } + return dst; +} + + +cv::Point2f ValveDetector::getCenterPoints(Mat &_Img, const Mat ¢erTempl, InputParam paramIn, Point2f pt, Mat & rstMat) +{//Ķλ 0ر 1 + if (0 == paramIn.nCenterAlg) { + return pt; + } + + if (paramIn.wheelType == 1) + { + if (paramIn.backGround.empty()) + { + return pt; + } + else + { + Record_List roiRecord = paramIn.roi.records; + int nRoiCount = roiRecord.size(); + if (nRoiCount > 0) + { + Item_List itemRoi = roiRecord.front(); + int width = abs(itemRoi.front().second.at(2)); + int height = abs(itemRoi.front().second.at(3)); + int corr_x = itemRoi.front().second.at(0) - width / 2.0; + int corr_y = itemRoi.front().second.at(1) - height / 2.0; + Rect rect = Rect(corr_x, corr_y, width, height); + Mat roiMat = _Img(rect); + Mat backCandidateMat = paramIn.backGround(rect); + //Mat forMat = abs(roiMat - backCandidateMat); + luffy_base::luffyCircle pCircle; + findCircleObject(roiMat, backCandidateMat, paramIn.backgroundThresh, &pCircle); + rstMat = findCircleObject(_Img, paramIn.backGround, paramIn.backgroundThresh, NULL); + float axis_x = corr_x + pCircle.ptCenter.x; + float axis_y = corr_y + pCircle.ptCenter.y; + return Point2f(axis_x, axis_y); + } + } + + luffy_base::luffyCircle pCircle; + rstMat = findCircleObject(_Img, paramIn.backGround, paramIn.backgroundThresh, &pCircle); + qDebug() << "get image"; + return pCircle.ptCenter; + } + else + { + Mat centerMatch; + int nOffset = 80; //need + int templW = centerTempl.cols; + int templH = centerTempl.rows; + + int nStartX = pt.x - templW / 2 - nOffset; + int nStartY = pt.y - templH / 2 - nOffset; + if (nStartX<0||nStartY<0) + return Point2f(0, 0); + if ((2 * nOffset + templH)>_Img.rows) + return Point2f(0, 0); + if ((2 * nOffset + templW)>_Img.cols) + return Point2f(0, 0); + if ((2 * nOffset + templH+nStartY) > _Img.rows) + return Point2f(0, 0); + if ((2 * nOffset + templW+nStartX) > _Img.cols) + return Point2f(0, 0); + + Mat imgRoi; + _Img(Rect(pt.x - templW / 2 - nOffset, pt.y - templH / 2 - nOffset, 2 * nOffset + templW, 2 * nOffset + templH)).copyTo(imgRoi); + + matchTemplate(imgRoi, centerTempl, centerMatch, CV_TM_CCOEFF_NORMED); + Point p; + double v = luffy_math::getMinMaxData(centerMatch, luffy_math::emDataMax, &p); + int localCenterX = p.x + templW / 2; + int localCenterY = p.y + templH / 2; + int newCenterX = pt.x - templW / 2 - nOffset + localCenterX; + int newCenterY = pt.y - templH / 2 - nOffset + localCenterY; + /*Mat img1 = _Img.clone(); + Mat img2 = _Img.clone(); + Mat img3 = _Img.clone(); + vector imgs; + imgs.push_back(img1); + imgs.push_back(img2); + imgs.push_back(img3); + Mat rst; + merge(imgs, rst); + cv::circle(rst, Point(newCenterX, newCenterY), 3, Scalar(255), -1);*/ + return Point2f(newCenterX, newCenterY); + } + + + +} + +cv::Mat ValveDetector::getForeImage(const Mat & src, const Mat &backgroundImg) +{ + Mat resizedBackgroundImg = backgroundImg; + if (backgroundImg.size() != src.size()) { + resize(backgroundImg, resizedBackgroundImg, src.size()); + } + qDebug() << src.cols << "" << src.rows << "" << resizedBackgroundImg.cols << "" << resizedBackgroundImg.rows; + qDebug() << src.channels() << "" << resizedBackgroundImg.channels(); + Mat h = src - resizedBackgroundImg; + qDebug() << "h pass"; + return (src - resizedBackgroundImg); +} + + +cv::Mat ValveDetector::findCircleObject(const Mat &src, const Mat& backgroundImg, int nThres, luffy_base::luffyCircle *pCircle) +{ + if (src.empty() || backgroundImg.empty() || src.rows < 500) { + return Mat(); + } + + assert(backgroundImg.type() == CV_8UC1); + Mat imgTmp, imgBinary; + const cv::Size cSize = cv::Size(ALG_RESIZE_IMAGE_WIDTH, floorf(ALG_RESIZE_IMAGE_WIDTH / (float)src.cols*(float)src.rows)); + cv::resize(src, imgTmp, cSize); + Mat foregroundImg = getForeImage(imgTmp, backgroundImg);// 0421 + using namespace luffy_base; + luffy_threshold::Threshold(foregroundImg, imgBinary, nThres);//0421 + //luffy_threshold::Threshold(imgTmp, imgBinary, nThres); + + Mat dilatedImgBin; + dilate(imgBinary, dilatedImgBin, Mat::ones(7, 7, CV_32FC1)); + erode(dilatedImgBin, imgBinary, Mat::ones(7, 7, CV_32FC1)); + erode(imgBinary, imgBinary, Mat::ones(1, 13, CV_32FC1)); + dilate(imgBinary, imgBinary, Mat::ones(1, 13, CV_32FC1)); + + vector> conts; + cv::findContours(imgBinary, conts, RETR_EXTERNAL, CHAIN_APPROX_NONE); + imgBinary.setTo(0); + for (int i = 0; i < conts.size(); i++) { + const vector &pt = conts.at(i); + if (pt.size() < 20) { + continue; + } + Rect rt = boundingRect(pt); + if (rt.width < 5 || rt.height < 5) { + continue; + } + drawContours(imgBinary, conts, i, Scalar::all(255), -1); + } + Mat hit; vector pts; + luffy_hit::firstHit4Circle(imgBinary, hit, pts, Point(cSize.width / 2, cSize.height / 2), 0, cSize.width / 2, 360, luffy_hit::emHitOut2In); + qDebug() << "image8"; + //luffy_imageProc::RansacParam rs(0.02, 2.5, 70, 100, 220); + luffy_imageProc::RansacParam rs(0.01, 3, 200, 150, 240);//0421 + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); +#ifdef _DEBUG + Mat imgColor; + cv::cvtColor(imgTmp, imgColor, CV_GRAY2BGR); + for (int i = 0; i < pts.size(); i++) { + imgColor.at(pts.at(i))[0] = 255;//B + imgColor.at< cv::Vec3b >(pts.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts.at(i))[2] = 0;//R + } + for (int i = 0; i < pts2.size(); i++) { + imgColor.at(pts2.at(i))[0] = 0;//B + imgColor.at< cv::Vec3b >(pts2.at(i))[1] = 0;//G + imgColor.at< cv::Vec3b >(pts2.at(i))[2] = 255;//R + } +#endif + + float fRadius; + Point2f ptCenter; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius, ptCenter); + qDebug() << "image9"; + if (!bFind) { + return Mat(); + } + Mat dst; + const int nOffset = 1; + fRadius += nOffset; + Rect rt(ptCenter.x - fRadius + nOffset, ptCenter.y - fRadius + nOffset, 2 * fRadius, 2 * fRadius); + rt &= Rect(0, 0, imgTmp.cols, imgTmp.rows); + imgTmp(rt).copyTo(dst); + static int nCount = cv::getTickCount(); + if (pCircle) { + float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; + Mat matBig = src - backgroundImg;//0421 + //Mat matBig = src; + pCircle->fRadius = fRadius * fScale; + pCircle->ptCenter = Point(ptCenter.x * fScale, ptCenter.y * fScale); + Mat matBinary; + luffy_threshold::Threshold(matBig, matBinary, nThres); + Mat hit; vector pts; + luffy_hit::firstHit4Circle(matBinary, hit, pts, pCircle->ptCenter, 0, pCircle->fRadius + 10, 360, luffy_hit::emHitOut2In); + luffy_imageProc::RansacParam rs(0.01, 2.5, 200, 150, 220); + vector pts2 = luffy_imageProc::fitModelbyRansac(pts, luffy_imageProc::emModelCircle, &rs); + float fRadius2; + Point2f ptCenter2; + bool bFind = luffy_imageProc::lsCircleFit(pts2, fRadius2, ptCenter2); + if (bFind) { + pCircle->fRadius = fRadius2; + pCircle->ptCenter = ptCenter2; + Rect rt(ptCenter2.x - fRadius2 + nOffset, ptCenter2.y - fRadius2 + nOffset, 2 * fRadius2, 2 * fRadius2); + if (rt.x < 0 || rt.y < 0 || rt.x + rt.width > matBinary.cols || rt.y + rt.height > matBinary.rows) { + return Mat(); + } + rt &= Rect(0, 0, matBinary.cols, matBinary.rows); + src(rt).copyTo(dst); + int nWidth = ((int)((double)dst.cols / fScale / 4)) * 4; + cv::resize(dst, dst, cv::Size(nWidth, nWidth)); + } + } + + return dst; +} + + + +bool isRequiredModel(Mat &_img, InputParam ¶mIn) +{ + int notSatisified = 0; + Mat imgRect = _img.clone(); + Mat rstImage; + luffy_match::LoopMatMatch(imgRect, imgRect, luffy_match::emLoopMatX, rstImage); + int interval = floor(paramIn.nMaxAngle / paramIn.barNum); + double minVal, maxVal; + Point minLoc, maxLoc; + cv::minMaxLoc(rstImage, &minVal, &maxVal, &minLoc, &maxLoc); + vector loc; + loc.push_back(maxLoc.x); + Point getMaxLoc; + for (int i = 1; i < paramIn.barNum + 1; i++) + { + getMaxLoc = getNextMinMax(&rstImage, maxLoc, 0, paramIn); + maxLoc = getMaxLoc; + loc.push_back(getMaxLoc.x); + } + std::sort(loc.begin(), loc.end()); + for (int j = 0; j < loc.size(); j++) + { + if (j + 1 >= 7) + { + break; + } + int diff = loc[j + 1] - loc[j]; + int interDiff = abs(diff - interval); + if (interDiff > 10) + { + notSatisified++; + } + } + if (notSatisified > 2) + { + return false; + } + else + { + return true; + } +} + +void getTargetPosAndVal(const Mat &img, InputParam &in, double &val, int &nPos) +{ + vector diffVec; + vector vec; + vec.resize(in.barNum); + diffVec.resize(in.barNum); + Mat result = img.clone(); + double minVal, maxVal; + Point minLoc, maxLoc; + minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); + int maxLength = in.nMaxAngle; + int interval = in.nMaxAngle / in.barNum; + int barX = maxLoc.x + in.barTemplate.cols / 2; + barX = barX % maxLength; + int valveOffset = in.nValveOffset; + diffVec[0] = abs(barX - valveOffset); + vec[0] = barX; + for (int i = 1; i < diffVec.size(); i++) + { + int vOffset = barX + interval*i; + if (vOffset >=in.nMaxAngle) + { + vOffset = vOffset % maxLength; + } + diffVec[i] = abs(vOffset - valveOffset); + vec[i] = vOffset; + } + + size_t valIndex = std::min_element(diffVec.begin(), diffVec.end()) - diffVec.begin(); + nPos = vec[valIndex]; + val = maxVal; + //nPos = barX; +} + +//int matchValveScoreShoot(const vector& rois, const Mat &templ, int candidateIndex) +//{ +// cv::SurfFeatureDetector Detector(400); +// vector roiKeyPoint, templkeyPoint; +// Detector.detect(templ, templkeyPoint); +// +// SurfDescriptorExtractor Descriptor; +// Mat roiDesc, templDesc; +// Descriptor.compute(templ, templkeyPoint, templDesc); +// int Tnum = templkeyPoint.size(); +// if (Tnum <3) +// { +// qDebug() << "num of template keyPoints is less than 3, need to be returned"; +// return -1; +// } +// qDebug() << "the template keyPoints num ;" << Tnum; +// int tarIndex = -1; +// for (int i = 0; i < rois.size(); ++i) +// { +// const Mat &roi = rois[i]; +// Detector.detect(roi, roiKeyPoint); +// Descriptor.compute(roi, roiKeyPoint, roiDesc); +// int keyNum = roiKeyPoint.size(); +// if (keyNum < 3) +// { +// qDebug() << "the Point num is less than 2, need to be returned;" << keyNum; +// continue; +// } +// else +// { +// qDebug() << "the Point num success"; +// } +// /*BFMatcher matcher(NORM_L2, true); +// vector matches; +// matcher.match(templateDesc, imageDesc2, matches); +// Mat img_match; +// drawMatches(templateMat, keyPointTemplate, rightImage, keyPoint2, matches, img_match);*/ +// /*BFMatcher matcher; +// vector matchePoints; +// matcher.match(templDesc, roiDesc, matchePoints);*/ +// /*vector GoodMatchePoints; +// +// double maxDis = 0, minDis = 100; +// for (int j = 0; j < matchePoints.size(); ++j) +// { +// double dis = matchePoints[j].distance; +// if (dis < minDis) +// { +// minDis = dis; +// } +// +// if (dis > maxDis) +// { +// maxDis = dis; +// } +// } +// +// for (int k = 0; k < matchePoints.size(); ++k) +// { +// if (matchePoints[k].distance < 1.2*minDis) +// { +// GoodMatchePoints.push_back(matchePoints[k]); +// } +// }*/ +// FlannBasedMatcher matcher; +// vector > matchePoints; +// vector GoodMatchePoints; +// +// vector train_desc(1, templDesc); +// matcher.add(train_desc); +// qDebug() << "start training"; +// matcher.train(); +// qDebug() << "finish training"; +// +// matcher.knnMatch(roiDesc, matchePoints, 2); +// qDebug()<<"finish match"; +// +// //vector GoodMatchePoints; +// for (int j = 0; j < matchePoints.size(); j++) +// { +// if (matchePoints[j][0].distance < 0.6 * matchePoints[j][1].distance) +// { +// GoodMatchePoints.push_back(matchePoints[j][0]); +// } +// } +// int maxVal = -1; +// int num = 0; +// +// Mat ShowResult; +// int x = GoodMatchePoints.size(); +// if (GoodMatchePoints.size() <= 0) +// { +// continue; +// } +// else +// { +// if (x > maxVal) +// { +// maxVal = GoodMatchePoints.size(); +// tarIndex = i; +// } +// } +// //Mat ShowResult; +// //drawMatches(roi, roiKeyPoint, templ, templkeyPoint, GoodMatchePoints, ShowResult); +// } +// +// return tarIndex; +//} + +int roiCandidateMatch(const vector &vec, Mat templ) +{ + vector candidateVal; + candidateVal.resize(vec.size()); + for (int i = 0; i < vec.size(); ++i) + { + Mat roi = vec[i]; + Mat roiMatch; + luffy_match::LoopMatMatch(roi, templ, luffy_match::emLoopMatX, roiMatch); + Point pt3; + double v3 = luffy_math::getMinMaxData(roiMatch, luffy_math::emDataMax, &pt3); + candidateVal[i] = v3; + } + auto val = std::max_element(candidateVal.begin(), candidateVal.end()); + int index = std::distance(candidateVal.begin(), val); + return index; +} + + +bool imageRotateMatch(Mat & imgSrc, InputParam ¶mIn, OutputParam ¶mOut, vector candidatePoints) +{ + float templateAngle = paramIn.nValveOffset / paramIn.nMaxAngle * 360; + Mat imgTemplate = paramIn.imgTemplate; + vector templates; + templates.resize(360); + int rotateOffset = 15; + int x = imgTemplate.cols / 2 - rotateOffset; + int y = imgTemplate.rows / 2 - rotateOffset; + int width = imgTemplate.cols - 2 * x; + int height = imgTemplate.rows - 2 * y; + Rect rect = Rect(x, y, width, height); + for (int i = templateAngle, j = 0; i < 360 + templateAngle, j < 360; ++i, ++j) + { + i = i % 360; + Mat transMat = getRotationMatrix2D(Point2f(imgTemplate.cols / 2.0, imgTemplate.rows / 2.0), j, 1.0); + Mat dst; + warpAffine(imgTemplate, dst, transMat, imgTemplate.size()); + Mat dstRoi = dst(rect); + templates[i] = dstRoi; + } + + vector> candiateAngleRange; + candiateAngleRange.resize(candidatePoints.size()); + int nOffSet = 0; + for (int x = 0; x < candidatePoints.size(); ++x) + { + float startIndex = candidatePoints[x] - templates[0].cols / 2.0 - nOffSet; + startIndex = luffy_math::mod(startIndex, paramIn.nMaxAngle); + float holeStartAngle = startIndex / paramIn.nMaxAngle * 360; + float endIndex = candidatePoints[x] + templates[0].cols + nOffSet; + float holeEndAngle = 0.0; + if (endIndex > paramIn.nMaxAngle) + { + holeEndAngle = fmod(endIndex, paramIn.nMaxAngle) / paramIn.nMaxAngle * 360; + } + else + { + holeEndAngle = endIndex / paramIn.nMaxAngle * 360; + } + + candiateAngleRange[x].push_back(holeStartAngle); + candiateAngleRange[x].push_back(holeEndAngle); + } + + + float fvalveWidth = paramIn.fValveWidth; + float fvalveDis = paramIn.fValveDis; + Point wheelCenter = paramIn.ptCenter; + int offset = 30; + Mat srcImg = imgSrc.clone(); + int outterRadius = fvalveDis + offset; + int innerRadius = fvalveDis - offset; + + Mat wheelRoi = srcImg(Rect(wheelCenter.x - outterRadius, wheelCenter.y - outterRadius, outterRadius * 2, outterRadius * 2)); + Mat wheelRoiMask(wheelRoi.size(), wheelRoi.type(), Scalar::all(0)); + cv::circle(wheelRoiMask, Point2f(wheelRoi.cols / 2.0, wheelRoi.rows / 2.0), outterRadius, Scalar::all(255), -1); + cv::circle(wheelRoiMask, Point2f(wheelRoi.cols / 2.0, wheelRoi.rows / 2.0), innerRadius, Scalar::all(0), -1); + Mat selectRoi = (wheelRoiMask / 255).mul(wheelRoi); + + /*vector imgs; + Mat img1 = selectRoi.clone(); + Mat img2 = selectRoi.clone(); + imgs.push_back(selectRoi); + imgs.push_back(img2); + imgs.push_back(img1); + Mat showImage; + showImage.setTo(0); + merge(imgs, showImage);*/ + /*std::map valToLoc;*/ + ////qDebug() << "start"; + //float sumVal = 0; + Point p = Point(0, 0); + float maxVal = _I32_MIN; + float m_Index = 0.0; + Mat roi; + roi.setTo(0); + for (int k = 0; k < selectRoi.rows; ++k) + { + //uchar *ptr = selectRoi.row(k).data; + for (int m = 0; m < selectRoi.cols; ++m) + { + //qDebug() << "k:" << k << "m :" << m ; + float dis = luffy_math::disofPoints(Point2f(m, k), Point2f(wheelRoi.cols / 2.0, wheelRoi.rows / 2.0)); + if (dis > outterRadius || dis < innerRadius) + { + continue; + } + float nIndex = luffy_math::caculAngle(Point2f(wheelRoi.cols / 2.0, wheelRoi.rows / 2.0), Point2f(m, k)); + int flag = false; + for (int y = 0; y < candiateAngleRange.size(); ++y) + { + + if (candiateAngleRange[y][0] > candiateAngleRange[y][1]) + { + if ((nIndex >= candiateAngleRange[y][0] && nIndex < 360) || (nIndex >=0 && nIndex <=candiateAngleRange[y][1])) + { + const Mat& templ = templates[nIndex]; + + int nwidth = templ.cols; + int nheight = templ.rows; + if ((m + nwidth >= outterRadius * 2) || (k + nheight > outterRadius * 2)) + { + continue; + } + Mat matchRoi = selectRoi(Rect(m, k, nwidth, nheight)); + Mat val; + cv::matchTemplate(matchRoi, templ, val, CV_TM_CCOEFF_NORMED); + //float val = norm(matchRoi, templ, NORM_L2); + + if (val.at(0, 0) > maxVal) + { + maxVal = val.at(0, 0); + p = Point(m, k); + m_Index = nIndex; + roi = matchRoi; + } + } + } + if (nIndex >= candiateAngleRange[y][0] && nIndex <= candiateAngleRange[y][1]) + { + //selectRoi.at(k, m) = 0; + const Mat& templ = templates[nIndex]; + + int nwidth = templ.cols; + int nheight = templ.rows; + if ((m + nwidth >= outterRadius * 2) || (k + nheight > outterRadius * 2)) + { + continue; + } + Mat matchRoi = selectRoi(Rect(m, k, nwidth, nheight)); + Mat val; + cv::matchTemplate(matchRoi, templ, val, CV_TM_CCOEFF_NORMED); + //float val = norm(matchRoi, templ, NORM_L2); + + if (val.at(0, 0) > maxVal) + { + maxVal = val.at(0, 0); + p = Point(m, k); + m_Index = nIndex; + roi = matchRoi; + } + } + } + + } + } + Point2f pLoc = Point2f(p.x + templates.front().cols / 2.0, p.y + templates.front().rows / 2.0); + paramOut.rstPoint = paramIn.ptCenter + pLoc - Point2f(wheelRoi.cols / 2.0, wheelRoi.rows / 2.0); + paramOut.dAngleRes = m_Index; + paramOut.dScore = maxVal; + paramIn.fValveWidth = templates.front().cols / 2.0; + //cv::rectangle(showImage, p, Point(p.x + templates[0].cols, p.y + templates[0].rows), Scalar(0, 0, 255), 2, 8, 0); + double disVal = tempScoreShoot(roi, templates[55], detectMode::shootTargetMatch); + return true; +} + + +bool ValveDetector::detect(Mat & imgSrc, InputParam ¶mIn, OutputParam ¶mOut, Mat &imgDst /*= Mat()*/) +{ + + int rtWidth = 100; + if (paramIn.ptCenter.x - rtWidth < 0 || paramIn.ptCenter.y - rtWidth < 0) + return false; + if (paramIn.ptCenter.x + 2 * rtWidth > imgSrc.cols) + return false; + if (paramIn.ptCenter.y + 2 * rtWidth>imgSrc.rows) + return false; + + if (paramIn.barNum <= 0) + return false; + + cv::Mat imgCenter = imgSrc(Rect(paramIn.ptCenter.x - rtWidth, paramIn.ptCenter.y - rtWidth, 2 * rtWidth, 2 * rtWidth)); + Scalar scMean = cv::mean(imgCenter); + if (scMean[0] < 20) { + paramOut.dAngle = 3610; + paramOut.dScore = 0; + } + else { + float fValveWidth = paramIn.fValveWidth; + float fValveDis = paramIn.fValveDis; + int offset = 10; + int nImgHeight = fValveWidth * 2 + 2 * offset; + Mat img2Rect; + paramIn.ptCenter = Point(paramIn.ptCenter.x , paramIn.ptCenter.y); + luffy_math::polar2rect(imgSrc, img2Rect, paramIn.ptCenter, + fValveDis - nImgHeight / 2, fValveDis + nImgHeight / 2, paramIn.nMaxAngle); + + Mat imgMatch, barCompare; + + + if (paramIn.flagCircle == 1 ) + { + luffy_match::LoopMatMatch(img2Rect, paramIn.barTemplate, luffy_match::emLoopMatX, barCompare); + double score = 0; + int tarPos; + getTargetPosAndVal(barCompare, paramIn, score, tarPos); + paramOut.dAngle = tarPos; + paramOut.dScore = score; + } + else + { + luffy_match::LoopMatMatch(img2Rect, paramIn.barTemplate, luffy_match::emLoopMatX, barCompare); + vector candidatePoints; + findCandidateValsInMat(barCompare, candidatePoints, paramIn); + int bIsNotStatisfy = 0; + Mat imgRect = img2Rect.clone(); + for (int i = 0; i < candidatePoints.size(); i++) + { + int rectW = paramIn.barTemplate.cols; + int rectH = img2Rect.rows; + if ((candidatePoints[i].x + rectW) > img2Rect.cols) + { + rectW = img2Rect.cols - candidatePoints[i].x; + int leftOffset = candidatePoints[i].x + paramIn.barTemplate.cols - img2Rect.cols; + img2Rect(Rect(0, 0, leftOffset, rectH)).setTo(0); + } + Rect rToBeErease(candidatePoints[i].x, 0, rectW, rectH); + img2Rect(rToBeErease).setTo(0); + Mat barRoi = LoopRoi(barCompare, candidatePoints[i].x, paramIn.barTemplate.cols); + double dx = luffy_math::getMinMaxData(barRoi, luffy_math::emDataMax); + if (dx < paramIn.nBarScore / 100.0) { + bIsNotStatisfy++; + } + } + + if (bIsNotStatisfy < 2) { + vector detectedOffset; + findOffsets(paramIn, candidatePoints, detectedOffset); + + //Mat iMask(img2Rect.size(), img2Rect.type(), Scalar::all(0)); + //creatMask(img2Rect, detectedOffset, paramIn, iMask); + vector vecImg; + int nOffset = 10; + for (int i = 0; i < detectedOffset.size(); i++) { + int nStart = detectedOffset.at(i) - paramIn.imgTemplate.cols / 2.0 - nOffset; + nStart = luffy_math::mod(nStart, paramIn.nMaxAngle); + Mat roi = LoopRoi(imgRect, nStart, paramIn.imgTemplate.cols + 2 * nOffset); + Mat roi2 = roi(Rect(0, 0, roi.cols, roi.rows *3.0 / 5)); + // Mat roi3; + // float m = 128; float d = 70.0; + // luffy_imageProc::meanvarnorm(roi2, roi3, m, d); + if (paramIn.wheelType == 0) + { + vecImg.push_back(roi2); + } + else + { + vecImg.push_back(roi); + } + + } + + + // FOR MOTORCIRCLE PROGRAM START + Mat ret(vecImg.size(), vecImg.size(), CV_32FC1, Scalar(0)); + for (int i = 0; i < vecImg.size(); i++) { + for (int j = 0; j < vecImg.size(); j++) { + Mat imgMatch2; + Point pt; + Mat templ; + luffy_match::LoopMatMatch(vecImg.at(i), vecImg.at(j), luffy_match::emLoopMatY, imgMatch2); + double v = luffy_math::getMinMaxData(imgMatch2, luffy_math::emDataMax, &pt); + ret.at(i, j) = v; + } + } + + float fMin = 1000; + int nIndex = 0; + std::map scoreMapIndex; + for (int i = 0; i < ret.cols; i++) { + float fSum = sum(ret.col(i))[0]; + scoreMapIndex[fSum] = i; + if (fSum < fMin) { + fMin = fSum; + nIndex = i; + } + } + + std::map::iterator it = scoreMapIndex.begin(); + int candidateIndex = 0; + int ni = 0; + for (; it != scoreMapIndex.end(); ++it, ++ni) + { + if (ni == 1) + { + candidateIndex = it->second; + } + } + //FOR MOTORCIRCLE END + double mcutOffset = 1.0; + float ss = 0.0; + if (paramIn.wheelType == 0) + { + + mcutOffset = 2.0; + + // FOR MOTORCIRCLE PROGRAM START + Mat imgTemplate = paramIn.imgTemplate(Rect(0, 0, paramIn.imgTemplate.cols, paramIn.imgTemplate.rows / mcutOffset)); + + Mat ret0; + matchTemplate(vecImg[nIndex], imgTemplate, ret0, CV_TM_CCORR_NORMED); + Point p0; + double v0 = luffy_math::getMinMaxData(ret0, luffy_math::emDataMax, &p0); + + Mat ret1; + matchTemplate(vecImg[candidateIndex], imgTemplate, ret1, CV_TM_CCORR_NORMED); + Point p1; + double v1 = luffy_math::getMinMaxData(ret1, luffy_math::emDataMax, &p1); + nIndex = v1 > v0 ? candidateIndex : nIndex; + + Mat identicalImg = vecImg[nIndex](Rect(10, 0, imgTemplate.cols, imgTemplate.rows)); + double disVal = tempScoreShoot(identicalImg, imgTemplate, detectMode::shootTargetMatch); + + std::vector vecMat; + auto imgCrop = [&](Mat srcMat, std::vector& vecMat){ + int rightTopX = srcMat.cols - imgTemplate.cols; + int leftDownY = srcMat.rows - imgTemplate.rows; + Mat rightTopMat = srcMat(Rect(rightTopX, 0, imgTemplate.cols, imgTemplate.rows)); + Mat leftDownMat = srcMat(Rect(0, leftDownY, imgTemplate.cols, imgTemplate.rows)); + Mat rightDownMat = srcMat(Rect(rightTopX, leftDownY, imgTemplate.cols, imgTemplate.rows)); + vecMat.push_back(rightTopMat); + vecMat.push_back(leftDownMat); + vecMat.push_back(rightDownMat); + }; + + imgCrop(vecImg[nIndex], vecMat); + + for each (Mat vMat in vecMat) + { + double s = tempScoreShoot(vMat, imgTemplate, detectMode::shootTargetMatch); + if (s > disVal) + { + disVal = s; + } + } + + int targetIndex = nIndex; + float maxVal = disVal; + + + if (disVal < 0.85) + { + float vMax = FLT_MIN; + for (int k = 0; k < vecImg.size(); k++) + { + if (k == nIndex) + { + continue; + } + else + { + + Mat imgRet; + matchTemplate(vecImg[k], imgTemplate, imgRet, CV_TM_CCORR_NORMED); + Point pnt; + double v3 = luffy_math::getMinMaxData(imgRet, luffy_math::emDataMax, &pnt); + if (v3 > vMax) + { + targetIndex = k; + vMax = v3; + } + + } + } + /*identicalImg = vecImg[targetIndex](Rect(10, 0, imgTemplate.cols, imgTemplate.rows)); + vector localMatVec; + imgCrop(vecImg[targetIndex], localMatVec); + + for each (Mat mat in localMatVec) + { + double s = tempScoreShoot(mat, imgTemplate, detectMode::shootTargetMatch); + if (s > disVal) + { + disVal = s; + } + } + */ + + /*disVal = tempScoreShoot(identicalImg, imgTemplate, detectMode::shootTargetMatch); + + if (disVal > maxVal) + { + maxVal = disVal; + targetIndex = k; + }*/ + } + nIndex = targetIndex; + Mat imgMatchRet; + matchTemplate(vecImg[nIndex], imgTemplate, imgMatchRet, CV_TM_CCORR_NORMED); + Point pt3; + double v3 = luffy_math::getMinMaxData(imgMatchRet, luffy_math::emDataMax, &pt3); + float nPos = pt3.x + detectedOffset.at(nIndex) - nOffset; + paramOut.dAngle = fmod(nPos, (double)paramIn.nMaxAngle); + paramOut.dScore = v3; + } + else + { + Rect ret = Rect(0, 0, paramIn.imgTemplate.cols, paramIn.imgTemplate.rows / mcutOffset); + if (paramIn.imgTemplate.cols <= 0 || paramIn.imgTemplate.rows / mcutOffset <= 0 || paramIn.imgTemplate.rows / mcutOffset > paramIn.imgTemplate.rows) + return false; + + Mat imgTemplate = paramIn.imgTemplate(ret); + PatternDetector m_detect; + m_detect.train(imgTemplate); + Vec4f t_vec; + int m_posIndex = 0; + float maxVal = 0; + int m_index = 0; + for (int k = 0; k < vecImg.size(); k++) + { + Mat roiMat = vecImg[k]; + float score = m_detect.detectBest(roiMat, t_vec); + if (score > maxVal) + { + maxVal = score; + m_posIndex = t_vec[0]; + m_index = k; + } + } + + //Mat imgMatchRet; + //int m_index = roiCandidateMatch(vecImg, imgTemplate); + //matchTemplate(vecImg[nIndex], imgTemplate, imgMatchRet, CV_TM_CCORR_NORMED); + //Point pt3; + // double v3 = luffy_math::getMinMaxData(imgMatchRet, luffy_math::emDataMax, &pt3); + float nPos = m_posIndex + detectedOffset.at(m_index) - nOffset - imgTemplate.cols / 2.0; + paramOut.dAngle = fmod(nPos, (double)paramIn.nMaxAngle); + //paramOut.dScore = disVal; + paramOut.dScore = maxVal / 100.0; + } + //} + } + else { + qDebug() << "bar check is failed"; + paramOut.dAngle = 3610; + paramOut.dScore = 0; + } + } + + } + + if (paramOut.dScore < paramIn.dScoreThres / 100.0 ) + { + paramOut.nErrorType += 8; + } + + paramOut.bIsFind = true; + return true; +} + +void ValveDetector::drawResult(Mat &img, InputParam ¶mIn, OutputParam ¶mOut) +{ + if (img.empty()) { + return; + } + + QString strObj = paramIn.strObj; + QString str = "type: " + (strObj.isEmpty() ? "no type" : strObj); + putText(img, str.toLatin1().data(), Point(10, 100), 3, 3, LP_COLOR_RED, 3); + + QString strAngle; + if (!paramOut.bIsFind) { + strAngle = "result: can not find valve"; + } + else { + strAngle = "result: " + QString::number(paramOut.dAngleRes, 'f', 2); + } + putText(img, strAngle.toLatin1().data(), Point(10, 200), 3, 3, LP_COLOR_RED, 3); + + QString strScore; + QString strComp = ">"; + if ((paramOut.nErrorType & 0x08) || (paramOut.nErrorType & 0x16)) { + strComp = "<"; + } + + strScore = "score=" + QString::number((paramOut.dScore)*100.0, 'f', 2) + "%" + strComp + QString::number(paramIn.dScoreThres, 'f', 2) + "%"; + putText(img, strScore.toLatin1().data(), Point(10, 400), 3, 3, LP_COLOR_RED, 3); + + str = "time: " + QString::number((int)paramOut.dTime) + "ms"; + putText(img, str.toLatin1().data(), Point(10, 300), 3, 3, LP_COLOR_RED, 3); + + str = "errorType: " + QString::number(paramOut.nErrorType); + putText(img, str.toLatin1().data(), Point(10, 500), 3, 3, LP_COLOR_RED, 3); + + if (paramOut.flag == 1) + { + str = "Attention: center need to be ccalibrated"; + putText(img, str.toLatin1().data(), Point(10, 600), 3, 3, LP_COLOR_RED, 3); + } + if (paramOut.nErrorType & 0x16) { + strComp = ">"; + } + else + { + strComp = "<"; + } + if (paramOut.showMatchScore >= 0) + { + str = "model judge score = " + QString::number(paramOut.showMatchScore, 'f', 4) + strComp + QString::number(paramIn.cMatchScore, 'f', 4); + putText(img, str.toLatin1().data(), Point(10, 700), 3, 3, LP_COLOR_RED, 3); + } + + if (paramOut.bIsFind) { + //= paramIn.nMaxAngle ? 0 : paramOut.dAngle; + int tmpX = paramIn.ptCenter.x + paramIn.fValveDis * luffy_base::luffy_triangle::getCos(paramIn.nMaxAngle, angle); + int tmpY = paramIn.ptCenter.y - paramIn.fValveDis * luffy_base::luffy_triangle::getSin(paramIn.nMaxAngle, angle); + Point ptValve(tmpX, tmpY); + cv::line(img, paramIn.ptCenter, ptValve, LP_COLOR_RED, 2); + + cv::circle(img, ptValve, paramIn.fValveWidth, LP_COLOR_RED, 2); + cv::circle(img, ptValve, 3, LP_COLOR_BLUE, 3); + } + cv::circle(img, paramIn.ptCenter, 3, LP_COLOR_BLUE, 2); + if (paramIn.nCenterAlg == 1) + { + cv::circle(img, paramIn.originalPoint, 3, LP_COLOR_GREEN, 2); + } + //imwrite("C:\\Users\\Administrator\\Desktop\\1\\1.bmp", img); +} + + +double ValveDetector::ruleData(double dAngle, int nType) +{ + if (0 != nType) { + dAngle = 361; + } + if (dAngle < 0) { + dAngle += 360.0; + } + // + int r = rand() % 100; + double dr = r / 4000.0; + dAngle += dr; + if (dAngle >= 359.99 && dAngle < 360.0) + { + dAngle += 0.01; + } + if (dAngle < 361.0 && dAngle >= 360.0) + { + dAngle -= 360; + } + return dAngle; +} + +QString ValveDetector::genResultTip(QString str, int nType) +{ + if (nType & 0x0001) { + // no image + str += "no image; "; + } + if (nType & 0x0002) { + // no obj + str += "no obj; "; + } + if (nType & 0x0004) { + // lost calibrate info + str += "no cali info; "; + } + if (nType & 0x0008) { + // less than score th + str += "less than scoreTh; "; + } + if (nType &0x0010) + { + str += "model is not matched; "; + } + return str; +} + +cv::Point2f ValveDetector::getCenter(Mat & imgSrc, Point2f pt, InputParam ¶mIn) +{ + if (0 == paramIn.nCenterAlg) { + return pt; + } + Mat imgBinary; + int nOffset = 80; //need + Mat imgRoi; + imgSrc(Rect(pt.x - nOffset, pt.y - nOffset, 2 * nOffset, 2 * nOffset)).copyTo(imgRoi); + cv::threshold(imgRoi, imgBinary, 40, 255.0, THRESH_BINARY_INV); + vector> con; + Rect rect = Rect(0, 0, imgBinary.cols, imgBinary.rows); + if (rect.width > imgBinary.cols || rect.height > imgBinary.rows) + return pt; + + cv::rectangle(imgBinary, rect, Scalar(255), 1); + cv::findContours(imgBinary.clone(), con, RETR_EXTERNAL, CHAIN_APPROX_NONE); + bool bFind = false; + Point2f ptNew; + for (int i = 0; i < con.size(); i++) { + const vector& c = con.at(i); + if (c.size() < 20) { + continue; + } + Rect rt = boundingRect(c); + if (abs(rt.width - rt.height) > 5) { + continue; + } + int nArea = luffy_blob::getArea(imgBinary.size(), c); + double r = (rt.width + rt.height) / 4.0; + double d = nArea / r /r; + if (d < 2.5) { + continue; + } + bFind = true; + ptNew.x = rt.x + rt.width / 2.0 + pt.x - nOffset; + ptNew.y = rt.y + rt.height / 2.0 + pt.y - nOffset; + } + + if (bFind) { + return ptNew; + } + return pt; +} + +bool ValveDetector::saveResult(Mat &img, InputParam ¶mIn, OutputParam ¶mOut, QString modelStr) +{ + return true; +/* if (0 == paramOut.nErrorType) { + return true; + } + QString strName = ""; + strName += "time" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + "error=" + QString::number(paramOut.nErrorType); + strName += ".bmp"; + QString strPath = qApp->applicationDirPath() + "//errorImage//"; + QString str = strPath + modelStr + "\\"; + QDir fileInfo(strPath); + if (fileInfo.exists()) + { + QDir errorFile(str); + if (!errorFile.exists()) + { + fileInfo.mkdir(str); + } + } + strName = str + strName; + bool bSave = cv::imwrite(strName.toLocal8Bit().data(), img); + qDebug() << "save error image:" << bSave; + return true;*/ +} + +void ValveDetector::drawToImage(Mat &img, InputParam ¶mIn, OutputParam ¶mOut) +{ + if (img.empty()) + { + return; + } + QString strObj = paramIn.strObj; + QString str = "type: " + (strObj.isEmpty() ? "no type" : strObj); + putText(img, str.toLatin1().data(), Point(10, 100), 3, 3, LP_COLOR_RED, 3); + + QString strAngle; + if (!paramOut.bIsFind) { + strAngle = "result: can not find valve"; + } + else { + strAngle = "result: " + QString::number(paramOut.dAngleRes, 'f', 2); + } + putText(img, strAngle.toLatin1().data(), Point(10, 200), 3, 3, LP_COLOR_RED, 3); + + QString strScore; + QString strComp = ">"; + if (paramOut.nErrorType & 0x08) { + strComp = "<"; + } + + strScore = "score=" + QString::number((paramOut.dScore)*100.0, 'f', 2) + "%" + strComp + QString::number(paramIn.dScoreThres, 'f', 2) + "%"; + putText(img, strScore.toLatin1().data(), Point(10, 400), 3, 3, LP_COLOR_RED, 3); + + str = "time: " + QString::number((int)paramOut.dTime) + "ms"; + putText(img, str.toLatin1().data(), Point(10, 300), 3, 3, LP_COLOR_RED, 3); + + str = "errorType: " + QString::number(paramOut.nErrorType); + putText(img, str.toLatin1().data(), Point(10, 500), 3, 3, LP_COLOR_RED, 3); + + if (paramOut.bIsFind) { + // mRImgVec; + vector mDisValVec; + + float mStartAngle, mEndAngle; +}; + +class ImageCompareModelInvoker : public cv::ParallelLoopBody +{ +public: + ImageCompareModelInvoker(Mat &templ, void* pData) + : m_pData(pData), temp(templ) + {} +private: + void *m_pData; + Mat temp; + virtual void operator() (const cv::Range& range) const; +};*/ + + + + +#endif //LP_VALVE_DETECTOR_H \ No newline at end of file diff --git a/tpvs17/valveDetector/valveDetector.vcxproj b/tpvs17/valveDetector/valveDetector.vcxproj new file mode 100644 index 0000000..6a6dba0 --- /dev/null +++ b/tpvs17/valveDetector/valveDetector.vcxproj @@ -0,0 +1,174 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE} + Qt4VSv1.0 + valveDetector + 10.0.16299.0 + + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>12.0.30501.0 + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(ProjectName) + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(ProjectName) + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + UNICODE;WIN32;WIN64;QT_CORE_LIB;ALGO_LIB;QT_GUI_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;.\..\..\..\tadpole\include;.\..\..\3part\opencv2.4.9\include;.\..\..\3part\opencv2.4.9\include\opencv;.\..\..\3part\opencv2.4.9\include\opencv2;.\..\..\..\Cyclops\include;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(SolutionDir)..\runner13\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\..\Cyclops\3rd\nlopt\x86;.\..\..\3part\opencv2.4.9\x86\vc12\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Widgetsd.lib;opencv_core249d.lib;opencv_imgproc249d.lib;opencv_highgui249d.lib;luffyd.lib;Qt5Guid.lib;Cyclopsd.lib;libnlopt-0.lib;opencv_nonfree249d.lib;opencv_objdetect249d.lib;opencv_video249d.lib;opencv_ml249d.lib;opencv_features2d249d.lib;opencv_flann249d.lib;opencv_calib3d249d.lib;%(AdditionalDependencies) + + + + + _UNICODE;ALGO_LIB;QT_CORE_LIB;QT_GUI_LIB;UNICODE;WIN32;WIN64;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;.\..\..\3part\tadpole\include\tpBase;.\..\..\3part\opencv3.4.1\include;.\..\..\3part\opencv3.4.1\include\opencv;.\..\..\3part\opencv3.4.1\include\opencv2;.\..\..\..\Cyclops\include;.\..\..\3part\Cyclops\include;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(SolutionDir)..\runner17\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\3part\opencv3.4.1\x64\vc15\lib;..\..\3part\Cyclops\lib;..\..\3part\Cyclops\3rd\nlopt;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Widgetsd.lib;Qt5Guid.lib;Cyclopsd.lib;luffyd.lib;opencv_world341d.lib;libnlopt-0.lib;%(AdditionalDependencies) + MachineX64 + /SUBSYSTEM:WINDOWS + + + + + UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;ALGO2_LIB;QT_GUI_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;.\..\..\..\tadpole\include;.\..\..\3part\opencv2.4.9\include;.\..\..\3part\opencv2.4.9\include\opencv;.\..\..\3part\opencv2.4.9\include\opencv2;.\..\..\..\Cyclops\include;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) + + MultiThreadedDLL + true + + + Windows + $(SolutionDir)..\runner13\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\..\Cyclops\3rd\nlopt\x86;.\..\..\3part\opencv2.4.9\x86\vc12\lib;%(AdditionalLibraryDirectories) + true + qtmain.lib;Qt5Core.lib;Qt5Widgets.lib;opencv_core249.lib;opencv_imgproc249.lib;opencv_highgui249.lib;luffy.lib;Qt5Gui.lib;cyclops.lib;libnlopt-0.lib;opencv_nonfree249.lib;opencv_objdetect249.lib;opencv_video249.lib;opencv_ml249.lib;opencv_features2d249.lib;opencv_flann249.lib;opencv_calib3d249.lib;%(AdditionalDependencies) + true + + + + + _UNICODE;ALGO2_LIB;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_NO_DEBUG;UNICODE;WIN32;WIN64;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;.\..\..\3part\tadpole\include\tpBase;.\..\..\3part\opencv3.4.1\include;.\..\..\3part\opencv3.4.1\include\opencv;.\..\..\3part\opencv3.4.1\include\opencv2;.\..\..\..\Cyclops\include;.\..\..\3part\Cyclops\include;%(AdditionalIncludeDirectories) + + + MultiThreadedDLL + true + + + Windows + $(SolutionDir)..\runner17\algorithmLib\$(TargetName)$(TargetExt) + $(QTDIR)\lib;$(OutDir);..\..\3part\opencv3.4.1\x64\vc15\lib;..\..\3part\Cyclops\lib;..\..\3part\Cyclops\3rd\nlopt;%(AdditionalLibraryDirectories) + true + qtmain.lib;Qt5Core.lib;Qt5Widgets.lib;Qt5Gui.lib;Cyclops.lib;luffy.lib;opencv_world341.lib;libnlopt-0.lib;%(AdditionalDependencies) + true + MachineX64 + /SUBSYSTEM:WINDOWS + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/valveDetector/valveDetector.vcxproj.filters b/tpvs17/valveDetector/valveDetector.vcxproj.filters new file mode 100644 index 0000000..6eb1cde --- /dev/null +++ b/tpvs17/valveDetector/valveDetector.vcxproj.filters @@ -0,0 +1,68 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;cxx;c;def + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C} + ts + false + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Translation Files + + + \ No newline at end of file diff --git a/tpvs17/wheel.sln b/tpvs17/wheel.sln index 16c6143..a962a32 100644 --- a/tpvs17/wheel.sln +++ b/tpvs17/wheel.sln @@ -23,6 +23,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lpbengine", "lpbengine\lpbe EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lpdesigner", "lpdesigner\lpdesigner.vcxproj", "{616EB73F-66E3-46FF-B423-1A5B7E6AAB8B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "caliCenter", "caliCenter\caliCenter.vcxproj", "{C87504ED-3FD2-4539-AD1F-CF56BDE735FE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "caliValve", "caliValve\caliValve.vcxproj", "{E2DA7636-5531-47F1-ADE1-E5DD6E19154A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "valveDetector", "valveDetector\valveDetector.vcxproj", "{2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -95,12 +101,32 @@ Global {616EB73F-66E3-46FF-B423-1A5B7E6AAB8B}.Release|x64.ActiveCfg = Release|x64 {616EB73F-66E3-46FF-B423-1A5B7E6AAB8B}.Release|x64.Build.0 = Release|x64 {616EB73F-66E3-46FF-B423-1A5B7E6AAB8B}.Release|x86.ActiveCfg = Release|x64 + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE}.Debug|x64.ActiveCfg = Debug|x64 + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE}.Debug|x64.Build.0 = Debug|x64 + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE}.Debug|x86.ActiveCfg = Debug|x64 + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE}.Release|x64.ActiveCfg = Release|x64 + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE}.Release|x64.Build.0 = Release|x64 + {C87504ED-3FD2-4539-AD1F-CF56BDE735FE}.Release|x86.ActiveCfg = Release|x64 + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A}.Debug|x64.ActiveCfg = Debug|x64 + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A}.Debug|x64.Build.0 = Debug|x64 + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A}.Debug|x86.ActiveCfg = Debug|x64 + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A}.Release|x64.ActiveCfg = Release|x64 + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A}.Release|x64.Build.0 = Release|x64 + {E2DA7636-5531-47F1-ADE1-E5DD6E19154A}.Release|x86.ActiveCfg = Release|x64 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Debug|x64.ActiveCfg = Debug|x64 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Debug|x64.Build.0 = Debug|x64 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Debug|x86.ActiveCfg = Debug|Win32 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Debug|x86.Build.0 = Debug|Win32 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Release|x64.ActiveCfg = Release|x64 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Release|x64.Build.0 = Release|x64 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Release|x86.ActiveCfg = Release|Win32 + {2EDE9385-9EB0-4A22-9E27-B68D89C8E0BE}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - Qt5Version = qt5.9.4-msvc2017-x64 SolutionGuid = {CD365F32-5EAC-4A16-AD47-BFB1D8E5511A} + Qt5Version = qt5.9.4-msvc2017-x64 EndGlobalSection EndGlobal