openCV中的模板匹配[JAVA] [英] Template matching in openCV [JAVA]

查看:373
本文介绍了openCV中的模板匹配[JAVA]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 OpenCV(opencv_java248).我有一个模板图像.该模板图像具有徽标的一些公司.我想知道此徽标是否包含在其他图像中.我在某处遵循了代码.

I am using OpenCV(opencv_java248). I have one template image. This template image have logo some company. I want to know if this logo contain in other image. I got following code somewhere.

public void run(String inFile, String templateFile, String outFile,
        int match_method) {
    System.out.println("Running Template Matching");

    Mat img = Highgui.imread(inFile);
    Mat templ = Highgui.imread(templateFile);

    // / Create the result matrix
    int result_cols = img.cols() - templ.cols() + 1;
    int result_rows = img.rows() - templ.rows() + 1;
    Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);

    // / Do the Matching and Normalize
    Imgproc.matchTemplate(img, templ, result, match_method);
    // Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new
    // Mat());
    Imgproc.threshold(result, result, 0.5, 1.0, Imgproc.THRESH_TOZERO);
    // / Localizing the best match with minMaxLoc
    MinMaxLocResult mmr = Core.minMaxLoc(result);

    Point matchLoc;
    if (match_method == Imgproc.TM_SQDIFF
            || match_method == Imgproc.TM_SQDIFF_NORMED) {
        matchLoc = mmr.minLoc;
    } else {
        matchLoc = mmr.maxLoc;
    }
    double threashhold = 0.40;
    if (mmr.maxVal > threashhold) {
        Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
                matchLoc.y + templ.rows()), new Scalar(0, 255, 0));
    }
    // Save the visualized detection.
    Highgui.imwrite(outFile, img);
}

当模板和目标图像尺寸相同时,效果很好.我的问题是,如何使它的缩放无关紧要? 我的搜索图像和徽标

It is working great when template and target image is of same scale. My question is how can I make it scale irrelevant ? My search image and logo

推荐答案

一些您想要匹配的图像或一些代码将非常有用.

Some images of what you want to match or some code would be really useful.

我不知道Java API,但最近确实研究了用C ++编写的类似内容. 转换应该相当简单,因为两种语言的转换过程都是相同的.

I don't know the Java API but did recently look into something similar written in C++. Converting should be fairly straightforward as the process will be same in either language.

首先按常规执行模板匹配,读入图像并创建一个垫以保存结果.

Firstly perform template matching as normal, read in your images and create a mat to hold the result.

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

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

Now that the result is populated, create variables for holding the min/max scores and their locations within the result matrix.

公差值用于过滤可接受的结果,其中1.0可以看作是100%匹配,而0.25则可以看作是25%.

A tolerance value is used to filter acceptable results, where 1.0 can be seen as a 100% match and 0.25 as 25%.

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

现在从结果中提取值,并根据容差检查最大值,如果在容差范围之内.

Now extract values from the result and check your max value against your tolerance, if it's within the tolerance its a match.

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

You can also loop this process and check through all the results to see if your image contains multiple occurences of the template.

//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
}

您可能需要尝试公差/图像质量以及算作合格.但是,对于简单匹配,效果很好.

You'll likely need to experiment with tolerances / image quality and what counts as a pass. But for simple matching this works fairly well.

编辑-模板匹配和规模

仅由于模板的工作原理,标准模板匹配在缩放方面的效果就很差-搜索窗口只能与提供的模板一样小,因此要查找任何较小(或较大)的对象将很困难.

Standard template matching performs very poorly with scaling simply because of how it works - the search window can only be as small as the provided template, so finding anything smaller (or larger) is going to be difficult.

精简模板匹配以实现尺度不变性不是一件容易的事,您可以尝试的一种简单方法是创建模板的尺度变化(请看一下OpenCV的图像金字塔).

Refining template matching for scale invariance isn't the easiest thing to do, a simple method you could try is creating scaled variations of the template (have a look at OpenCVs Image Pyramids).

如果有兴趣的话,也有很多论文涉及更高级的模板匹配变体(Google搜索将带来最多的收获).

There are also plenty of papers out there covering more advanced variations of template matching if interested (a Google search will bring most up).

您可能想研究特征检测缩放和旋转不变.

You might want to look into feature detection which is invariant to scale and rotation.

同样,如果您可以贴上徽标图片和搜索图片,那么可能会有一个简单的选择.

Again, if you could post a picture of your logo and search image that would help, there might be a simple alternative.

这篇关于openCV中的模板匹配[JAVA]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆