我想与面具进行模板匹配。通常,通过将图像从空间域转换为频域,可以更快地进行模板匹配。但是,如果我想用面具执行相同的操作,我可以申请任何方法吗?我使用的是opencv c ++。 opencv中是否有任何匹配函数用于此任务?
我目前的方法:
Bitwise Xor Image A&图B带面具。
计算非零像素。
使用此计数填充结果矩阵。
搜索maxi-ma。
我现在猜测的参数很少:
如果匹配率低于25%,则跳过磁贴位置。
如果之前的Tile匹配小于50%,则跳过Tile位置。
我的问题:是否有任何算法可以进行此匹配?有没有可以加速这个过程的数学运算?
答案 0 :(得分:0)
使用二进制图像,您可以直接使用HU-Moments和Mahalanobis距离来查找图像A是否与图像B相似。如果距离趋于0,则图像相同。
当然你也可以使用功能探测器,所以看匹配什么,但对于像这样的图像,HU Moments或Features探测器会给出大致相同的结果,但是HU Moments更有效。
使用findContours,您可以提取白星内的黑色区域并填充它们,以使图像A =图像B。
其他方法:在蒙版上使用findContours并将结果应用于图像A(提取感兴趣区域),您可以提取星内的内容并计算您有多少黑色像素(不匹配的像素)。
答案 1 :(得分:0)
我有同样的要求,我尝试过几乎相同的方式。如图所示,我想要匹配城堡。城堡有不同的盾牌图像和可变长度的氏族名称以及草背景(此图像来自游戏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
请给我声誉,所以我可以发布图片。 :)