我有同样的要求,我尝试了几乎相同的方法。如图所示,我想匹配城堡。城堡有不同的盾牌图像和可变长度的氏族名称以及草背景(此图像来自游戏 Clash of Clans)。正常的 opencv matchTemplate 不起作用。所以我自己写。
我按照 matchTemplate 的方式创建结果图像,但使用不同的算法。
核心思想是统计掩码下匹配的像素。代码如下,很简单。
这工作正常,但时间成本很高。如您所见,它花费了 457 毫秒。
现在我正在优化。
源图像和模板图像都是CV_8U3C,掩码图像是CV_8U。匹配一个通道就可以了。它速度更快,但成本仍然很高。
Mat tmp(matTempl.cols, matTempl.rows, matTempl.type());
int matchCount = 0;
float maxVal = 0;
double areaInvert = 1.0 / countNonZero(matMask);
for (int j = 0; j < resultRows; j++)
{
float* data = imgResult.ptr<float>(j);
for (int i = 0; i < resultCols; i++)
{
Mat matROI(matSource, Rect(i, j, matTempl.cols, matTempl.rows));
tmp.setTo(Scalar(0));
bitwise_xor(matROI, matTempl, tmp);
bitwise_and(tmp, matMask, tmp);
data[i] = 1.0f - float(countNonZero(tmp) * areaInvert);
if (data[i] > matchingDegree)
{
SRect rc;
rc.left = i;
rc.top = j;
rc.right = i + imgTemplate.cols;
rc.bottom = j + imgTemplate.rows;
rcOuts.push_back(rc);
if ( data[i] > maxVal)
{
maxVal = data[i];
maxIndex = rcOuts.size() - 1;
}
if (++matchCount == maxMatchs)
{
Log_Warn("Too many matches, stopped at: " << matchCount);
return true;
}
}
}
}
它说我没有足够的声誉来发布图片....
http://i.stack.imgur.com/mJrqU.png
新增:
我通过使用关键点成功地优化了算法。计算所有点是成本,但只计算服务器关键点更快。看图,成本大大降低,现在是7ms左右。
我还是不能发图,请访问:http://i.stack.imgur.com/ePcD9.png
请给我声望,以便我发布图片。 :)