opencv - 为什么模板匹配后掩模图像消失?

标签 opencv

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/

相关文章:

opencv - 廉价的立体视觉相机+ opencv

python - python中没有highgui

android - OpenCV imwrite,颜色错误: Which argument for convertTo/cvColor do I use?

java - 如何展平2个不同的图像层?

c++ - 跨平台截图

node.js - return process.dlopen(module, path._makeLong(filename));

c++ - 无需读取整个图像的 OpenCV 图像尺寸

opencv - OpenCV 中的 cornerSubPix : purpose and application

java - OpenCV VideoWriter for Java 在 MacOS 上无法按预期工作

c++ - 如何在 C++ OpenCV 中将图像 (Mat) 转换为 inputArray?