openCV中的模板匹配[JAVA]

时间:2015-08-10 12:05:32

标签: java opencv image-processing

我正在使用 OpenCV(opencv_java248)。我有一个模板图像。这个模板图片有一些公司的标识。我想知道这个标志是否包含其他图片。我在某处获得了以下代码。

});

当模板和目标图像具有相同比例时,它工作得很好。我的问题是如何才能使其无关紧要? 我的搜索图片Target Image 和徽标Template

1 个答案:

答案 0 :(得分:4)

您想要匹配的内容或某些代码的某些图片非常有用。

我不了解Java API,但最近看到的是用C ++编写的类似内容。 转换应该相当简单,因为这两种语言的过程都是相同的。

首先正常执行模板匹配,读入图像并创建垫以保存结果。

cv::Mat drawing = cv::imread(_drawing); //Read drawing
cv::Mat tmp = cv::imread(_tmp);  //Read template
cv::Mat res(drawing.rows - tmp.rows + 1, drawing.cols - tmp.cols + 1, CV_32FC1); //Create result matrix

//Perform template matching, normalise results 0 -> 1
cv::matchTemplate(tmp, drawing, res, CV_TM_CCOEFF_NORMED);
cv::threshold(res, res, 0.8, 1.0, CV_THRESH_TOZERO); //Can thresh to filter results if needed

现在已填充结果,创建变量以保存结果矩阵中的最小/最大分数及其位置。

公差值用于过滤可接受的结果,其中1.0可视为100%匹配,0.25视为25%。

//min/max values and acceptable tolerance
double min, max, tolerance = 0.90;
cv::Point minloc, maxloc; //min/max value locations

现在从结果中提取值,并根据公差检查最大值,如果它在公差范围内匹配。

您还可以循环此过程并检查所有结果,以查看您的图片是否包含模板的多次出现。

//Loop through all results
while (true){

    //Pull out min/max values from results matrix
    cv::minMaxLoc(res, &min, &max, &minloc, &maxloc);

    //Is max within tolerance
    if (max >= tolerance){

        //Yes - Match found, do stuff //

        //Blank out that result in matrix so next highest can be extracted
        cv::floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(0.1), cv::Scalar(1.0));

    }
    else
        break; //No more results within tolerance, break search
}

您可能需要尝试公差/图像质量以及什么算作合格。但是对于简单匹配,这种方法效果相当不错。

编辑 - 模板匹配&规模

标准模板匹配在缩放方面的表现非常差,因为它的工作原理 - 搜索窗口只能与提供的模板一样小,因此找到更小(或更大)的东西将会很困难。

为缩放不变性精炼模板匹配并不是最简单的方法,您可以尝试的一种简单方法是创建模板的缩放变体(查看OpenCVs Image Pyramids)。

如果感兴趣的话,还有很多论文涉及模板匹配的更高级变体(谷歌搜索会带来最多)。

您可能希望查看feature detection,它对缩放和旋转不变。

同样,如果您可以发布有用的徽标和搜索图片的图片,可能会有一个简单的替代方案。