【OpenCV-Python】教程:3-12 模板匹配

OpenCV Python 模板匹配

【目标】

  • 利用模板匹配的方法寻找目标
  • cv2.matchTemplate(), cv2.minMaxLoc()

【理论】

模板匹配是一个寻找大图像中目标位置的方法。OpenCV提供了函数 cv2.matchTemplate() 函数,通过在输入图像上滑动模板,将目标与滑动处的图像 patch 进行匹配,OpenCV中实现了很多种不同的方法,返回的是一个结果图像,结果图像的每个像素代表的滑动位置的匹配值。如果输入图像是 W ∗ H W*H WH, 模板图像大小是 w ∗ h w*h wh, 那么结果图像的大小为 ( W − w + 1 ) ∗ ( H − h + 1 ) (W-w+1)*(H-h+1) (Ww+1)(Hh+1)。最终可以使用 cv2.minMaxLoc函数获得匹配结果最大值或最小值的位置。

如果使用 cv2.TM_SQDIFF 作为比较方法,最小值代表越匹配。

【代码】

【OpenCV-Python】教程:3-12 模板匹配_第1张图片
【OpenCV-Python】教程:3-12 模板匹配_第2张图片
【OpenCV-Python】教程:3-12 模板匹配_第3张图片
【OpenCV-Python】教程:3-12 模板匹配_第4张图片
【OpenCV-Python】教程:3-12 模板匹配_第5张图片
【OpenCV-Python】教程:3-12 模板匹配_第6张图片

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 

img = cv2.imread("assets/messi5.jpg", 0)
img2 = img.copy()

template = cv2.imread("assets/messi_face.png", 0)
w, h = template.shape

methods = ["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)
  
    res = cv2.matchTemplate(img2, templ=template, method=method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  
    # 如果用的是 cv2.TM_SQDIFF 或 cv2.TM_SQDIFF_NORMED, 则用最小值
    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, color=255, thickness=2)
  
    # cv2.imshow('Match Res', res)
    # cv2.imshow('Det Res', img)
    # cv2.waitKey(0)
  
    plt.subplot(121), plt.imshow(res, cmap='gray')
    plt.title('Match Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122), plt.imshow(img, cmap='gray')
    plt.title('Detect Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.savefig(meth+'.png', bbox_inches='tight')
    plt.show()
  
# cv2.destroyAllWindows()
  • 多目标匹配

【OpenCV-Python】教程:3-12 模板匹配_第7张图片

import cv2 
import numpy 
from matplotlib import pyplot as plt 

img = cv2.imread("assets/coin.png")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

template = cv2.imread("assets/coin_template.png", 0)
w, h = template.shape

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8

loc = np.where(res >= threshold)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img, pt, (pt[0]+w, pt[1]+h), (0, 255, 0), 2)

cv2.imshow("result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

【接口】

  • matchTemplate
cv2.matchTemplate(	image, templ, method[, result[, mask]]	) ->	result

Compares a template against overlapped image regions.

  • image: 需要寻找目标的图像
  • templ: 模板(或目标)
  • method: 匹配方法
  • result: 32位单通道浮点图像,
  • mask: 大小和 templ 一致,通道数一致或为单通道。
  • TemplateMatchModes

【OpenCV-Python】教程:3-12 模板匹配_第8张图片

【OpenCV-Python】教程:3-12 模板匹配_第9张图片

  • minMaxLoc
cv2.minMaxLoc(	src[, mask]	) ->	minVal, maxVal, minLoc, maxLoc

寻找全局最大最小值以及位置
不适合多通道使用,如果确实要在多通道上使用,可以改变形状,或者分离通道等操作

  • src: 单通道图像或数据
  • minVal: 最小值
  • maxVal: 最大值
  • minLoc: 最小值的位置
  • maxLoc: 最大值的位置
  • mask: 掩码

【参考】

  1. OpenCV 官方文档

你可能感兴趣的:(#,OpenCV,opencv,python,计算机视觉,模板匹配)