模板匹配,就是在给定的图片中查找和模板最相似的区域,该算法的输入包括模板和图片,整个任务的思路就是按照滑窗的思路不断的移动模板图片,计算其与图像中对应区域的匹配度,最终将匹配度最高的区域选择为最终的结果。
模板块每次移动一个像素 (从左往右,从上往下),在每一个位置,都计算与模板图像的相似程度
对于每一个位置将计算的相似结果保存在结果矩阵(R)中。如果输入图像的大小(WxH)且模板图像的大小(wxh),则输出矩阵R的大小为(W-w + 1,H-h + 1)将R显示为图像
获得上述图像后,查找最大值所在的位置,那么该位置对应的区域就被认为是最匹配的。对应的区域就是以该点为顶点,长宽和模板图像一样大小的矩阵。
API:
res = cv.matchTemplate(img,template,method)
参数:
img: 要进行模板匹配的图像
Template :模板
完成匹配后,使用cv.minMaxLoc()方法查找最大值所在的位置即可。如果使用平方差作为比较方法,则最小值位置是最佳匹配位置。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 图像和模板读取
img = cv.imread("D:\Python\Opencvlearn\\02.code\image\wulin.jpeg")
template = cv.imread("D:\Python\Opencvlearn\\02.code\image\\bai.jpeg")
h,w,l = template.shape
# 2 模板匹配
# 2.1 模板匹配
res = cv.matchTemplate(img,template,cv.TM_CCORR)
# 2.2 返回图像中最匹配的位置,确定左上角的坐标,并将匹配位置绘制在图像上
min_val,max_val,min_loc,max_loc = cv.minMaxLoc(res)
# 使用平方差时最小值为最佳匹配位置
# top_left = min_loc
top_left = max_loc
bottom_right = (top_left[0]+w,top_left[1]+h)
cv.rectangle(img,top_left,bottom_right,(0,255,0),2)
# 3 图像显示
plt.imshow(img[:,:,::-1])
plt.title("The result of match"),plt.xticks([]),plt.yticks([])
plt.show()
拓展:模板匹配不适用于尺度变换,视角变换后的图像,这时我们就要使用关键点匹配算法,比较经典的关键点检测算法包括SIFT和SURF等,主要的思路是首先通过关键点检测算法获取模板和测试图片中的关键点;然后使用关键点匹配算法处理即可,这些关键点可以很好的处理尺度变化、视角变换、旋转变化、光照变化等,具有很好的不变性。
霍夫变换常用来提取图像中的直线和圆等几何形状
API:
cv.HoughLines(img, rho, theta, threshold)
参数:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import random
# 1.加载图片,转为二值图
img = cv.imread("D:\Python\Opencvlearn\\02.code\image\\rili.jpg")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray,50,150)
# 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("霍夫变换线检测")
plt.xticks([]),plt.yticks([])
plt.show()
原则上霍夫变换可以检测任何形状,但复杂的形状需要的参数就多,霍夫空间的维数就多,因此在程序实现上所需的内存空间以及运行效率上都不利于把标准霍夫变换应用于实际复杂图形的检测中。霍夫梯度法是霍夫变换的改进,它的目的是减小霍夫空间的维度,提高效率。
API
cv2.circle()方法用于在任何图像上绘制圆。
cv2.circle(image, center_coordinates, radius, color, thickness)
参数:
image:它是要在其上绘制圆的图像。
center_coordinates:它是圆的中心坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)。
radius:它是圆的半径。
color:它是要绘制的圆的边界线的颜色。对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色。
thickness:它是圆边界线的粗细像素。厚度-1像素将以指定的颜色填充矩形形状。
在OpenCV中检测图像中的圆环使用的是API是:
circles = cv.HoughCircles(image, method, dp, minDist, param1=100, param2=100, minRadius=0,maxRadius=0 )
参数:
返回:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import random
# 导入
img = cv.imread('D:\Python\Opencvlearn\\02.code\image\star.jpeg')
# BGR图像转为RGB图像, plt可以正常显示
img_RGB = cv.cvtColor(img, cv.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(img_RGB, cmap='gray')
plt.title('Original img'), plt.xticks([]), plt.yticks([])
# 去噪
img_blur = cv.medianBlur(img,5)
img_gray = cv.cvtColor(img_blur, cv.COLOR_BGR2GRAY)
circles = cv.HoughCircles(img_gray, cv.HOUGH_GRADIENT, 1, 40,
param1=200, param2=50, minRadius=50, maxRadius=130)
# circles = cv.HoughCircles(img_gray,cv.HOUGH_GRADIENT,1,80,
# param1=150,param2=40,minRadius=30,maxRadius=80)
circles = np.uint16(np.around(circles)) # 这里不懂,所以课件中的代码一直实现不了,这个是csdn复制的。
for i in circles[0, :]:
# 绘制外圆
img_circle = cv.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
# 绘制圆心
img_circlep = cv.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)
img_circlep = cv.cvtColor(img_circlep, cv.COLOR_BGR2RGB)
plt.subplot(122), plt.imshow(img_circlep, cmap='gray')
plt.title("detected circles (minDist=40)"), plt.xticks([]), plt.yticks([])
plt.show()