opencv 模板匹配后掩模图像为何消失?

hfsqlsce  于 2023-03-13  发布在  其他
关注(0)|答案(1)|浏览(181)
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是空的和黑色的。
这是正常的吗?还是错误的?我预计蒙片图像只是输入数据,不会在模板匹配中修改。

4si2a6ki

4si2a6ki1#

似乎您在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);
}

如您所见,threshold函数修改了mask矩阵。
原始255值在阈值化之后被转换为1
threshold代码(错误)被插入OpenCV版本4.4。
作为解决方法,我们可以保存msk*255imwrite("msk-after.png", msk*255);
我们也可以在执行matchTemplate之前将原始的msk复制到临时掩码。

相关问题