[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析

一、模板匹配分析

所谓模板匹配,就是在给定的图片中查找和模板最相似的区域,该算法的输入包括模板和图片,整个任务的思路就是按照滑窗的思路不断的移动模板图片,计算其与图像中对应区域的匹配度,最终将匹配度最高的区域选择为最终的结果。

1、实现流程

(1)准备两副图像

  1. 原图像(I):在这幅图中,找到与模板相匹配的区域
  2. 模板(T):与原图像进行比对的图像块

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第1张图片

(2)滑动模板图像和原图像进行比对

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第2张图片 (3)对于每一个位置将计算的相似结果保存在结果矩阵(R)中

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第3张图片

(4)获得上述图像后,查找最大值所在的位置。

获得上述图像后,查找最大值所在的位置,那么该位置对应的区域就被认为是最匹配的。对应的区域就是以该点为定点,长宽和模板图像一样大小的矩阵。 

 2、API介绍

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第4张图片

 3、简单案例

做一个梅西的模板,以梅西的脸部为模板,分别检测几种不同的检测方法

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第5张图片

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('images/messi5.jpg', 0)
img2 = img.copy()
template = cv.imread('images/messi_face.jpg', 0)
w, h = template.shape[::-1]

# All the 3 methods for comparison in a list
methods = ['cv.TM_CCOEFF', 'cv.TM_CCORR', 'cv.TM_SQDIFF']
for meth in methods:
    img = img2.copy()
    method = eval(meth)

    # Apply template Matching
    res = cv.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)

    # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
    if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv.rectangle(img, top_left, bottom_right, 255, 2)
    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()

检测结果如下:

cv.TM_CCOEFF:

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第6张图片

 cv.TM_CCORR:

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第7张图片

 cv.TM_SQDIFF:

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第8张图片

注: 可以看到使用cv.TM_CCORR的结果不如我们预期的那样好。

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第9张图片

 与多个对象匹配的模板

在上面我们搜索了梅西的脸的图像,在图像中只出现了一次。假设您正在搜索一个多次出现的对 象,cv.minMaxLoc()不会给出所有的位置。在这种情况下,我们将使用阈值化。在这个例子中,我们将使用著名游戏马里奥的截图,我们将在其中找到硬币。

python  zip()函数:

  • zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
  • 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。zip(*loc[::-1])
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img_rgb = cv.imread('images/mario.jpg')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('images/coin.jpg', 0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):
    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
cv.imshow('res.png', img_rgb)
cv.waitKey(0)
cv.destroyAllWindows()

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第10张图片

 二、霍夫变换分析

霍夫变换常用来提取图像中的直线和圆等几何形状,详情如下介绍:

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第11张图片

 1、实现流程

假设有一个大小为100 * 100的图片,使用霍夫变换检测图片中的直线,则步骤如下所示:

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第12张图片

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第13张图片

 2、霍夫线检测

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第14张图片

 霍夫线检测的整个流程如下图所示,这是在stackflow上一个关于霍夫线变换的解释:

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第15张图片

(1) 简单使用

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from matplotlib import font_manager
#设置字体
my_font = font_manager.FontProperties(fname="C:/Windows/Fonts/STHUPO.TTF")

#1、加载图片,转换二值图
img = cv.imread("./images/feilin.jpg")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 100)

#2、霍夫线变换
lines = cv.HoughLines(edges, 0.8, np.pi / 180, 150)

#3、将检测到的线绘制在图像上(注意是极坐标)
for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    x1 = int(x0 + 1000 * (-b))
    y1 = int(y0 + 1000 * (a))
    x2 = int(x0 - 1000 * (-b))
    y2 = int(y0 - 1000 * (a))
    cv.line(img, (x1, y1), (x2, y2), (0, 255, 0))

#4、图像显示
plt.figure(figsize=(10,8), dpi=100)
plt.imshow(img[:,:,::-1])
plt.title("霍夫变换线检测", fontproperties=my_font)
plt.xticks([]), plt.yticks([])
plt.show()

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第16张图片

3、霍夫圆检测

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第17张图片 (1)API介绍

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第18张图片

(2)简单使用

介绍:cv.circle(img,(520,430),300,(255,0,0),8)

  • 在img原始图片中划圈,其圈的中心点为(520,430),半径=300,颜色为(255,0,0),粗细=8
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from matplotlib import font_manager
#字体设置
my_font = font_manager.FontProperties(fname="C:/Windows/Fonts/STHUPO.TTF")

#1、读取图像,并转换为灰度图
plants = cv.imread("./images/star.jpg")
gray_img = cv.cvtColor(plants, cv.COLOR_BGR2GRAY)

#2、进行中值滤波,去除噪点
img = cv.medianBlur(gray_img, 7)

#3、霍夫圆检测
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 100, param1=100, param2=30, minRadius=0, maxRadius=100)

#4、将检测结果绘制在图像上
for i in circles[0, :]: #遍历矩阵每一行的数据
    #绘制图形
    cv.circle(plants, (i[0], i[1]), i[2], (0,0,255), 2)
    #绘制圆心
    cv.circle(plants, (i[0], i[1]), 2, (0,0,255), 3)

#5、图像显示
plt.figure(figsize=(10, 8), dpi=100)
plt.imshow(plants[:,:,::-1])
plt.title("霍夫变换圆检测", fontproperties=my_font)
plt.xticks([]),plt.yticks([])
plt.show()

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第19张图片 三、总结

[模板匹配&霍夫变换]——模板匹配分析、霍夫变换分析_第20张图片

你可能感兴趣的:(计算机视觉)