|
|
|
|
|
#pragma execution_character_set("utf-8")
|
|
|
|
|
|
#include "CategoryMatcher.h"
|
|
|
|
|
|
|
|
|
|
|
|
CategoryMatcher::CategoryMatcher(QObject *parent)
|
|
|
|
|
|
: QObject(parent)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_ilmatch = ILMatchPtr(__uuidof(LMatch));
|
|
|
|
|
|
m_ilmatchF = ILMatchPtr(__uuidof(LMatch));
|
|
|
|
|
|
m_display = ILDisplayPtr(__uuidof(LDisplay));
|
|
|
|
|
|
initILMatchParam(QCoreApplication::applicationDirPath() + MATCHER_CONFIG);
|
|
|
|
|
|
setILMatch(m_matchParam);
|
|
|
|
|
|
qDebug() << "init CategoryMatcher successed";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CategoryMatcher::~CategoryMatcher()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CategoryMatcher::initILMatchParam(const QString& path)
|
|
|
|
|
|
{
|
|
|
|
|
|
QString fileMyself = path;
|
|
|
|
|
|
QFile file(fileMyself);
|
|
|
|
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>";
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
QByteArray arr = file.readAll();
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
if (arr.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>";
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QJsonParseError err;
|
|
|
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(arr, &err);
|
|
|
|
|
|
if (doc.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << err.errorString(); //<2F><>ӡʧ<D3A1><CAA7><EFBFBD><EFBFBD>Ϣ
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QJsonObject jsMyself = doc.object();
|
|
|
|
|
|
QJsonObject MatchParamObj = jsMyself.value("MatchParam").toObject();
|
|
|
|
|
|
if (!MatchParamObj.isEmpty()) {
|
|
|
|
|
|
m_matchParam.MaxCount = MatchParamObj.value("MaxCount").toInt();
|
|
|
|
|
|
m_matchParam.ScaleTolerance = MatchParamObj.value("ScaleTolerance").toInt();
|
|
|
|
|
|
m_matchParam.AngleTolerance = MatchParamObj.value("AngleTolerance").toInt();
|
|
|
|
|
|
m_matchParam.AcceptScore = MatchParamObj.value("ScoreThresh").toInt();
|
|
|
|
|
|
m_matchParam.StrictScore = MatchParamObj.value("StrictScore").toBool();
|
|
|
|
|
|
m_matchParam.UseCache = MatchParamObj.value("UseCache").toBool();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CategoryMatcher::setILMatch(const MatchParam& matchParam)
|
|
|
|
|
|
{
|
|
|
|
|
|
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, ILImagePtr image)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::pair<int, QVector<ILMatchResultPtr>> templateLevelAndvecMatchRltPtr;
|
|
|
|
|
|
bool bRlt = smokeMatch(typeNo, image, templateLevelAndvecMatchRltPtr);
|
|
|
|
|
|
drawImage(image, templateLevelAndvecMatchRltPtr);
|
|
|
|
|
|
return bRlt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CategoryMatcher::smokeMatch(const QString& typeNo, const cv::Mat& inputMat, cv::Mat& rltMat)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (inputMat.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << "inputMat is empty";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
ILImagePtr ilImgGray(__uuidof(LImage));
|
|
|
|
|
|
cv::Mat imgMatGray;
|
|
|
|
|
|
ensureGrayImg(inputMat, imgMatGray);
|
|
|
|
|
|
qDebug() << "ensureGrayImg OK!";
|
|
|
|
|
|
ilImgGray->SetImageData(imgMatGray.cols, imgMatGray.rows, (void*)imgMatGray.data, imgMatGray.step, 0);
|
|
|
|
|
|
qDebug() << "LPV SetImageData OK!";
|
|
|
|
|
|
std::pair<int, QVector<ILMatchResultPtr>> templateLevelAndvecMatchRltPtr;
|
|
|
|
|
|
bool bRlt = smokeMatch(typeNo, ilImgGray, templateLevelAndvecMatchRltPtr);
|
|
|
|
|
|
drawImage(imgMatGray, rltMat, templateLevelAndvecMatchRltPtr);
|
|
|
|
|
|
return bRlt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CategoryMatcher::smokeMatch(const QString& typeNo, const ILImagePtr ilImgPtr,
|
|
|
|
|
|
std::pair<int, QVector<ILMatchResultPtr>>& templateLevelAndvecMatchRltPtr)
|
|
|
|
|
|
{
|
|
|
|
|
|
TemplateObject templateObj;
|
|
|
|
|
|
QString templateImgFolderPath = TYPE_TEMPLATE_PATH;
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܴ<EFBFBD><DCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣺֮ǰ<D6AE><C7B0>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><C6A1><EFBFBD><EFBFBD><D7BA><EFBFBD>˱<EFBFBD><CBB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD><DDA1><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
|
// ģ<><C4A3><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-ģ<><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
// ģ<><C4A3><EFBFBD><EFBFBD><EFBFBD>룺ģ<EBA3BA><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+ģ<><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
// ģ<><C4A3><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>1Ϊ<31><CEAA>ģ<EFBFBD>壨ģ<E5A3A8><C4A3><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>50%<25><><EFBFBD><EFBFBD>2ΪСģ<D0A1><C4A3>
|
|
|
|
|
|
// <20><><EFBFBD>磺1<E7A3BA><31>ģ<EFBFBD><C4A3><EFBFBD>ĵ<EFBFBD>1<EFBFBD><31>ģ<EFBFBD>壺11
|
|
|
|
|
|
// <20>л<EFBFBD>Ӳ310102<30><32>2<EFBFBD><32>ģ<EFBFBD><C4A3><EFBFBD>ĵ<EFBFBD>1<EFBFBD><31>ģ<EFBFBD>壺310102-21
|
|
|
|
|
|
QString folderPath = QString("%1\\%2").arg(templateImgFolderPath).arg(typeNo);
|
|
|
|
|
|
if (getTemplateImgFileInfo(folderPath, templateObj))
|
|
|
|
|
|
{
|
|
|
|
|
|
qDebug() << "Get TemplateImg OK!";
|
|
|
|
|
|
|
|
|
|
|
|
QVector<double> vecMatchSroreMax;
|
|
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRltsMax;
|
|
|
|
|
|
QList<int> keys = templateObj.uniqueKeys();
|
|
|
|
|
|
int templateLevel = keys.length();
|
|
|
|
|
|
qDebug() << "templateLevel = " << templateLevel;
|
|
|
|
|
|
templateLevelAndvecMatchRltPtr.first = templateLevel;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬģ<CDAC>弶<EFBFBD><E5BCB6>
|
|
|
|
|
|
for each (int level in keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
QVector<double> vecMatchSrore;
|
|
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRlts;
|
|
|
|
|
|
QMap<QString, int> strScoreMap = templateObj.value(level);
|
|
|
|
|
|
for (QMap<QString, int>::iterator it = strScoreMap.begin(); it != strScoreMap.end(); ++it)
|
|
|
|
|
|
{
|
|
|
|
|
|
//<2F><>Ҫ<EFBFBD><D2AA>֤û<D6A4><C3BB>1<EFBFBD><31>ģ<EFBFBD>壬<EFBFBD><E5A3AC><EFBFBD><EFBFBD>2<EFBFBD><32>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ͼ
|
|
|
|
|
|
|
|
|
|
|
|
QString templateImgPath = it.key();
|
|
|
|
|
|
ILImagePtr ilTemplatePtr(__uuidof(LImage));
|
|
|
|
|
|
ilTemplatePtr->Load(templateImgPath.toStdString().c_str());
|
|
|
|
|
|
if (ilTemplatePtr->Void())
|
|
|
|
|
|
{
|
|
|
|
|
|
QString outStr = templateImgPath + " is empty!";
|
|
|
|
|
|
qDebug() << outStr;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
ILMatchResultsPtr matchResults, matchResultsF;
|
|
|
|
|
|
|
|
|
|
|
|
if (level == 1) // <20><>ģ<EFBFBD><C4A3>
|
|
|
|
|
|
{
|
|
|
|
|
|
ILImageArithmPtr imgArithm(__uuidof(LImageArithm));
|
|
|
|
|
|
imgArithm->Resize(ilImgPtr, 0.5, 0.5, LPVInterNearest, img);
|
|
|
|
|
|
}
|
|
|
|
|
|
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 = matchResults->Count() + matchResultsF->Count();
|
|
|
|
|
|
|
|
|
|
|
|
if (objCount > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
double valueMaxScore = -1;
|
|
|
|
|
|
ILMatchResultPtr matchRltPtr;
|
|
|
|
|
|
int indexMaxScore = 0;
|
|
|
|
|
|
QVector<double> matchSrore;
|
|
|
|
|
|
|
|
|
|
|
|
// ģ<>巽<EFBFBD><E5B7BD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת180<38><30>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
auto maxPos = std::max_element(matchSrore.begin(), matchSrore.end());
|
|
|
|
|
|
valueMaxScore = *maxPos;
|
|
|
|
|
|
indexMaxScore = maxPos - matchSrore.begin();
|
|
|
|
|
|
|
|
|
|
|
|
vecMatchSrore.push_back(valueMaxScore);
|
|
|
|
|
|
if (indexMaxScore < matchResults->Count())
|
|
|
|
|
|
{
|
|
|
|
|
|
vecMatchRlts.push_back(matchResults->Item(indexMaxScore));
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
vecMatchRlts.push_back(matchResultsF->Item(indexMaxScore - matchResults->Count()));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
if (vecMatchSrore.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// ѡ<><D1A1><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
auto maxMatchScorePos = std::max_element(vecMatchSrore.begin(), vecMatchSrore.end());
|
|
|
|
|
|
auto maxIndex = maxMatchScorePos - vecMatchSrore.begin();
|
|
|
|
|
|
vecMatchSroreMax.push_back(*maxMatchScorePos);
|
|
|
|
|
|
vecMatchRltsMax.push_back(vecMatchRlts.at(maxIndex));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (vecMatchSroreMax.isEmpty() || (vecMatchSroreMax.length() != templateLevel))
|
|
|
|
|
|
{
|
|
|
|
|
|
QString outStr = QString("Level: %1 match failed!")
|
|
|
|
|
|
.arg(vecMatchSroreMax.length() + 1);
|
|
|
|
|
|
qDebug() << outStr;
|
|
|
|
|
|
templateLevelAndvecMatchRltPtr.second = vecMatchRltsMax;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
templateLevelAndvecMatchRltPtr.second = vecMatchRltsMax;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
QString outStr = QString("%1 find templateImage failed!").arg(folderPath);
|
|
|
|
|
|
qDebug() << outStr;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool CategoryMatcher::getTemplateImgFileInfo(const QString& folderPath, TemplateObject& templateObject)
|
|
|
|
|
|
{
|
|
|
|
|
|
templateObject.clear();
|
|
|
|
|
|
QDir fileDir(folderPath);
|
|
|
|
|
|
if (!fileDir.exists())
|
|
|
|
|
|
{
|
|
|
|
|
|
qWarning() << folderPath << " is not exist";
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
for each(QFileInfo imgFileInfo in fileDir.entryInfoList(QDir::Filter::Files | QDir::NoDotAndDotDot))
|
|
|
|
|
|
{
|
|
|
|
|
|
QString fileName = imgFileInfo.fileName();
|
|
|
|
|
|
|
|
|
|
|
|
if (fileName.endsWith(".png") || fileName.endsWith(".PNG")
|
|
|
|
|
|
|| fileName.endsWith(".BMP") || fileName.endsWith(".bmp")
|
|
|
|
|
|
|| fileName.endsWith(".jpeg") || fileName.endsWith(".JPEG")
|
|
|
|
|
|
|| fileName.endsWith(".jpg") || fileName.endsWith(".JPG"))
|
|
|
|
|
|
{
|
|
|
|
|
|
QStringList strList = imgFileInfo.baseName().split("_");
|
|
|
|
|
|
|
|
|
|
|
|
QString templateImgPath = imgFileInfo.filePath(); //<2F><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ȡʧ<C8A1><CAA7>
|
|
|
|
|
|
int level = strList.last().mid(0, 1).toInt();
|
|
|
|
|
|
templateObject[level].insert(templateImgPath, 70);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////֮ǰ<D6AE><C7B0>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD>磺templateImg/51520312/template_0101_65
|
|
|
|
|
|
//if (strList.first() == "template" && strList.length() == 3)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// int scoreThresh = strList.last().toInt();
|
|
|
|
|
|
// QString templateImgPath = imgFileInfo.filePath(); //<2F><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ȡʧ<C8A1><CAA7>
|
|
|
|
|
|
// std::pair<QString, int> imgScorePair(templateImgPath, scoreThresh);
|
|
|
|
|
|
// QString serialNum = strList[1];
|
|
|
|
|
|
// if (serialNum.length() == 4)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// int level = serialNum.mid(0, 2).toInt();
|
|
|
|
|
|
// templateObject[level].insert(templateImgPath, scoreThresh);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (templateObject.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CategoryMatcher::drawImage(ILImagePtr image, std::pair<int, QVector<ILMatchResultPtr>> templateLevelAndvecMatchRltPtr)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (image->Height == 0 || image->Width == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
int level = 1;
|
|
|
|
|
|
int templateLevel = templateLevelAndvecMatchRltPtr.first;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRlts = templateLevelAndvecMatchRltPtr.second;
|
|
|
|
|
|
QString rltStr;
|
|
|
|
|
|
cv::Scalar textColor(0, 255, 0);
|
|
|
|
|
|
if (!vecMatchRlts.isEmpty() && (vecMatchRlts.length() == templateLevel))
|
|
|
|
|
|
{
|
|
|
|
|
|
rltStr = QString("Match successful! Total level: %1").arg(templateLevel);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
textColor = cv::Scalar(0, 0, 255);
|
|
|
|
|
|
rltStr = QString("Match failed! Total level: %1").arg(templateLevel);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><>Display<61>ϻ<EFBFBD><CFBB><EFBFBD>ͼ<EFBFBD><CDBC>+<2B><><EFBFBD><EFBFBD>
|
|
|
|
|
|
m_display->SetImage(image);
|
|
|
|
|
|
m_display->AddObject(rltStr,0);
|
|
|
|
|
|
|
|
|
|
|
|
rltStr.clear();
|
|
|
|
|
|
for each(ILMatchResultPtr matchRltPtr in vecMatchRlts)
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣺<EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>ģ<EFBFBD>壬ֱ<E5A3AC><D6B1><EFBFBD><EFBFBD>2<EFBFBD><32>ģ<EFBFBD><C4A3>
|
|
|
|
|
|
double score = matchRltPtr->GetScore();
|
|
|
|
|
|
rltStr.append(QString(" Level %1 score: %2").arg(level++).arg(score));
|
|
|
|
|
|
//<2F><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>⡪<EFBFBD><E2A1AA><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ƥ<EFBFBD><C6A5><EFBFBD>ĵõ<C4B5><C3B5>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>λ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
m_display->AddObject(matchRltPtr, LPVPatDrawFlags::LPVPatDrawBoundingRect | LPVPatDrawFlags::LPVPatDrawCenter);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!rltStr.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
m_display->AddObject(rltStr, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CategoryMatcher::saveResultsImage(const QString& filePath)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::wstring str = filePath.toStdWString();
|
|
|
|
|
|
m_display->SaveSceneToFile(str.c_str(), 1, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CategoryMatcher::drawImage(const cv::Mat& imgMatSrc, cv::Mat& rltCvImg,
|
|
|
|
|
|
std::pair<int, QVector<ILMatchResultPtr>> templateLevelAndvecMatchRltPtr)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (imgMatSrc.empty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
ensureColorBGRImg(imgMatSrc, rltCvImg);
|
|
|
|
|
|
int level = 1;
|
|
|
|
|
|
int templateLevel = templateLevelAndvecMatchRltPtr.first;
|
|
|
|
|
|
QVector<ILMatchResultPtr> vecMatchRltPtr = templateLevelAndvecMatchRltPtr.second;
|
|
|
|
|
|
QString rltStr;
|
|
|
|
|
|
cv::Scalar textColor(0, 255, 0);
|
|
|
|
|
|
if (!vecMatchRltPtr.isEmpty() && (vecMatchRltPtr.length() == templateLevel))
|
|
|
|
|
|
{
|
|
|
|
|
|
rltStr = QString("Match successful! Total level: %1").arg(templateLevel);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
textColor = cv::Scalar(0, 0, 255);
|
|
|
|
|
|
rltStr = QString("Match failed! Total level: %1").arg(templateLevel);
|
|
|
|
|
|
}
|
|
|
|
|
|
int fontFace = cv::FONT_HERSHEY_DUPLEX;
|
|
|
|
|
|
double fontScale = 2.5;
|
|
|
|
|
|
int textThickness = 2;
|
|
|
|
|
|
int baseLine = 0;
|
|
|
|
|
|
int startX = 50;
|
|
|
|
|
|
int startY = 100;
|
|
|
|
|
|
cv::Size textSize = cv::getTextSize(rltStr.toStdString(), fontFace, fontScale, textThickness, &baseLine);
|
|
|
|
|
|
cv::putText(rltCvImg, rltStr.toStdString(), cv::Point(startX, startY),
|
|
|
|
|
|
fontFace, fontScale, textColor, textThickness);
|
|
|
|
|
|
rltStr.clear();
|
|
|
|
|
|
for each(ILMatchResultPtr matchRltPtr in vecMatchRltPtr)
|
|
|
|
|
|
{
|
|
|
|
|
|
double score = matchRltPtr->GetScore();
|
|
|
|
|
|
rltStr.append(QString(" Level %1 score: %2").arg(level++).arg(score));
|
|
|
|
|
|
ILRectPtr ilRectPtr = matchRltPtr->GetRect();
|
|
|
|
|
|
ILPointsPtr ilPointsPtr = ilRectPtr->GetPoints();
|
|
|
|
|
|
cv::Point2f vertices[4];
|
|
|
|
|
|
int count = ilPointsPtr->Count();
|
|
|
|
|
|
if (count != 4)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
ILPointPtr ilPointPtr = ilPointsPtr->Item(i);
|
|
|
|
|
|
vertices[i] = cv::Point2f(ilPointPtr->GetX(), ilPointPtr->GetY());
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
cv::line(rltCvImg, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), 8);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!rltStr.isEmpty())
|
|
|
|
|
|
{
|
|
|
|
|
|
cv::putText(rltCvImg, rltStr.toStdString(),
|
|
|
|
|
|
cv::Point(startX, startY + textSize.height + 20),
|
|
|
|
|
|
fontFace, fontScale, textColor, textThickness);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ensureGrayImg(const cv::Mat& img, cv::Mat& gray)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (img.channels() == 3)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (img.depth() == CV_8U) {
|
|
|
|
|
|
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
cv::Mat channels[3];
|
|
|
|
|
|
split(img, channels);
|
|
|
|
|
|
gray = channels[2] * 0.299 + channels[1] * 0.587 + channels[0] * 0.114;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (img.channels() == 4)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (img.depth() == CV_8U) {
|
|
|
|
|
|
cvtColor(img, gray, cv::COLOR_BGRA2GRAY);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
cv::Mat channels[4];
|
|
|
|
|
|
cv::split(img, channels);
|
|
|
|
|
|
gray = channels[2] * 0.299 + channels[1] * 0.587 + channels[0] * 0.114;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (img.channels() == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
gray = img;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_ASSERTE(false && "unsupported image conversion.");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool ensureColorBGRImg(const cv::Mat& img, cv::Mat& color)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (img.channels() == 3) {
|
|
|
|
|
|
color = img;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (img.channels() == 4) {
|
|
|
|
|
|
if (img.depth() == CV_8U) {
|
|
|
|
|
|
cvtColor(img, color, cv::COLOR_BGRA2BGR);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
static int from4_to3[] = { 0,0,1,1,2,2 };
|
|
|
|
|
|
if (color.cols != img.cols || color.rows != img.rows || color.type() != CV_MAKE_TYPE(img.depth(), 3))
|
|
|
|
|
|
color = cv::Mat(img.rows, img.cols, CV_MAKE_TYPE(img.depth(), 3));
|
|
|
|
|
|
mixChannels(img, color, from4_to3, 3);
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (img.channels() == 1) {
|
|
|
|
|
|
if (img.depth() == CV_8U) {
|
|
|
|
|
|
cvtColor(img, color, cv::COLOR_GRAY2BGR);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
static int from1_to3[] = { 0,0,0,1,0,2 };
|
|
|
|
|
|
if (color.cols != img.cols || color.rows != img.rows || color.type() != CV_MAKE_TYPE(img.depth(), 3))
|
|
|
|
|
|
color = cv::Mat(img.rows, img.cols, CV_MAKE_TYPE(img.depth(), 3));
|
|
|
|
|
|
mixChannels(img, color, from1_to3, 3);
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
_ASSERTE(false && "unsupported image conversion.");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|