【待解决】【OpenCV图像处理】1.27 模板匹配(Template Match)

1. 相关理论

直观介绍:
在这里插入图片描述

  • 介绍

    • 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。
    • 所以模板匹配首先需要一个模板图像T(给定的子图像)
    • 另外需要一个待检测的图像-源图像S
    • 工作方法,在带检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大。
  • 模板匹配介绍 - 匹配算法介绍
    OpenCV中提供了六种常见的匹配算法如下:

    • 计算平方不同: R ( x , y ) = z , y ( T ( x , y ) I ( x + x , y + y ) ) 2 R(x, y)=\sum_{z^{\prime}, y}\left(T\left(x^{\prime}, y^{\prime}\right)-I\left(x+x^{\prime}, y+y^{\prime}\right)\right)^{2}
    • 计算相关性: R ( x , y ) = x , y ( T ( x , y ) I ( x + x , y + y ) ) R(x, y)=\sum_{x^{\prime}, y^{\prime}}\left(T\left(x^{\prime}, y^{\prime}\right) \cdot I\left(x+x^{\prime}, y+y^{\prime}\right)\right)
    • 计算相关系数:
      R ( x , y ) = x , y ( T ( x , y ) I ( x + x , y + y ) ) T ( x , y ) = T ( x , y ) 1 / ( w h ) x , y T ( x , y ) I ( x + x , y + y ) = I ( x + x , y + y ) 1 / ( w h ) x , y I ( x + x , y + y ) \begin{array}{c}{R(x, y)=\sum_{x^{\prime}, y^{\prime}}\left(T^{\prime}\left(x^{\prime}, y^{\prime}\right) \cdot I^{\prime}\left(x+x^{\prime}, y+y^{\prime}\right)\right)} \\ {T^{\prime}\left(x^{\prime}, y^{\prime}\right)=T\left(x^{\prime}, y^{\prime}\right)-1 /(w \cdot h) \cdot \sum_{x^{\prime \prime}, y^{\prime \prime}} T\left(x^{\prime \prime}, y^{\prime \prime}\right)} \\ {I^{\prime}\left(x+x^{\prime}, y+y^{\prime}\right)=I\left(x+x^{\prime}, y+y^{\prime}\right)-1 /(w \cdot h) \cdot \sum_{x^{\prime \prime}, y^{\prime \prime}} I\left(x+x^{\prime \prime}, y+y^{\prime \prime}\right)}\end{array}
    • 计算归一化平方不同:
      R ( x , y ) = z , y ( T ( x , y ) I ( x + x , y + y ) ) 2 z , y T ( x , y ) 2 z , y I ( x + x , y + y ) 2 R(x, y)=\frac{\sum_{z^{\prime}, y^{\prime}}\left(T\left(x^{\prime}, y^{\prime}\right)-I\left(x+x^{\prime}, y+y^{\prime}\right)\right)^{2}}{\sqrt{\sum_{z^{\prime}, y^{\prime}} T\left(x^{\prime}, y^{\prime}\right)^{2} \cdot \sum_{z^{\prime}, y^{\prime}} I\left(x+x^{\prime}, y+y^{\prime}\right)^{2}}}
    • 计算归一化相关性
      R ( x , y ) = z , y ( T ( x , y ) I ( x + x , y + y ) ) z y T ( x , y ) 2 z y I ( x + x , y + y ) 2 R(x, y)=\frac{\sum_{z^{\prime}, y}\left(T\left(x^{\prime}, y^{\prime}\right) \cdot I\left(x+x^{\prime}, y+y^{\prime}\right)\right)}{\sqrt{\sum_{z^{\prime} y^{\prime}} T\left(x^{\prime}, y^{\prime}\right)^{2} \cdot \sum_{z^{\prime} y^{\prime}} I\left(x+x^{\prime}, y+y^{\prime}\right)^{2}}}
    • 计算归一化相关系数:
      R ( x , y ) = x , y ( T ( x , y ) I ( x + x , y + y ) ) x , y T ( x , y ) 2 z , y I ( x + x , y + y ) 2 R(x, y)=\frac{\sum_{x^{\prime}, y^{\prime}}\left(T^{\prime}\left(x^{\prime}, y^{\prime}\right) \cdot I^{\prime}\left(x+x^{\prime}, y+y^{\prime}\right)\right)}{\sqrt{\sum_{x^{\prime}, y^{\prime}} T^{\prime}\left(x^{\prime}, y^{\prime}\right)^{2} \cdot \sum_{z^{\prime}, y^{\prime}} I^{\prime}\left(x+x^{\prime}, y+y^{\prime}\right)^{2}}}
  • 相关API介绍cv::matchTemplate

    matchTemplate(
    
    InputArray image,// 源图像,必须是8-bit或者32-bit浮点数图像
    
    InputArray templ,// 模板图像,类型与输入图像一致
    
    OutputArray result,// 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh,则结果必须为W-w+1, H-h+1的大小。
    int method,//使用的匹配方法
    
    InputArray mask=noArray()//(optional)
    )
    

2. 源码 & 效果展示

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>

using namespace std;
using namespace cv;

#ifndef P27
#define P27 27
#endif

#if P27 //模板匹配
    Mat src, temp, dst;
    int match_method = TM_SQDIFF;
    int max_track = 5;
    const char* INPUT_T = "input image";
    const char* OUTPUT_T = "result image";
    const char* match_t = "template match-demo";

    void Match_Demo(int, void*) {
        int width = src.cols - temp.cols + 1;
        int height = src.rows - temp.rows + 1;
        Mat result(width, height, CV_32FC1);

        matchTemplate(src, temp, result, match_method, Mat());
        normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

        Point minLoc;
        Point maxLoc;
        double min, max;
        src.copyTo(dst);
        Point temLoc;
        minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());
        if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED) {
            temLoc = minLoc;
        } else {
            temLoc = maxLoc;
        }

        rectangle(dst, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
        rectangle(result, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);

        imshow(OUTPUT_T, result);
        imshow(match_t, dst);
    }
#endif

int main() {
    std::string path = "../color_line.JPG";
    cv::Mat img = cv::imread(path, 5);
    if(img.empty())
    {
        std::cout << "open file failed" << std::endl;
        return -1;
    }
    
#if P27 //模板匹配
    src = imread("../fei.JPG");
	temp = imread("../color_line.JPG");
	if (src.empty() || temp.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow(INPUT_T, WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_T, WINDOW_AUTOSIZE);
	namedWindow(match_t, WINDOW_AUTOSIZE);
	imshow(INPUT_T, temp);
	const char* trackbar_title = "Match Algo Type:";
	createTrackbar(trackbar_title, OUTPUT_T, &match_method, max_track, Match_Demo);
	Match_Demo(0, 0);

#endif

    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

运行效果:
编译、链接成功,但运行上述代码失败,提示:

libc++abi.dylib: terminating with uncaught exception of type cv::Exception: OpenCV(4.0.1) 
/tmp/opencv-20190105-31032-o160to/opencv-4.0.1/modules/core/src/matrix.cpp:
235: error: (-215:Assertion failed) s >= 0 in function 'setSize'

Process finished with exit code 6

有待解决。

发布了134 篇原创文章 · 获赞 30 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/donaldsy/article/details/102746665