opencv笔记之模板匹配
来源:互联网 发布:当当读书网络连接失败 编辑:程序博客网 时间:2024/05/22 12:23
opencv笔记之模板匹配
原理:即从一幅图像中找出与给定模板最相似的部分,如图:
具体实现:
1.以模板大小的框T,从原图左上角开始Z字型遍历,步长为一个像素,得到与原图大小一致的图像S;
2.利用相关匹配等五种方法之一计算原图中S与模板T相似性;
3.将2中计算的值生成一幅大小为(srcImg.width-Template.width+1)*(srcImg.height-Template.height+1)矩阵M。(其类型为浮点型)
4.搜索矩阵M中最大或最小的坐标为在原图上匹配的结果的起始坐标(即上图中白色框的左上角坐标)。
注:在上述中第3步中,我们利用下图来具体描述:
其中第一幅图为原图像S,第二幅图像模板图像T,第三幅图像为匹配结果生成的矩阵Res。
我们通过在原图S中截取与模板图像T大小一致的图像,(即4*4的S1与4*4的T1)通过计算其像素值与模板图像的相关匹配CV_TM_CCORR,得到其Res的第一个值,通过Z字型划窗,步长为1,分别计算相关匹配CV_TM_CCORR的值,即可生成矩阵Res;
算法python实现:
# -*- coding:utf-8 -*-"""@author:Leyon@file:test.py@time:2017/12/1312:22"""import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('lena1.jpg', 0)cv2.imshow('img',img)#cv2.imwrite("img.jpg",img)img2 = img.copy()template = cv2.imread('lena2.jpg', 0)cv2.imshow('template',template)#cv2.imwrite("template.jpg",template)w, h = template.shape[::-1]# All the 6 methods for comparison in a listmethods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']for meth in methods: img = img2.copy() method = eval(meth) # Apply template Matching res = cv2.matchTemplate(img, template, method) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: top_left = min_loc else: top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(img, top_left, bottom_right, 255, 1) plt.subplot(121), plt.imshow(res, cmap='gray') plt.title('Matching Result'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(img, cmap='gray') plt.title('Detected Point'), plt.xticks([]), plt.yticks([]) plt.suptitle(meth) plt.show()
五种方法对应的效果图:
C++实现:(其代码在opencv\sources\samples\cpp\tutorial_code\Histograms_Matching文件夹下)
/** * @file MatchTemplate_Demo.cpp * @brief Sample code to use the function MatchTemplate * @author OpenCV team */#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>#include <stdio.h>using namespace std;using namespace cv;/// Global VariablesMat img; Mat templ; Mat result;const char* image_window = "Source Image";const char* result_window = "Result window";int match_method;int max_Trackbar = 5;/// Function Headersvoid MatchingMethod( int, void* );/** * @function main */int main( int, char** argv ){ /// Load image and template //img = imread( argv[1], 1 ); //templ = imread( argv[2], 1 ); img = imread("lena.jpg", 1); templ = imread("lena1.jpg", 1); /// Create windows namedWindow( image_window, WINDOW_AUTOSIZE ); namedWindow( result_window, WINDOW_AUTOSIZE ); /// Create Trackbar const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod ); MatchingMethod( 0, 0 ); waitKey(0); return 0;}/** * @function MatchingMethod * @brief Trackbar callback */void MatchingMethod( int, void* ){ /// Source image to display Mat img_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_cols, result_rows, CV_32FC1 ); /// Do the Matching and Normalize matchTemplate( img, templ, result, match_method ); normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() ); /// Localizing the best match with minMaxLoc double minVal; double maxVal; Point minLoc; Point maxLoc; Point matchLoc; minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, 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; } /// Show me what you got rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 ); imshow( image_window, img_display ); imshow( result_window, result ); return;}如果想要单步调试,查看其具体函数实现,可以用Cmake编译Opencv的Sample查看其细节实现
注:两个主要函数如下:或在OpenCV API Reference查询
五种计算模板相似性方法:
总结:使用此类算法有一定的局限性,其用时过长,而且准确率也不高,例如上述效果图中,第一,三种方法匹配结果不准确;对于此类算法,我们也可以利用原图与模板的直方图进行对比,来实现匹配。比如,肤色检测中,我们利用肤色模板的H-S二维直方图,与原图的H-S二维直方图进行匹配。准确率应该会有一定程度的提高。
- opencv笔记之模板匹配
- 【openCV笔记1】模板匹配
- opencv学习之模板匹配
- Opencv学习之模板匹配
- OpenCV学习笔记[4]模板匹配
- OpenCV 学习笔记(模板匹配)
- OpenCV学习笔记(十七)模板匹配
- opencv学习笔记(三十二)模板匹配
- opencv模板匹配笔记----C++练手项目
- opencv for python 之 模板匹配
- OpenCV实现之模板匹配(Template Matching)
- opencv 模板匹配matchTemplate研究之二
- matlab/opencv图像处理之模板匹配
- opencv之模板匹配(初)
- opencv-模板匹配
- OpenCV模板匹配
- opencv的模板匹配
- OpenCV编程->模板匹配
- DevExpress v17.2新版亮点—WPF篇(二)
- leetcode 459. Repeated Substring Pattern 暴力拆分即可
- QRCode使用Encoding.UTF8编码时,报错
- 深度学习记录随笔-持续更新
- Jquery 总结
- opencv笔记之模板匹配
- App 压力测试——Monkey Script常用命令介绍
- Ubuntu14.04下 安装OpenSSL 部署腾讯云免费版DV SSL证书
- Centos7安装node
- 第十五周项目1(3)-验证算法(冒泡排序)
- JavaScript变量声明与提升
- 第15周项目1(7)- 验证基数排序算法
- IP地址非你在商户平台设置的可用IP地址
- Date 与 String、long 的相互转换