diff --git a/src/algorithm/AlgorithmFluorescence.cpp b/src/algorithm/AlgorithmFluorescence.cpp index c2b7b0f..ba7b797 100644 --- a/src/algorithm/AlgorithmFluorescence.cpp +++ b/src/algorithm/AlgorithmFluorescence.cpp @@ -246,7 +246,6 @@ QString CAlgorithmFluorescence::bestMatch(const QMap* mod return bestName; } - int CAlgorithmFluorescence::IImageAnalysis(class IImageObject* pImgObj, TP_ALGORITHM_OPTION* pOpt, class IDetectorEngine* pDE) { QMutexLocker locker(&mutex); @@ -281,7 +280,7 @@ int CAlgorithmFluorescence::IImageAnalysis(class IImageObject* pImgObj, TP_ALGOR Mat matBack = getBackGroundImage(pImgObj, bReload);//获取背景图 Mat matMatch;//装载抠图后的图像 if (IsCutedImg == 0){ - if (matSrc.size().height != matBack.size().height || matSrc.size().width != matBack.size().width) + if (bUseBackground == true && (matSrc.size().height != matBack.size().height || matSrc.size().width != matBack.size().width)) { rltMap.insert("error", 0); pImgObj->IVariantMapToUI(rltMap); @@ -297,7 +296,12 @@ int CAlgorithmFluorescence::IImageAnalysis(class IImageObject* pImgObj, TP_ALGOR else{ matMatch = matSrc; } - + if (matMatch.empty()) + { + rltMap.insert("noCircle", 0); + pImgObj->IVariantMapToUI(rltMap); + return 0; + } //Mat matMatch = ImageProcess::findCircleObject(matSrc, matBack, 15, NULL/* &lCircle*/); //double dDiameter = dD2H * matMatch.rows; double dDiameter = dD2H * lCircle.fRadius * 2; @@ -325,7 +329,11 @@ int CAlgorithmFluorescence::IImageAnalysis(class IImageObject* pImgObj, TP_ALGOR pResult->m_dScore = dValue; } } - else { + //else { + //} + else if (matMatch.empty()) + { + } qDebug() << "pull result"; pResult->m_pixSrc = QtCVUtils::cvMatToQPixmap(matSrc);//!>原图像发送值UI 用于保存备份和调试 diff --git a/src/algorithm/ImageProcess.cpp b/src/algorithm/ImageProcess.cpp index 62d66ff..da4420b 100644 --- a/src/algorithm/ImageProcess.cpp +++ b/src/algorithm/ImageProcess.cpp @@ -40,7 +40,7 @@ Mat findEdge2(const Mat &Src) filter2D(Src, ret, CV_8UC1, kernel); return ret; } -#define REAIZE 1 +#define REAIZE 2 cv::Mat ImageProcess::findCircleObject(const Mat &src, const Mat& backgroundImg, bool useBackgroundFlag, int nThres /*= 20*/, luffy_base::luffyCircle *pCircle /*= NULL*/) { #ifdef MOTO_DETECT//摩轮型号识别抠图算法 @@ -101,6 +101,15 @@ cv::Mat ImageProcess::findCircleObject(const Mat &src, const Mat& backgroundImg, //float fScale = src.cols / ALG_RESIZE_IMAGE_WIDTH; //pCircle->fRadius = hight*1.0 / fScale; pCircle->fRadius = radius * REAIZE; + + //2021-05-10 增加图像大小判断 对超过900像素的图像进行再一次压缩 + if (cutMat.cols >= 900 || cutMat.rows >= 900) + { + Mat newCutImg; + cv::resize(cutMat, newCutImg, cv::Size(cutMat.cols / REAIZE, cutMat.rows / REAIZE)); + pCircle->fRadius = pCircle->fRadius / REAIZE; + return newCutImg; + } return cutMat; } } @@ -239,13 +248,14 @@ cv::Mat ImageProcess::findCircleObject(const Mat &src, const Mat& backgroundImg, if (src.empty() || backgroundImg.empty() || src.rows < 500) { return Mat(); } + bool findFlag = false; /*第一阶梯找圆*/ assert(backgroundImg.type() == CV_8UC1); Mat detectImg; cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE)); int bBaseX = detectImg.cols; int bBaseY = detectImg.rows; - Mat upLight_Img = detectImg + 1.5*detectImg;//20200423 修改 对图像进行叠加,增强目标亮度 + Mat upLight_Img = detectImg + 1.5 * detectImg;//20200423 修改 对图像进行叠加,增强目标亮度 blur(upLight_Img, upLight_Img, Size(3, 3)); EDCircles edcircles(upLight_Img); vector EDCircle = edcircles.getCircles(); @@ -257,7 +267,7 @@ cv::Mat ImageProcess::findCircleObject(const Mat &src, const Mat& backgroundImg, int startY = EDCircle[i].center.y - EDCircle[i].r; if (startX < 0 || startY <0) continue; - if (EDCircle[i].center.x + EDCircle[i].r>bBaseX || EDCircle[i].center.y + EDCircle[i].r>bBaseY) + if (EDCircle[i].center.x + EDCircle[i].r> bBaseX || EDCircle[i].center.y + EDCircle[i].r>bBaseY) continue; if (EDCircle[i].r > maxR) { diff --git a/src/tpMain/CamConfig.cpp b/src/tpMain/CamConfig.cpp index abfb11f..d0d2821 100644 --- a/src/tpMain/CamConfig.cpp +++ b/src/tpMain/CamConfig.cpp @@ -16,7 +16,7 @@ CamConfig::~CamConfig() void CamConfig::init() { QString fileCam = m_appRoot + WHEEL_CAMERACONFIG_FILE; - QJsonObject jsMyself = QZkJsonParser::ReadJsonAuto(fileCam); + QJsonObject jsMyself = QZkJsonParser::ReadJsonAuto(fileCam); QJsonObject m_deviceObj = jsMyself.value("devices").toObject(); QJsonObject::iterator pObj = m_deviceObj.begin(); QString objname = pObj.key(); diff --git a/src/tpMain/qipconfigdlg.h b/src/tpMain/qipconfigdlg.h index 09286a7..7b381eb 100644 --- a/src/tpMain/qipconfigdlg.h +++ b/src/tpMain/qipconfigdlg.h @@ -11,7 +11,7 @@ struct IPConfig QString m_ClientAddress; int m_ClientPort; IPConfig(){ - m_TcpAddress = "192.168.0.240"; + m_TcpAddress = "192.168.0.110"; m_ClientAddress = "192.168.0.119"; m_TcpPort = 2000; m_ClientPort = 2000; diff --git a/tpvs17/tpMain/QCamSettingDlg.cpp b/tpvs17/tpMain/QCamSettingDlg.cpp index b7a0ae4..bda0e37 100644 --- a/tpvs17/tpMain/QCamSettingDlg.cpp +++ b/tpvs17/tpMain/QCamSettingDlg.cpp @@ -144,7 +144,6 @@ Q_SLOT void QCamSettingDlg::onButtonClicked() } else if ("m_pbOpen" == strObj) { - if (m_pCoreCtl) { if (tr("关闭") == ui.m_pbOpen->text()) diff --git a/tpvs17/tpMain/QSystemSettingDlg.cpp b/tpvs17/tpMain/QSystemSettingDlg.cpp index 56bc95e..cbe29bd 100644 --- a/tpvs17/tpMain/QSystemSettingDlg.cpp +++ b/tpvs17/tpMain/QSystemSettingDlg.cpp @@ -271,7 +271,7 @@ void QSystemSettingDlg::addPicRoot(QTreeWidget *pTreewidget, QString strName) m_useBackground->setText(tr("使用背景图")); m_useBackground->setObjectName("m_useBackground"); connect(m_useBackground, SIGNAL(stateChanged(int)), this, SLOT(onCheckstateChanged(int))); - m_useBackground->setChecked(DetectState::instance()->saveBad == (int)true); + m_useBackground->setChecked(DetectState::instance()->m_UseBackground == (int)true); QCheckBox *m_ResAll2A = new QCheckBox; m_ResAll2A->setText(tr("轮毂全去A通道")); diff --git a/tpvs17/tpMain/lpMainWin.cpp b/tpvs17/tpMain/lpMainWin.cpp index eff155b..d71782a 100644 --- a/tpvs17/tpMain/lpMainWin.cpp +++ b/tpvs17/tpMain/lpMainWin.cpp @@ -18,9 +18,12 @@ #include "saveimgthread.h" #include "lpGlobalData.h" #include "qpulpewidget.h" -#define VERSION_HUB "3.0.0.1" -#define VERSION_ALG "3.0.0.1" -#define UPDATE_TIME "2021-02-20" + +#include "QZkJsonParser.h" + +#define VERSION_HUB "3.0.0.2" +#define VERSION_ALG "3.0.0.2" +#define UPDATE_TIME "2021-05-08" #pragma execution_character_set("utf-8") lpMainWin::lpMainWin(QWidget *parent) @@ -251,6 +254,10 @@ lpMainWin::lpMainWin(QWidget *parent) m_timerID = startTimer(1000); //m_PulseTimer.start(1000); + + connect(this, SIGNAL(sgAutoExposure()), this, SLOT(onAutoExposure())); + QString strPath = QApplication::applicationDirPath(); + readExposureTimeConfig(strPath); } lpMainWin::~lpMainWin() @@ -395,6 +402,8 @@ bool lpMainWin::onInitCoreCtrl() FuncCallBack_StrImg strImgfunc = std::bind(&lpMainWin::INewCameraImage, this, std::placeholders::_1, std::placeholders::_2); m_pCoreCtrl->IRegisterImageCallBack(strImgfunc); + + m_camKey = m_pCoreCtrl->ICameraKeys().first(); return true; } @@ -523,18 +532,97 @@ void lpMainWin::INewCameraImage(const QString& camKey, QImage img) /*多线程发送算法结果*/ void lpMainWin::IVariantMapToUI(const QString& camKey, const QVariantMap& vMap) -{ +{ emit(sgShowImgState(tr("显示识别结果"))); + Result2Ui *pResult = (Result2Ui*)vMap.value("result").toLongLong(); + if (pResult == nullptr) + { + pResult = new Result2Ui(); + } + + // 当没抠出轮毂和NG时自动调整曝光时间重新拍照,最多调整的次数为5次 + if (m_autoExposureSwitch) + { + if (vMap.contains("noCircle")) + { + if (m_exposureTimeCount == 0) + { + int curExposure = getCurExposureTime(); + if (curExposure != m_exposureTimeArray[0]) + { + emit(sgShowMsgdlg(tr("当前曝光时间未识别到轮毂!"))); + emit sgAutoExposure(); + m_exposureTimeCount++; + delete pResult; + return; + } + } + m_exposureTimeCount++; + if (m_exposureTimeCount >= m_exposureTimeArray.size()) + { + // m_exposureTimeCount = 0; + emit(sgShowMsgdlg(tr("调整5次曝光时间后依然未能识别到轮毂!"))); + } + else + { + emit(sgShowMsgdlg(tr("当前曝光时间未识别到轮毂!"))); + emit sgAutoExposure(); + delete pResult; + return; + } + } + bool ngFlag = (pResult->m_strModel.isEmpty()) && (m_exposureTimeCount < m_exposureTimeArray.size()); + if (ngFlag) + { + if (m_exposureTimeCount == 0) + { + int curExposure = getCurExposureTime(); + if (curExposure != m_exposureTimeArray[0]) + { + emit(sgShowMsgdlg(tr("当前曝光时间未识别到轮毂!"))); + emit sgAutoExposure(); + pResult->m_strModel = "NG"; + saveImage(pResult); + m_exposureTimeCount++; + delete pResult; + return; + } + } + m_exposureTimeCount++; + if (m_exposureTimeCount >= m_exposureTimeArray.size()) + { + // m_exposureTimeCount = 0; + emit(sgShowMsgdlg(tr("调整5次曝光时间后依然未能识别到轮毂!"))); + } + else + { + emit(sgShowMsgdlg(tr("当前曝光时间未识别到轮毂!"))); + emit sgAutoExposure(); + pResult->m_strModel = "NG"; + saveImage(pResult); + delete pResult; + return; + } + } + } if (vMap.contains("error")) { + m_exposureTimeCount = 0; emit(sgShowMsgdlg(tr("相机图像和背景图不一样,请更换检测背景!"))); return; } - Result2Ui *pResult = (Result2Ui*)vMap.value("result").toLongLong(); onShowResult(pResult); if (m_pDebugDlg) { m_pDebugDlg->onShowResult(pResult); } + saveImage(pResult); + if (m_autoExposureSwitch) + { + m_exposureTimeCount = 0; + int exp = m_exposureTimeArray[m_exposureTimeCount]; + m_pCoreCtrl->ISetExposureTime(m_camKey, exp); + } + // m_pUi->processResult(pResult); static int ErrorNum = 0; if (m_pNet) { @@ -561,6 +649,7 @@ void lpMainWin::IVariantMapToUI(const QString& camKey, const QVariantMap& vMap) SendResultBee(LIGHT_BEE, 3); } } + if (DetectState::instance()->m_SendDetectStr2Net) SendResultStr2PLC(pResult);//发送检测结果字符到PLC if (DetectState::instance()->m_SendChannelRes2COM) @@ -569,7 +658,6 @@ void lpMainWin::IVariantMapToUI(const QString& camKey, const QVariantMap& vMap) SendResultChannel2PLC(pResult);//发送检测结果通道到PLC m_pCtrl->saveResult(pResult); - saveImage(pResult); delete pResult; } @@ -1134,7 +1222,11 @@ Q_SLOT void lpMainWin::onTrigRecv(int m_value) //if (DetectState::instance()->m_CameraTrigeType == 0)//软件触发模式 { if (DetectState::instance()->IsDetect == true) { - //CC_Action(CC_AC_NEXT); +// if (m_exposureTimeCount != 0) +// { +// m_pCoreCtrl->ISetExposureTime(m_camKey, m_exposureTimeArray[m_exposureTimeCount]); +// } + onTriggerCam(); qWarning() << "soft ctrol camera :" << "(" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz") << ")"; } @@ -1484,6 +1576,8 @@ void lpMainWin::saveImage(Result2Ui* pRes) if (pRes == nullptr) return; qDebug() << "satrt tread save Image"; + QString curExposureTimeStr = QString::number(getCurExposureTime()); + QDir testDir; bool IsTestDir = testDir.exists(DetectState::instance()->m_SaveImgDirPath); if (!IsTestDir) @@ -1520,6 +1614,7 @@ void lpMainWin::saveImage(Result2Ui* pRes) QString errorSourceDir = fileSavePath + "\\Error"; filename += QString("_%1_%2_").arg((int)pRes->m_dThickness).arg((int)pRes->m_dDiameter); filename += QDateTime::currentDateTime().toString("hhmmsszzz"); + filename = filename + "_" + curExposureTimeStr; if (DetectState::instance()->saveBad == 1) { errorSourceDir += "\\Source"; QString resultpath = errorSourceDir + "\\" + filename + ".png"; @@ -1573,4 +1668,48 @@ Q_SLOT void lpMainWin::onwfPulseTimer() // frame.data2 = 0; // frame.data8 = 50; // SendDataToCom(0x43, frame); +} + +bool lpMainWin::readExposureTimeConfig(const QString& strPath) +{ + QString filePath = strPath + "\\config\\exposure.json"; + QJsonObject jsonObj = QZkJsonParser::ReadJsonAuto(filePath); + if (jsonObj.empty()) + { + qDebug() << "Json file parsing failed!"; + return false; + } + + QJsonObject exposureObj = jsonObj.value("exposureTime").toObject(); + + QJsonObject::iterator objIterEnd = exposureObj.end(); + for (auto objIter = exposureObj.begin(); objIter != objIterEnd; objIter++) + { + int exposureTime = objIter.value().toInt(); + m_exposureTimeArray.emplace_back(exposureTime); + } + m_autoExposureSwitch = jsonObj.value("switch").toInt(); + + return true; +} + +int lpMainWin::getCurExposureTime() +{ + TP_CAMERA_OPTION camOpt; + m_pCoreCtrl->IGetCameraOption(m_camKey, camOpt); + return camOpt.exposure; +} + +Q_SLOT void lpMainWin::onAutoExposure() +{ + if (m_exposureTimeCount >= 0) + { + if (m_exposureTimeArray.size() <= m_exposureTimeCount) + return; + int exp = m_exposureTimeArray[m_exposureTimeCount]; + qDebug() << "exp:" << exp; + m_pCoreCtrl->ISetExposureTime(m_camKey, exp); + } + + onTriggerCam(); } \ No newline at end of file diff --git a/tpvs17/tpMain/lpMainWin.h b/tpvs17/tpMain/lpMainWin.h index 4142100..6caf0ac 100644 --- a/tpvs17/tpMain/lpMainWin.h +++ b/tpvs17/tpMain/lpMainWin.h @@ -61,12 +61,12 @@ signals: void operate(); void sgNetData(int, QVariantMap); - + void sgAutoExposure(); private: Q_SLOT void onLogInOut(QString strName, int level, int state); Q_SLOT void onActionClicked(); Q_SLOT void onButtonClicked(); - + Q_SLOT void onAutoExposure(); protected: bool onInitCoreCtrl(); @@ -189,6 +189,16 @@ private: int m_timerID{ 0 };//定时器 更新状态栏信息 quint64 m_runTimeCount{ 0 }; + +private: + int m_exposureTimeCount{ 0 }; + QString m_camKey; + std::vector m_exposureTimeArray; + bool m_autoExposureSwitch{false}; + + bool readExposureTimeConfig(const QString& strPath); + int getCurExposureTime(); + }; #endif