|
|
|
@ -4,7 +4,8 @@
|
|
|
|
CategoryMatcher::CategoryMatcher(QObject *parent)
|
|
|
|
CategoryMatcher::CategoryMatcher(QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
: QObject(parent)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_ilmatchPtr = ILMatchPtr(__uuidof(LMatch));
|
|
|
|
m_ilmatch = ILMatchPtr(__uuidof(LMatch));
|
|
|
|
|
|
|
|
m_ilmatchF = ILMatchPtr(__uuidof(LMatch));
|
|
|
|
initILMatchParam(QCoreApplication::applicationDirPath() + MATCHER_CONFIG);
|
|
|
|
initILMatchParam(QCoreApplication::applicationDirPath() + MATCHER_CONFIG);
|
|
|
|
setILMatch(m_matchParam);
|
|
|
|
setILMatch(m_matchParam);
|
|
|
|
qDebug() << "init CategoryMatcher successed";
|
|
|
|
qDebug() << "init CategoryMatcher successed";
|
|
|
|
@ -47,23 +48,28 @@ void CategoryMatcher::initILMatchParam(const QString& path)
|
|
|
|
m_matchParam.ScaleTolerance = MatchParamObj.value("ScaleTolerance").toInt();
|
|
|
|
m_matchParam.ScaleTolerance = MatchParamObj.value("ScaleTolerance").toInt();
|
|
|
|
m_matchParam.AngleTolerance = MatchParamObj.value("AngleTolerance").toInt();
|
|
|
|
m_matchParam.AngleTolerance = MatchParamObj.value("AngleTolerance").toInt();
|
|
|
|
m_matchParam.AcceptScore = MatchParamObj.value("ScoreThresh").toInt();
|
|
|
|
m_matchParam.AcceptScore = MatchParamObj.value("ScoreThresh").toInt();
|
|
|
|
m_matchParam.GrayValueWeight = MatchParamObj.value("GrayValueWeight").toInt();
|
|
|
|
|
|
|
|
m_matchParam.StrictScore = MatchParamObj.value("StrictScore").toBool();
|
|
|
|
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)
|
|
|
|
void CategoryMatcher::setILMatch(const MatchParam& matchParam)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_ilmatchPtr->MaxCount = m_matchParam.MaxCount;
|
|
|
|
m_ilmatch->MaxCount = m_matchParam.MaxCount;
|
|
|
|
m_ilmatchPtr->ScaleTolerance = m_matchParam.ScaleTolerance;
|
|
|
|
m_ilmatch->ScaleTolerance = m_matchParam.ScaleTolerance;
|
|
|
|
m_ilmatchPtr->AngleTolerance = m_matchParam.AngleTolerance;
|
|
|
|
m_ilmatch->AngleTolerance = m_matchParam.AngleTolerance;
|
|
|
|
m_ilmatchPtr->GrayValueWeight = m_matchParam.GrayValueWeight;
|
|
|
|
m_ilmatch->StrictScore = m_matchParam.StrictScore;
|
|
|
|
m_ilmatchPtr->StrictScore = m_matchParam.StrictScore;
|
|
|
|
m_ilmatch->UseCache = m_matchParam.UseCache;
|
|
|
|
if (m_bUseTotalThresh)
|
|
|
|
m_ilmatch->AcceptScore = m_matchParam.AcceptScore;
|
|
|
|
{
|
|
|
|
|
|
|
|
m_ilmatchPtr->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)
|
|
|
|
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,
|
|
|
|
bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPtr,
|
|
|
|
std::pair<int, QVector<ILMatchResultPtr>>& templateLevelAndvecMatchRltPtr)
|
|
|
|
std::pair<int, QVector<ILMatchResultPtr>>& templateLevelAndvecMatchRltPtr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRltPtrMax;
|
|
|
|
|
|
|
|
TemplateObject templateObj;
|
|
|
|
TemplateObject templateObj;
|
|
|
|
QString templateImgFolderPath = TYPE_TEMPLATE_PATH;
|
|
|
|
QString templateImgFolderPath = TYPE_TEMPLATE_PATH;
|
|
|
|
QString folderPath = QString("%1\\%2").arg(templateImgFolderPath).arg(typeNo);
|
|
|
|
QString folderPath = QString("%1\\%2").arg(templateImgFolderPath).arg(typeNo);
|
|
|
|
if (getTemplateImgFileInfo(folderPath, templateObj))
|
|
|
|
if (getTemplateImgFileInfo(folderPath, templateObj))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
qDebug() << "Get TemplateImg OK!";
|
|
|
|
qDebug() << "Get TemplateImg OK!";
|
|
|
|
|
|
|
|
|
|
|
|
QVector<double> vecMatchSroreMax;
|
|
|
|
QVector<double> vecMatchSroreMax;
|
|
|
|
ILMatchResultsPtr matchResultsPtr;
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRltsMax;
|
|
|
|
QList<int> keys = templateObj.uniqueKeys();
|
|
|
|
QList<int> keys = templateObj.uniqueKeys();
|
|
|
|
int templateLevel = keys.length();
|
|
|
|
int templateLevel = keys.length();
|
|
|
|
qDebug() << "templateLevel = " << templateLevel;
|
|
|
|
qDebug() << "templateLevel = " << templateLevel;
|
|
|
|
templateLevelAndvecMatchRltPtr.first = templateLevel;
|
|
|
|
templateLevelAndvecMatchRltPtr.first = templateLevel;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历不同模板级别
|
|
|
|
for each (int level in keys)
|
|
|
|
for each (int level in keys)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QVector<double> vecMatchSrore;
|
|
|
|
QVector<double> vecMatchSrore;
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRltPtr;
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRlts;
|
|
|
|
QMap<QString, int> strScoreMap = templateObj.value(level);
|
|
|
|
QMap<QString, int> strScoreMap = templateObj.value(level);
|
|
|
|
for (QMap<QString, int>::iterator it = strScoreMap.begin(); it != strScoreMap.end(); ++it)
|
|
|
|
for (QMap<QString, int>::iterator it = strScoreMap.begin(); it != strScoreMap.end(); ++it)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
//需要验证没用1类模板,但有2类模板的图
|
|
|
|
|
|
|
|
|
|
|
|
QString templateImgPath = it.key();
|
|
|
|
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));
|
|
|
|
ILImagePtr ilTemplatePtr(__uuidof(LImage));
|
|
|
|
ilTemplatePtr->Load(templateImgPath.toStdString().c_str());
|
|
|
|
ilTemplatePtr->Load(templateImgPath.toStdString().c_str());
|
|
|
|
if (ilTemplatePtr->Void())
|
|
|
|
if (ilTemplatePtr->Void())
|
|
|
|
@ -128,56 +128,63 @@ bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPt
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isReduced = false;
|
|
|
|
m_ilmatch->Learn(ilTemplatePtr, nullptr);
|
|
|
|
ILImagePtr img(__uuidof(LImage));
|
|
|
|
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))
|
|
|
|
ILMatchResultsPtr matchResults, matchResultsF;
|
|
|
|
{
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_ilmatchPtr->DetailLevel = 0.5;
|
|
|
|
if (level == 1) // 大模板
|
|
|
|
m_ilmatchPtr->Learn(ilTemplatePtr, nullptr);
|
|
|
|
|
|
|
|
// 如果模板的特征点特别多,匹配时间会相当长,需要降低细节
|
|
|
|
|
|
|
|
if (m_ilmatchPtr->GetPatFeature()->Count()>2500)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_ilmatchPtr->DetailLevel = 0.05;
|
|
|
|
ILImageArithmPtr imgArithm(__uuidof(LImageArithm));
|
|
|
|
m_ilmatchPtr->Learn(ilTemplatePtr, nullptr);
|
|
|
|
imgArithm->Resize(ilImgPtr, 0.5, 0.5, LPVInterNearest, img);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LPVErrorCode err = m_ilmatch->Match((level == 1 ? img : ilImgPtr), nullptr, &matchResults);
|
|
|
|
LPVErrorCode err = m_ilmatchPtr->Match((isReduced ? img : ilImgPtr), nullptr, &matchResultsPtr);
|
|
|
|
LPVErrorCode errF = m_ilmatchF->Match((level == 1 ? img : ilImgPtr), nullptr, &matchResultsF);
|
|
|
|
if (err != LPVErrorCode::LPVNoError) {
|
|
|
|
if (err < LPVErrorCode::LPVNoError || errF < LPVErrorCode::LPVNoError) {
|
|
|
|
continue; // match failed
|
|
|
|
//continue; // match failed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int objCount = matchResultsPtr->Count();
|
|
|
|
|
|
|
|
|
|
|
|
int objCount = matchResults->Count() + matchResultsF->Count();
|
|
|
|
|
|
|
|
|
|
|
|
if (objCount > 0)
|
|
|
|
if (objCount > 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
double maxScore = -1;
|
|
|
|
double valueMaxScore = -1;
|
|
|
|
ILMatchResultPtr matchRltPtr;
|
|
|
|
ILMatchResultPtr matchRltPtr;
|
|
|
|
int indexMaxScore = 0;
|
|
|
|
int indexMaxScore = 0;
|
|
|
|
for (int i = 0; i < objCount; i++)
|
|
|
|
QVector<double> matchSrore;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模板方向的匹配结果——旋转180度匹配结果,组成一个完整的匹配结果值
|
|
|
|
|
|
|
|
for (int i = 0; i < matchResults->Count(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
matchRltPtr = matchResultsPtr->Item(i);
|
|
|
|
matchSrore.push_back(matchResults->Item(i)->Score);
|
|
|
|
double score = matchRltPtr->GetScore();
|
|
|
|
}
|
|
|
|
if (score < scoreThresh)
|
|
|
|
for (int i = 0; i < matchResultsF->Count(); i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
matchSrore.push_back(matchResultsF->Item(i)->Score);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (maxScore < score)
|
|
|
|
|
|
|
|
|
|
|
|
//选择评分最高的匹配结果
|
|
|
|
|
|
|
|
auto maxPos = std::max_element(matchSrore.begin(), matchSrore.end());
|
|
|
|
|
|
|
|
valueMaxScore = *maxPos;
|
|
|
|
|
|
|
|
indexMaxScore = maxPos - matchSrore.begin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vecMatchSrore.push_back(valueMaxScore);
|
|
|
|
|
|
|
|
if (indexMaxScore < matchResults->Count())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
maxScore = score;
|
|
|
|
vecMatchRlts.push_back(matchResults->Item(indexMaxScore));
|
|
|
|
indexMaxScore = i;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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())
|
|
|
|
if (vecMatchSrore.isEmpty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -185,10 +192,11 @@ bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
// 选择该模板等级下评分最高的匹配结果
|
|
|
|
auto maxMatchScorePos = std::max_element(vecMatchSrore.begin(), vecMatchSrore.end());
|
|
|
|
auto maxMatchScorePos = std::max_element(vecMatchSrore.begin(), vecMatchSrore.end());
|
|
|
|
auto maxIndex = maxMatchScorePos - vecMatchSrore.begin();
|
|
|
|
auto maxIndex = maxMatchScorePos - vecMatchSrore.begin();
|
|
|
|
vecMatchSroreMax.push_back(*maxMatchScorePos);
|
|
|
|
vecMatchSroreMax.push_back(*maxMatchScorePos);
|
|
|
|
vecMatchRltPtrMax.push_back(vecMatchRltPtr.at(maxIndex));
|
|
|
|
vecMatchRltsMax.push_back(vecMatchRlts.at(maxIndex));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (vecMatchSroreMax.isEmpty() || (vecMatchSroreMax.length() != templateLevel))
|
|
|
|
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!")
|
|
|
|
QString outStr = QString("Level: %1 match failed!")
|
|
|
|
.arg(vecMatchSroreMax.length() + 1);
|
|
|
|
.arg(vecMatchSroreMax.length() + 1);
|
|
|
|
qDebug() << outStr;
|
|
|
|
qDebug() << outStr;
|
|
|
|
templateLevelAndvecMatchRltPtr.second = vecMatchRltPtrMax;
|
|
|
|
templateLevelAndvecMatchRltPtr.second = vecMatchRltsMax;
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
templateLevelAndvecMatchRltPtr.second = vecMatchRltPtrMax;
|
|
|
|
templateLevelAndvecMatchRltPtr.second = vecMatchRltsMax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
|