java - openCV中的模板匹配[JAVA]

标签 java opencv image-processing

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

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);
}

当模板和目标图像具有相同比例时,效果很好。我的问题是如何使其规模无关? 我的搜索图片Target Image 和标志Template

最佳答案

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

我不了解 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 图像金字塔)。

如果有兴趣,还有大量论文涵盖了模板匹配的更高级变体(Google 搜索将找到大部分内容)。

您可能想查看feature detection它对于缩放和旋转是不变的。

同样,如果您可以发布您的 Logo 图片和搜索图像以提供帮助,那么可能有一个简单的替代方案。

关于java - openCV中的模板匹配[JAVA],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31919094/

相关文章:

java - Maven 未安装依赖项

java - Android:互联网连接变化监听器

Python OpenCV--MAC WebCam 不关闭

python - 将纬度、经度和高度转换为平面 3D 空间中的点

php - 在imagemagick中从png到jpg的透明背景

java - 如何使实例在我的 Android 应用程序中的任何位置可用或可访问

java - 使用 Maven 的 Oracle JDBC 项目 : runs fine in IDE but ClassNotFoundException in command-line

c++ - 如何在opencv cpp中获取霍夫变换矩阵,霍夫变换的theta和rho值

javascript - 如何在 Node.js 中运行时执行一系列图像处理步骤

java - 如何在图像上显示图像不同像素的速度 vector ?