OpenCV是一个流行的计算机视觉库,它提供了多种图像处理和计算机视觉算法。其中模板匹配、霍夫线检测和霍夫圆检测是其常用的图像处理算法之一。
模板匹配
模板匹配是一种在给定的图像中寻找特定图案或模板的方法。其基本思想是将模板图片与待匹配的原始图片按照各自的像素点逐一比较,并计算相似度。可以采用不同的相似度度量方法,常用的有平方差匹配和相关性匹配等。在OpenCV中,可以使用cv2.matchTemplate()函数实现模板匹配。该函数需要输入原始图片和模板图片,并根据选择的相似度度量方法返回匹配结果图像。
霍夫线检测
霍夫线检测是一种广泛应用于计算机视觉领域的技术,可以检测出图像中的直线。它的基本思想是对于图像中的每个点,将其表示成在极坐标空间中的一条直线,并根据给定阈值找到投票数达到设定值的直线。在OpenCV中,可以使用cv2.HoughLines()函数实现霍夫线检测,该函数接受输入图像、霍夫变换方法(标准或累加器)和投票阈值等参数,并返回在Hough空间中检测到的直线信息。
霍夫圆检测
霍夫圆检测是一种通过在二维平面上应用霍夫变换来检测图像中的圆形。其基本思路是对于图像中的每个点,将其表示成在参数空间中的一个圆。找到一组参数集合,使得这些参数描述的圆最符合图像中的圆形特征。在OpenCV中,可以使用cv2.HoughCircles()函数实现霍夫圆检测。该函数需要提供输入图像、霍夫变换方法、圆心和半径的最小和最大值等参数,并返回在参数空间中检测到的圆的信息。
总结一下,模板匹配可以用于寻找给定图案或模板在图像中的位置,霍夫线检测适用于检测出图像中的直线,而霍夫圆检测则可以用于检测出图像中的圆形。在OpenCV中,这些功能都有相应的函数实现,并且可以根据具体需求进行调整。需要注意的是,在不同的场景下,这些算法可能会存在一些限制或局限性,使用时应充分考虑其适用性与准确性。
霍夫线检测原理:
霍夫线检测基于以下原理:一条直线可由其在参数空间中的两个参数表示,一般为极坐标形式,即 (ρ, θ)。对于图像中的每个边缘点,都可以在参数空间中生成一条曲线,通过计算曲线上的交点,可以确定在图像中的直线。在霍夫线检测的过程中,需要设置一个投票阈值,当累计投票数达到设定值时,就认为在参数空间中找到了一条直线。
霍夫线检测参数设置:
精度参数rho (ρ):表示ρ的精度,即参数空间中ρ的步长。较小的步长可以提高检测的精度,但会增加计算量。
角度参数theta (θ):表示θ的精度,即参数空间中θ的步长。同样地,较小的步长可以提高检测的精度,但也会增加计算量。
投票阈值threshold:用于确定在参数空间中哪些点被选为直线。较高的阈值可以得到更明显的直线,但可能会丢失某些较弱的直线。
最小直线长度minLineLength:表示被检测到的直线的最小长度。短于此长度的直线将被丢弃。
最大间隔距离maxLineGap:指定两条直线被认为是一条直线的最大允许间隔距离。
霍夫圆检测原理:
霍夫圆检测基于以下原理:对于图像中的每个边缘点,都可以在参数空间中生成一个圆。通过计算这些圆的交点,并统计交点的累计投票数,就可以确定在图像中的圆。在霍夫圆检测的过程中,同样需要设置一个投票阈值,当累计投票数达到设定值时,就认为在参数空间中找到了一个圆。
霍夫圆检测参数设置:
累加器分辨率dp:表示霍夫变换空间的分辨率。较小的数值可以提高检测的精度,但会增加计算量。
最小圆半径minRadius和最大圆半径maxRadius:用于限定圆的半径范围。只有在此范围内的圆才会被检测到。
投票阈值threshold:用于确定在参数空间中哪些点被选为圆。较高的阈值可以得到更明显的圆,但可能会丢失某些较弱的圆。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
#图像和模板的读取
img = cv.imread("cat.png")
template = cv.imread(r"E:\All_in\opencv\cat_1.png")
h,w,l = template.shape #template.shape 返回模板图像的高度、宽度和通道数。
#模板匹配
res = cv.matchTemplate(img,template,cv.TM_CCORR) #cv.TM_CCORR 是匹配方法,表示使用相关系数进行匹配。
#返回图像中最匹配的位置,确定左上角的坐标,并将匹配位置绘制在图像上
min_val,max_val,min_loc,max_loc = cv.minMaxLoc(res) #cv.minMaxLoc 函数返回匹配结果矩阵中的最小值、最大值及其对应的位置。在这里,我们只关心最大值和其对应的位置。
#使用平方差时最小值为最佳匹配位置
#top_left = min_loc
"""确定最佳匹配位置的左上角坐标(top_left)和
右下角坐标(bottom_right),并在图像上绘制矩形框来表示匹配位置:"""
top_left = max_loc
bottom_right = (top_left[0] + w,top_left[1] + h)
cv.rectangle(img , top_left,bottom_right,(0,255,0),5)
"""top_left 和 bottom_right 分别是矩形框的左上角和右下角坐标,
(0, 255, 0) 是矩形框的颜色,(0, 255, 0) 表示绿色,2 是矩形框的线宽。"""
#图像显示
plt.imshow(img[:,:,::-1])
plt.title('匹配结果'),plt.xticks([]),plt.yticks([])
plt.show()
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
#加载图片,转为二值图
img = cv.imread("line.png")
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray,50,150)
'''
50 和 150:Canny 边缘检测的阈值参数。这两个参数用于控制边缘的检测灵敏度
使用 cv.cvtColor() 函数将图像从 BGR 格式转换为灰度图像,并将结果存储在变量 gray 中。
再利用 cv.Canny() 函数对灰度图像进行边缘检测,得到边缘图像并将其存储在变量 edges 中
'''
#霍夫直线变换
lines = cv.HoughLines(edges,0.8,np.pi / 180,150)
'''0.8:距离精度 rho 的值,表示极坐标距离 rho 的最小步长。
np.pi / 180:角度精度 theta 的值,表示极坐标角度 theta 的最小步长。
150:阈值,表示在霍夫空间中检测直线时所需的最低投票数。投票数高于阈值的直线将被认为是有效的直线。
'''
#将检测的线绘制在图像上(极坐标)
for line in lines:
rho,theta = line[00]
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))
'''遍历检测到的直线参数列表 lines。对于每条直线,首先获取直线的极坐标参数 rho 和 theta。
然后,根据极坐标中的角度 theta 计算出直线的斜率参数 a 和 b。
再根据极坐标中的距离 rho 计算出直线上的一对坐标 (x0, y0)。
接下来,利用斜率和距离计算直线上另外两个点的坐标 (x1, y1) 和 (x2, y2)。
最后,使用 cv.line() 函数在原始图像 img 上绘制检测到的直线,线段颜色为绿色。
'''
#图像显示
plt.figure(figsize=(5,4),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title("霍夫变换线检测")
plt.xticks([]),plt.yticks([])
plt.show()
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
#读取图像转化为灰度图
planets = cv.imread("circle.png")
gray_img = cv.cvtColor(planets,cv.COLOR_BGR2GRAY)
#进行模糊去噪点
img = cv.medianBlur(gray_img,7)
#霍夫圆检测
circles = cv.HoughCircles(img , cv.HOUGH_GRADIENT,1,200,param1=100,param2=30,minRadius=0,maxRadius=100)
# 判断是否成功找到圆
if circles is not None:
# 将结果显示在图像上
for i in circles[0, :]:
cv.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2) # 绘制圆形
cv.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3) # 绘制圆心
# 图像显示
plt.figure(figsize=(5, 4), dpi=100)
plt.imshow(planets[:, :, ::-1])
plt.title("霍夫圆检测")
plt.xticks([])
plt.yticks([])
plt.show()
else:
print("未检测到圆")