在图像中查找图标
Finding an icon in an image
我刚刚开始学习计算机视觉,并且正在从事一个简单的项目,以在静止图像中查找基本图标。
我有一个模板图片:
和两张测试图片:
和
我使用了模板匹配(使用AForge.net,但我认为它是相同的算法
OpenCV 和 Emgu 使用的。我可能是错的,我是 CV 的新手)并发现阈值是 .80563,我会在上面两个中找到完全匹配的一个,并且在我尝试过图标不在的图像中没有匹配。
在查看每张图像中作为匹配项返回的内容之前,我以为我已经有所进展:(蓝色突出显示的方块是图像匹配的地方。)
(Correct) and (完全错误)
我意识到问题是以下任何一个或所有问题:
- 我正在寻找的图标在大小、颜色和阴影方面将相似,但不保证它们在上述任何方面都相同。 (注意:Angular 方向和比例应该保持一致。我不想要一个带有“+”的圆圈来匹配模板。我也不想要一个带有微小 "X" 的大圆圈匹配。)
- 我的模板不是正方形,我只是猜测透明像素不会包含在匹配项中。
- 考虑到上述两个问题,模板匹配可能是错误的方法。也许我需要用别的东西来做这个?
最后,我需要一些基本的帮助来了解我的匹配出了什么问题,这样我至少可以回到正确的方向。模板是否匹配正确的方法,但我需要更改某些内容?或者我是否需要查看这些库中的其他功能之一?对于这个简单的任务,OpenCV(和 EMGU)功能和 AForge.net 功能之间有很大的功能差异吗?
模板匹配在这种情况下是正确的选择,但你必须做对:
- 您的模板不符合您的要求。在你的第二张图片中,你的结果很糟糕,因为按钮的灰度值与背景中的某个地方更相似。如果要搜索白色十字,则使用白色十字作为模板,如下所示:
- 不要使用固定阈值,而是搜索最高响应点。
根据这些指南,您可以找到 按钮(红色小矩形):
这是 OpenCV (C++) 中的代码,例如:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
// Load template and image
Mat3b templ = imread("path_to_template");
Mat3b img = imread("path_to_image");
// Convert to grayscale
Mat1b img_gray;
Mat1b templ_gray;
cvtColor(img, img_gray, COLOR_BGR2GRAY);
cvtColor(templ, templ_gray, COLOR_BGR2GRAY);
// Match template
Mat1f result;
matchTemplate(img, templ, result, TM_CCOEFF_NORMED);
// Find highest response
Point maxLoc;
minMaxLoc(result, NULL, NULL, NULL, &maxLoc);
// Draw the red rectangle
rectangle(img, Rect(maxLoc, templ.size()), Scalar(0,0,255), 2);
// Show results
imshow("Result", img);
waitKey();
return 0;
}
如果您想检测只有少量变化的模式,这可能有点矫枉过正。训练 haar 级联分类器将使您能够更准确地检测此类模式,并且您不必担心阈值。
我刚刚开始学习计算机视觉,并且正在从事一个简单的项目,以在静止图像中查找基本图标。
我有一个模板图片:
和两张测试图片:
我使用了模板匹配(使用AForge.net,但我认为它是相同的算法 OpenCV 和 Emgu 使用的。我可能是错的,我是 CV 的新手)并发现阈值是 .80563,我会在上面两个中找到完全匹配的一个,并且在我尝试过图标不在的图像中没有匹配。
在查看每张图像中作为匹配项返回的内容之前,我以为我已经有所进展:(蓝色突出显示的方块是图像匹配的地方。)
我意识到问题是以下任何一个或所有问题:
- 我正在寻找的图标在大小、颜色和阴影方面将相似,但不保证它们在上述任何方面都相同。 (注意:Angular 方向和比例应该保持一致。我不想要一个带有“+”的圆圈来匹配模板。我也不想要一个带有微小 "X" 的大圆圈匹配。)
- 我的模板不是正方形,我只是猜测透明像素不会包含在匹配项中。
- 考虑到上述两个问题,模板匹配可能是错误的方法。也许我需要用别的东西来做这个?
最后,我需要一些基本的帮助来了解我的匹配出了什么问题,这样我至少可以回到正确的方向。模板是否匹配正确的方法,但我需要更改某些内容?或者我是否需要查看这些库中的其他功能之一?对于这个简单的任务,OpenCV(和 EMGU)功能和 AForge.net 功能之间有很大的功能差异吗?
模板匹配在这种情况下是正确的选择,但你必须做对:
- 您的模板不符合您的要求。在你的第二张图片中,你的结果很糟糕,因为按钮的灰度值与背景中的某个地方更相似。如果要搜索白色十字,则使用白色十字作为模板,如下所示:
- 不要使用固定阈值,而是搜索最高响应点。
根据这些指南,您可以找到 按钮(红色小矩形):
这是 OpenCV (C++) 中的代码,例如:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
// Load template and image
Mat3b templ = imread("path_to_template");
Mat3b img = imread("path_to_image");
// Convert to grayscale
Mat1b img_gray;
Mat1b templ_gray;
cvtColor(img, img_gray, COLOR_BGR2GRAY);
cvtColor(templ, templ_gray, COLOR_BGR2GRAY);
// Match template
Mat1f result;
matchTemplate(img, templ, result, TM_CCOEFF_NORMED);
// Find highest response
Point maxLoc;
minMaxLoc(result, NULL, NULL, NULL, &maxLoc);
// Draw the red rectangle
rectangle(img, Rect(maxLoc, templ.size()), Scalar(0,0,255), 2);
// Show results
imshow("Result", img);
waitKey();
return 0;
}
如果您想检测只有少量变化的模式,这可能有点矫枉过正。训练 haar 级联分类器将使您能够更准确地检测此类模式,并且您不必担心阈值。