Mat img = Mat::zeros(100, 100, CV_8UC3);
Mat pat = Mat::zeros(10, 10, CV_8UC3);
Mat msk = Mat::zeros(10, 10, CV_8UC1);
line(img, Point(10, 10), Point(90, 90), Scalar(255, 255, 255));
line(pat, Point(0, 0), Point(10, 10), Scalar(255, 255, 255));
line(msk, Point(3, 3), Point(7, 7), Scalar(255, 255, 255));
Mat res = Mat();
imwrite("msk-befor.png", msk);
matchTemplate(img, pat, res, TM_CCOEFF_NORMED, msk);
imwrite("msk-after.png", msk);
imwrite("img.png", img);
imwrite("pat.png", pat);
msk-befor.png
没关系,这是我的意图。
但是,msk-befor.png
是空的、黑色的。
这正常吗?或者这是一个错误?我预计掩模图像只是输入数据,不会在模板匹配中被修改。
最佳答案
看来您在 OpenCV 中发现了一个错误...
mask 参数的类型是 InputArray
,并且未记录 mask 可以通过 matchTemplate
修改。
OpenCV是一个开源软件,因此我们可以遵循源代码(我使用的是4.7.0版本)。
我们可以在 source code 中找到该问题:
源文件:sources/modules/imgproc/src/templmatch.cpp
函数:static void matchTemplateMask(InputArray _img, InputArray _templ, OutputArray _result, int method, InputArray _mask )
。
源代码行:
Mat img = _img.getMat(), templ = _templ.getMat(), mask = _mask.getMat();
if (mask.depth() == CV_8U)
{
// To keep compatibility to other masks in OpenCV: CV_8U masks are binary masks
threshold(mask, mask, 0/*threshold*/, 1.0/*maxVal*/, THRESH_BINARY);
mask.convertTo(mask, CV_32F);
}
如您所见,阈值函数修改掩码
矩阵。
原始 255
值在阈值处理后转换为 1
。
OpenCV 4.4 版本中插入了 threshold
代码(错误)。
作为解决方法,我们可以保存 msk*255
:imwrite("msk-after.png", msk*255);
我们还可以在执行 matchTemplate
之前将原始 msk
复制到临时掩码。
关于opencv - 为什么模板匹配后掩模图像消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75700158/