diff --git a/README.md b/README.md index 33b5148..3300ffd 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,7 @@ Identify the types and quantities of smoke boxes 这是基于南京烟草版本,把扫码器和传感器等功能做一个是否加载的选项: +1、2D模板匹配算法修改 + + + diff --git a/runner17/Release/config/match.json b/runner17/Release/config/match.json index 026488f..6d96c51 100644 --- a/runner17/Release/config/match.json +++ b/runner17/Release/config/match.json @@ -1,11 +1,10 @@ { "MatchParam": { "MaxCount": 10, - "ScaleTolerance": 25, - "AngleTolerance": 180, - "GrayValueWeight": 40, - "StrictScore": true, - "ScoreThresh": 50, - "UseTotalThresh": true + "ScaleTolerance": 50, + "AngleTolerance": 10, + "StrictScore": true, + "ScoreThresh": 70, + "UseCache": true } } diff --git a/runner17/Release/smokeBox.exe b/runner17/Release/smokeBox.exe index 97c23c0..0facfd9 100644 Binary files a/runner17/Release/smokeBox.exe and b/runner17/Release/smokeBox.exe differ diff --git a/src/CategoryMatcher.cpp b/src/CategoryMatcher.cpp index e1ca336..d8fff55 100644 --- a/src/CategoryMatcher.cpp +++ b/src/CategoryMatcher.cpp @@ -4,7 +4,8 @@ CategoryMatcher::CategoryMatcher(QObject *parent) : QObject(parent) { - m_ilmatchPtr = ILMatchPtr(__uuidof(LMatch)); + m_ilmatch = ILMatchPtr(__uuidof(LMatch)); + m_ilmatchF = ILMatchPtr(__uuidof(LMatch)); initILMatchParam(QCoreApplication::applicationDirPath() + MATCHER_CONFIG); setILMatch(m_matchParam); qDebug() << "init CategoryMatcher successed"; @@ -47,23 +48,28 @@ void CategoryMatcher::initILMatchParam(const QString& path) m_matchParam.ScaleTolerance = MatchParamObj.value("ScaleTolerance").toInt(); m_matchParam.AngleTolerance = MatchParamObj.value("AngleTolerance").toInt(); m_matchParam.AcceptScore = MatchParamObj.value("ScoreThresh").toInt(); - m_matchParam.GrayValueWeight = MatchParamObj.value("GrayValueWeight").toInt(); m_matchParam.StrictScore = MatchParamObj.value("StrictScore").toBool(); - m_bUseTotalThresh = MatchParamObj.value("UseTotalThresh").toBool(); + m_matchParam.UseCache = MatchParamObj.value("UseCache").toBool(); } } void CategoryMatcher::setILMatch(const MatchParam& matchParam) { - m_ilmatchPtr->MaxCount = m_matchParam.MaxCount; - m_ilmatchPtr->ScaleTolerance = m_matchParam.ScaleTolerance; - m_ilmatchPtr->AngleTolerance = m_matchParam.AngleTolerance; - m_ilmatchPtr->GrayValueWeight = m_matchParam.GrayValueWeight; - m_ilmatchPtr->StrictScore = m_matchParam.StrictScore; - if (m_bUseTotalThresh) - { - m_ilmatchPtr->AcceptScore = m_matchParam.AcceptScore; - } + m_ilmatch->MaxCount = m_matchParam.MaxCount; + m_ilmatch->ScaleTolerance = m_matchParam.ScaleTolerance; + m_ilmatch->AngleTolerance = m_matchParam.AngleTolerance; + m_ilmatch->StrictScore = m_matchParam.StrictScore; + m_ilmatch->UseCache = m_matchParam.UseCache; + m_ilmatch->AcceptScore = m_matchParam.AcceptScore; + + + m_ilmatchF->MaxCount = m_matchParam.MaxCount; + m_ilmatchF->ScaleTolerance = m_matchParam.ScaleTolerance; + m_ilmatchF->AngleTolerance = m_matchParam.AngleTolerance; + m_ilmatchF->StrictScore = m_matchParam.StrictScore; + m_ilmatchF->UseCache = m_matchParam.UseCache; + m_ilmatchF->AcceptScore = m_matchParam.AcceptScore; + } bool CategoryMatcher::smokeMatch(const QString& typeNo, const cv::Mat& inputMat, cv::Mat& rltMat) @@ -88,37 +94,31 @@ bool CategoryMatcher::smokeMatch(const QString& typeNo, const cv::Mat& inputMat, bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPtr, std::pair>& templateLevelAndvecMatchRltPtr) { - QVector vecMatchRltPtrMax; TemplateObject templateObj; QString templateImgFolderPath = TYPE_TEMPLATE_PATH; QString folderPath = QString("%1\\%2").arg(templateImgFolderPath).arg(typeNo); if (getTemplateImgFileInfo(folderPath, templateObj)) { qDebug() << "Get TemplateImg OK!"; + QVector vecMatchSroreMax; - ILMatchResultsPtr matchResultsPtr; + QVector vecMatchRltsMax; QList keys = templateObj.uniqueKeys(); int templateLevel = keys.length(); - qDebug() << "templateLevel = "<< templateLevel; + qDebug() << "templateLevel = " << templateLevel; templateLevelAndvecMatchRltPtr.first = templateLevel; + + // ͬģ弶 for each (int level in keys) { QVector vecMatchSrore; - QVector vecMatchRltPtr; + QVector vecMatchRlts; QMap strScoreMap = templateObj.value(level); for (QMap::iterator it = strScoreMap.begin(); it != strScoreMap.end(); ++it) { + //Ҫ֤û1ģ壬2ģͼ + QString templateImgPath = it.key(); - int scoreThresh; - if (!m_bUseTotalThresh) - { - scoreThresh = it.value(); - m_ilmatchPtr->AcceptScore = scoreThresh; - } - else - { - scoreThresh = m_matchParam.AcceptScore; - } ILImagePtr ilTemplatePtr(__uuidof(LImage)); ilTemplatePtr->Load(templateImgPath.toStdString().c_str()); if (ilTemplatePtr->Void()) @@ -128,56 +128,63 @@ bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPt continue; } - bool isReduced = false; + m_ilmatch->Learn(ilTemplatePtr, nullptr); ILImagePtr img(__uuidof(LImage)); + ILImagePtr tempImage(__uuidof(LImage)); + ILImageArithmPtr imgArithmF(__uuidof(LImageArithm)); + imgArithmF->Flip(ilTemplatePtr, LPVFlipType::LPVFlipH, tempImage); + imgArithmF->Flip(tempImage, LPVFlipType::LPVFlipV, tempImage); + m_ilmatchF->Learn(tempImage, nullptr); - if ((ilTemplatePtr->Height > 100 && ilTemplatePtr->Width > 100)) - { - isReduced = true; - ILImageArithmPtr imgArithm1(__uuidof(LImageArithm)); - ILImageArithmPtr imgArithm2(__uuidof(LImageArithm)); - imgArithm1->Resize(ilTemplatePtr, 0.5, 0.5, LPVInterNearest, ilTemplatePtr); - imgArithm2->Resize(ilImgPtr, 0.5, 0.5, LPVInterNearest, img); - } + ILMatchResultsPtr matchResults, matchResultsF; - m_ilmatchPtr->DetailLevel = 0.5; - m_ilmatchPtr->Learn(ilTemplatePtr, nullptr); - // ģر࣬ƥʱ൱Ҫϸ - if (m_ilmatchPtr->GetPatFeature()->Count()>2500) + if (level == 1) // ģ { - m_ilmatchPtr->DetailLevel = 0.05; - m_ilmatchPtr->Learn(ilTemplatePtr, nullptr); + ILImageArithmPtr imgArithm(__uuidof(LImageArithm)); + imgArithm->Resize(ilImgPtr, 0.5, 0.5, LPVInterNearest, img); } - - LPVErrorCode err = m_ilmatchPtr->Match((isReduced ? img : ilImgPtr), nullptr, &matchResultsPtr); - if (err != LPVErrorCode::LPVNoError) { - continue; // match failed + LPVErrorCode err = m_ilmatch->Match((level == 1 ? img : ilImgPtr), nullptr, &matchResults); + LPVErrorCode errF = m_ilmatchF->Match((level == 1 ? img : ilImgPtr), nullptr, &matchResultsF); + if (err < LPVErrorCode::LPVNoError || errF < LPVErrorCode::LPVNoError) { + //continue; // match failed } - int objCount = matchResultsPtr->Count(); + + int objCount = matchResults->Count() + matchResultsF->Count(); + if (objCount > 0) { - double maxScore = -1; + double valueMaxScore = -1; ILMatchResultPtr matchRltPtr; int indexMaxScore = 0; - for (int i = 0; i < objCount; i++) + QVector matchSrore; + + // ģ巽ƥת180ƥһƥֵ + for (int i = 0; i < matchResults->Count(); i++) + { + matchSrore.push_back(matchResults->Item(i)->Score); + } + for (int i = 0; i < matchResultsF->Count(); i++) + { + matchSrore.push_back(matchResultsF->Item(i)->Score); + } + + //ѡߵƥ + auto maxPos = std::max_element(matchSrore.begin(), matchSrore.end()); + valueMaxScore = *maxPos; + indexMaxScore = maxPos - matchSrore.begin(); + + vecMatchSrore.push_back(valueMaxScore); + if (indexMaxScore < matchResults->Count()) { - matchRltPtr = matchResultsPtr->Item(i); - double score = matchRltPtr->GetScore(); - if (score < scoreThresh) - { - continue; - } - if (maxScore < score) - { - maxScore = score; - indexMaxScore = i; - } + vecMatchRlts.push_back(matchResults->Item(indexMaxScore)); + } + else + { + vecMatchRlts.push_back(matchResultsF->Item(indexMaxScore - matchResults->Count())); } - if (maxScore < 0) - continue; - vecMatchSrore.push_back(maxScore); - vecMatchRltPtr.push_back(matchResultsPtr->Item(indexMaxScore)); } + + } if (vecMatchSrore.isEmpty()) { @@ -185,10 +192,11 @@ bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPt } else { + // ѡģȼߵƥ auto maxMatchScorePos = std::max_element(vecMatchSrore.begin(), vecMatchSrore.end()); auto maxIndex = maxMatchScorePos - vecMatchSrore.begin(); vecMatchSroreMax.push_back(*maxMatchScorePos); - vecMatchRltPtrMax.push_back(vecMatchRltPtr.at(maxIndex)); + vecMatchRltsMax.push_back(vecMatchRlts.at(maxIndex)); } } if (vecMatchSroreMax.isEmpty() || (vecMatchSroreMax.length() != templateLevel)) @@ -196,12 +204,12 @@ bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPt QString outStr = QString("Level: %1 match failed!") .arg(vecMatchSroreMax.length() + 1); qDebug() << outStr; - templateLevelAndvecMatchRltPtr.second = vecMatchRltPtrMax; + templateLevelAndvecMatchRltPtr.second = vecMatchRltsMax; return false; } else { - templateLevelAndvecMatchRltPtr.second = vecMatchRltPtrMax; + templateLevelAndvecMatchRltPtr.second = vecMatchRltsMax; } } else diff --git a/src/CategoryMatcher.h b/src/CategoryMatcher.h index e32b53d..0719e94 100644 --- a/src/CategoryMatcher.h +++ b/src/CategoryMatcher.h @@ -32,16 +32,16 @@ struct MatchParam int MaxCount; //ƥ int ScaleTolerance; //űΧ int AngleTolerance; //ǶȷΧ - int GrayValueWeight; //ҶƥȨ int AcceptScore; //ƥֵ bool StrictScore; //ϸ + bool UseCache; //û MatchParam() { MaxCount = 10; ScaleTolerance = 20; AngleTolerance = 180; - GrayValueWeight = 40; StrictScore = true; + UseCache = true; } }; @@ -64,9 +64,9 @@ private: std::pair> templateLevelAndvecMatchRltPtr); MatchParam m_matchParam; - ILMatchPtr m_ilmatchPtr; + ILMatchPtr m_ilmatch; + ILMatchPtr m_ilmatchF; QMutex m_mutex; - bool m_bUseTotalThresh{ false }; }; bool ensureGrayImg(const cv::Mat& img, cv::Mat& gray); diff --git a/src/SmokeBoxIdentification.cpp b/src/SmokeBoxIdentification.cpp index 4a09a00..69d411a 100644 --- a/src/SmokeBoxIdentification.cpp +++ b/src/SmokeBoxIdentification.cpp @@ -50,31 +50,38 @@ SmokeBoxIdentification::SmokeBoxIdentification(QWidget *parent) connect(m_pNetControl, &NetControl::sgReceiveData, this, &SmokeBoxIdentification::onDecodeMsg, Qt::QueuedConnection); connect(this, &SmokeBoxIdentification::sgSendMsg, m_pNetControl, &NetControl::onSendMsg, Qt::QueuedConnection); + + if (m_moduleParam.CodeScan != 0) + { + QString codeFilePath = applicationDirPath + COM_CONFIG; + CodeScanStation::instance()->loadParameters(filePath); + CodeScanStation::instance()->openComs(); + } + if (m_moduleParam.Sensor != 0) { ADModule::instance()->loadParameters(filePath); filePath = applicationDirPath + COM_CONFIG; lpSerialStation::instance()->loadParameters(filePath); lpSerialStation::instance()->openComs(); - } - if (m_moduleParam.CodeScan != 0) - { - QString codeFilePath = applicationDirPath + COM_CONFIG; - CodeScanStation::instance()->loadParameters(filePath); - CodeScanStation::instance()->openComs(); + connect(lpSerialStation::instance(), &lpSerialStation::sgMonitorSensorTriggerStart, this + , &SmokeBoxIdentification::onMonitorSensorTriggerStart); + connect(lpSerialStation::instance(), &lpSerialStation::sgMonitorSensorTriggerStop, this + , &SmokeBoxIdentification::onMonitorSensorTriggerStop); + connect(lpSerialStation::instance(), &lpSerialStation::sgNewEmptyCheckResults, this + , &SmokeBoxIdentification::onSendEmptyCheckResults); } + + m_pCategoryMatcher = new CategoryMatcher(); connect(CodeScanStation::instance(), &CodeScanStation::sgNewCodeScanData, lpSerialStation::instance() , &lpSerialStation::onNewCodeScanResults); connect(this, &SmokeBoxIdentification::sgCategoryMatchFinished, this, &SmokeBoxIdentification::onNumStatistic); - connect(lpSerialStation::instance(), &lpSerialStation::sgMonitorSensorTriggerStart, this - , &SmokeBoxIdentification::onMonitorSensorTriggerStart); - connect(lpSerialStation::instance(), &lpSerialStation::sgMonitorSensorTriggerStop, this - , &SmokeBoxIdentification::onMonitorSensorTriggerStop); - connect(lpSerialStation::instance(), &lpSerialStation::sgNewEmptyCheckResults, this - , &SmokeBoxIdentification::onSendEmptyCheckResults); + + + connect(this, &SmokeBoxIdentification::sgControlSideLight, lpSerialStation::instance() , &lpSerialStation::onControlSideLight); connect(this, &SmokeBoxIdentification::sgStartEmptyPlaceCheck, lpSerialStation::instance() diff --git a/tpvs17/SmokeBoxIdentification/log/log-2024-01-08.log b/tpvs17/SmokeBoxIdentification/log/log-2024-01-08.log new file mode 100644 index 0000000..af70f17 --- /dev/null +++ b/tpvs17/SmokeBoxIdentification/log/log-2024-01-08.log @@ -0,0 +1,38 @@ +Debug | 2024-01-08 14:07:21 һ | Decode smokeInfo from "D:/Code/Logistics/smokeboxidentification/tpvs17/../runner17/Release\\user\\smokeInfo.xlsx" successed +Debug | 2024-01-08 14:07:21 һ | "D:/Code/Logistics/smokeboxidentification/tpvs17/../runner17/Release\\templateNum" has not folder +Warning | 2024-01-08 14:07:22 һ | Do not found any device! +Warning | 2024-01-08 14:07:22 һ | SerialNumber: "00J50359922" init failed +Warning | 2024-01-08 14:07:22 һ | Do not found any device! +Warning | 2024-01-08 14:07:22 һ | SerialNumber: "00J50359927" init failed +Warning | 2024-01-08 14:07:22 һ | Do not found any device! +Warning | 2024-01-08 14:07:22 һ | SerialNumber: "00J50359938" init failed +Warning | 2024-01-08 14:07:22 һ | Do not found any device! +Warning | 2024-01-08 14:07:22 һ | SerialNumber: "00J50359923" init failed +Warning | 2024-01-08 14:07:22 һ | QObject::moveToThread: Cannot move objects with a parent +Warning | 2024-01-08 14:07:22 һ | Do not found any device! +Warning | 2024-01-08 14:07:22 һ | SerialNumber: "00J50359918" init failed +Warning | 2024-01-08 14:07:22 һ | Do not found any device! +Warning | 2024-01-08 14:07:22 һ | SerialNumber: "00J50359945" init failed +Debug | 2024-01-08 14:07:22 һ | m_vecPCamera size: 0 +Debug | 2024-01-08 14:07:30 һ | init CategoryMatcher successed +Debug | 2024-01-08 14:07:33 һ | delete netControl +Debug | 2024-01-08 14:07:33 һ | delete netControl finished +Debug | 2024-01-08 20:26:54 һ | Decode smokeInfo from "D:/Code/Logistics/smokeboxidentification/tpvs17/../runner17/Release\\user\\smokeInfo.xlsx" successed +Debug | 2024-01-08 20:26:54 һ | "D:/Code/Logistics/smokeboxidentification/tpvs17/../runner17/Release\\templateNum" has not folder +Warning | 2024-01-08 20:26:55 һ | Do not found any device! +Warning | 2024-01-08 20:26:55 һ | SerialNumber: "00J50359922" init failed +Warning | 2024-01-08 20:26:55 һ | Do not found any device! +Warning | 2024-01-08 20:26:55 һ | SerialNumber: "00J50359927" init failed +Warning | 2024-01-08 20:26:55 һ | Do not found any device! +Warning | 2024-01-08 20:26:55 һ | SerialNumber: "00J50359938" init failed +Warning | 2024-01-08 20:26:55 һ | Do not found any device! +Warning | 2024-01-08 20:26:55 һ | SerialNumber: "00J50359923" init failed +Warning | 2024-01-08 20:26:55 һ | QObject::moveToThread: Cannot move objects with a parent +Warning | 2024-01-08 20:26:55 һ | Do not found any device! +Warning | 2024-01-08 20:26:55 һ | SerialNumber: "00J50359918" init failed +Warning | 2024-01-08 20:26:55 һ | Do not found any device! +Warning | 2024-01-08 20:26:55 һ | SerialNumber: "00J50359945" init failed +Debug | 2024-01-08 20:26:55 һ | m_vecPCamera size: 0 +Debug | 2024-01-08 20:26:57 һ | init CategoryMatcher successed +Debug | 2024-01-08 20:26:59 һ | delete netControl +Debug | 2024-01-08 20:26:59 һ | delete netControl finished