OPENCV C - 查找图像中包含的图像
OpenCV C++ - Find an image contained within an image?
我有搜索一个小图像的代码:
:int* MyLib::MatchingMethod(int, void*)
{
/// Source image to display
img.copyTo(img_display);
/// Create the result matrix
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create(result_rows, result_cols, CV_32FC1);
match_method = 0;
/// Do the Matching and Normalize
matchTemplate(img, templ, result, match_method);
normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
/// Localizing the best match with minMaxLoc
double minVal;
double maxVal;
cv::Point minLoc;
cv::Point maxLoc;
cv::Point matchLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if (match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED)
{
matchLoc = minLoc;
}
else
{
matchLoc = maxLoc;
}
if (showOpenCVWindow) {
/// Show me what you got
rectangle(img_display, matchLoc, cv::Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), cv::Scalar(255, 0, 0, 255), 2, 8, 0);
rectangle(result, matchLoc, cv::Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), cv::Scalar(255, 0, 0, 255), 2, 8, 0);
imshow(image_window, img_display);
imshow(result_window, result);
}
double myX = (matchLoc.x + (templ.cols) / 2);
double myY = (matchLoc.y + (templ.rows) / 2);
static int o[2];
o[0] = myX;
o[1] = myY;
return o;
}
但是,即使较大的图像不包含小图像,此代码也可能会错误地"找到"任何区域。
如何更改此代码,将其迫使其"准确"搜索小图像。例如,如果较小的图像不在较大的图像上,则此代码必须显示任何信息消息"未找到图像"。
更新1。看起来像matchTemplate
无法正常工作。例如,我有3个图像 - 一个模板(http://s6.postimg.org/nj2ts3lf5/image.png),一个图像,其中包含来自Template(http://s6.postimg.org.org.org.org.org.org.org/fpp6tkggg301/imimage from Template)。
对于第一个图像,包含模板,maxval = 0.9999999403955522及其正确选择的区域:http://s6.postimg.org/65x4qzfht/image.png
但对于图像,不包含模板,MaxVal = 1.00000000000000000000 和IT 错误地选定区域,t包含模板图像:http://s6.postimg.org/5132llt0x/screenshot_544.png
谢谢!
您正在可视化结果,无论算法执行匹配的确定性。模板匹配将始终为您提供输出 - 您想做的就是尝试找出是否有效。
根据match_method
尝试输出minVal
或maxVal
。在找到正确匹配的情况下以及在给您误报的情况下,您应该比较值。这些实验应允许您建立一个阈值,从而区分真正的命中和误报。因此,您将能够说出大小 - 例如,Maxval必须确保它是匹配的。伪代码会像这样:
if maxVal > threshold:
match_found = true
match_position = maxLoc
现在这是一种理论方法。由于您没有提供任何图像,因此可能不是解决问题的解决方案。
编辑:如果您找不到确定的阈值值(我认为在大多数情况下,如果您保持质量,尺寸等),请尝试做两件事之一:
- 尝试查看
minMaxLoc
之前的所有获得的结果,计算平均值,并查看发现的maxVal
是否比真实阳性情况中的平均值大得多。也许您可以将阈值定义为平均值的%,因此说:if maxVal > meanVal + meanVal * n%: match_found = true
- 这是一个常见的情况,模板匹配的边缘比真实图像更好。同样,您尚未提供样品,因此很难说在这里将有多可靠。但是,如果您有足够的高频率,以点亮具有巧妙边缘的图像,这可能会使您有更明显的阈值来区分真实和误报。
edit2:由于您使用的是match_method = 0,这意味着 CV_TM_SQDIFF
。有关对过程的更多控制,请明确使用名称。在此处查找有关方法的信息。
另外,将cout放入if语句中,以便打印正确的值,实际上是匹配匹配的(在您的情况下,是Minval)。
if (match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED)
{
matchLoc = minLoc;
std::cout << minVal << std::endl;
}
else
{
matchLoc = maxLoc;
std::cout << maxVal << std::endl;
}
又一次:如果这不给您预期的结果,几乎可以肯定会有所帮助。
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 编译包含字符串的代码时遇到问题
- c++库的公共头文件中应该包含什么
- 如何在包含数字的.bmp(二进制图像)中执行组件标记9 4 3 6
- 使用 QTimer 对包含 5 张图像的幻灯片进行计时
- wxWidgets 在编译时包含图像
- 如何确定 BMP 图像是否包含来自标题的 BGR 或 BGRA 像素
- OPENCV C - 查找图像中包含的图像
- Visual C++ Load rtf 文档在丰富编辑框中包含图像和文本
- 调用包含图像作为参数opencv/c++的函数时出现分段错误
- 如果我在Visual Studio项目中将图像作为资源包含在内,这些图像是否会编译到可执行文件中
- 给定尺寸为 26 * 7 的图像是否有可能在垫子的每一行中包含 78 个单独的颜色值,而另一个可以包含 77
- 将图像和文件包含到项目中
- 仅包含RGB 565中的红色成分的图像
- 将图像包含到标签中
- Xcode 4中的命令行工具构建版本,在构建可执行文件中包含图像存在问题
- 为什么我过滤后的图像(应该是二进制的)仍然包含彩色部分?(C++中的OpenCV)
- OpenCV创建矩阵,每行包含多个图像