目录
一、模板匹配
模板匹配就是用模板图(通常是一个小图)在目标图像(通常是一个比模板图大的图片)中不断的滑动比较,通过某种比较方法来判断是否匹配成功,找到模板图所在的位置
1、匹配方法
python
res=cv2.matchTemplate(image, templ, method)
image:原图像,这是一个灰度图像或彩色图像(在这种情况下,匹配将在每个通道上独立进行)
templ:模板图像,也是灰度图像或与原图像相同通道数的彩色图像
method:匹配方法:
cv2.TM_CCOEFF; cv2.TM_CCOEFF_NORMED
cv2.TM_CCORR; cv2.TM_CCORR_NORMED
cv2.TM_SQDIFF; cv2.TM_SQDIFF_NORMED
res:函数在完成图像模板匹配后返回一个结果矩阵,这个矩阵的大小与原图像不相同。矩阵的每个元素表示原图像中相应位置与模板图像匹配的相似度
(SQDIFF的两种方法,返回值越接近0,匹配程度越好,最小值对应的最佳匹配位置;
CCORR的两种方法,返回值越大,匹配程度越好,最大值对应的最佳匹配位置;
CCOEFF的两种方法,返回值越大,匹配程度越好,最大值对应的最佳匹配位置。)
2、绘制轮廓
找的目标图像中匹配程度最高的点,我们可以设定一个匹配阈值来筛选出多个匹配程度高的区域
python
loc=np.where(array > 0.8) #返回array中所有大于0.8的元素索引的数组
zip(*loc) #对loc解包,把单独的参数传递给zip,将这些数组按元素一一配对(表示一个坐标点)
案例:
python
import cv2 as cv
import numpy as np
# 读图
img=cv.imread("../images/game.png")
gray_img=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
temp=cv.imread("../images/temp.png")
gray_temp=cv.cvtColor(temp,cv.COLOR_BGR2GRAY)
h,w=gray_temp.shape
# 模板匹配 拿到匹配结果矩
res=cv.matchTemplate(gray_img,gray_temp,cv.TM_CCOEFF_NORMED)
# 设置阈值
thresh=0.8
# 获取匹配上的结果的索引
loc=np.where(res>=thresh)
# 解包,拿到成对的x y索引
# print(zip(*loc))
for i in zip(*loc):
x,y=i[1],i[0]
cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),1)
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()
二、霍夫变换
1、概念
霍夫变换 是图像处理的一种技术,主要用于检测图像中的直线、圆等几何形状。基本思想就是将图像空间中的点映射到参数空间 中,通过在参数空间中寻找累计最大值实现对特定形状的检测
2、(标准)霍夫直线变换
python
lines=cv2.HoughLines(image, rho, theta, threshold)
lines:一个二维数组,每一行代表一条直线在霍夫空间中的参数 (rho, theta)
image:输入图像,通常为二值图像,白点表示边缘点,黑点为背景
rho:r的精度,以像素为单位,表示霍夫空间中每一步的距离增量, 值越大,考虑越多的线
theta:角度θ的精度,通常以弧度为单位,表示霍夫空间中每一步的角度增量。值越小,考虑越 多的线
threshold:累加数阈值,只有累积投票数超过这个阈值的候选直线才会被返回
python
import cv2 as cv
import numpy as np
img=cv.imread("../../images/huofu.png")
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
_,binary=cv.threshold(gray,127,255,cv.THRESH_BINARY)
# 边缘检测
edges=cv.Canny(binary,30,70)
#霍夫变换 返回的是[r,theta]
lines=cv.HoughLines(edges,0.8,np.pi/180,90)
for line in lines:
r,theta=line[0]
sin_theta=np.sin(theta)
cos_theta=np.cos(theta)
x1,x2=0,img.shape[1]
y1=int((r-x1*cos_theta)/sin_theta)
y2=int((r-x2*cos_theta)/sin_theta)
cv.line(img,(x1,y1),(x2,y2),(0,255,0),1)
3、统计概率霍夫直线变换
一种改进的霍夫变换,它在获取到直线之后,会检测原图中在该直线上的点,并获取到两侧的端点坐标,然后通过两个点的坐标来计算该直线的长度,通过直线长度与最短长度阈值的比较来决定该直线要不要被保留
python
cv2.HoughLinesP(image, rho, theta, threshold, lines, minLineLength, maxLineGap)
image:通常为二值图像,其中白点表示边缘点,黑点为背景
rho:极径分辨率,以像素为单位,表示极坐标系中的距离分辨率
theta:极角分辨率,以弧度为单位,表示极坐标系中角度的分辨率
threshold:阈值,用于过滤掉弱检测结果,只有累计投票数超过这个阈值的直线才会被返回
lines(可选):一个可初始化的输出数组,用于存储检测到的直线参数
minLineLength(可选):最短长度阈值,比这个长度短的线会被排除
maxLineGap(可选):同一直线两点之间的最大距离
(返回值是一个二维数组,每个元素是一个包含4个元素的数组,分别表示每条直线的起始点和结束点在图像中的坐标(x1, y1, x2, y2) )

4、霍夫圆变换
霍夫圆变换跟直线变换类似,它可以从图像中找出潜在的圆形结构,并返回它们的中心坐标和半径。只不过线是用(r,θ)表示,圆是用(x_center,y_center,r)来表示,从二维变成了三维,数据量变大了很多;所以一般使用霍夫梯度法减少计算量
python
circles=cv2.HoughCircles(image, method, dp, minDist, param1, param2)
circles:一个二维numpy数组,包含所有满足条件的圆的参数
image:通常是灰度图像
method:霍夫梯度法,可以是 cv2.HOUGH_GRADIENT
,这是唯一在OpenCV中用于圆检测的方法
dp:累加器分辨率与输入图像分辨率之间的降采样比率,用于加速运算但不影响准确性。设置为1 表示霍夫梯度法中累加器图像的分辨率与原图一致
minDist:检测到的圆心之间的最小允许距离,以像素为单位。为了过滤掉过于接近的圆检测结果,避免检测结果过于密集。
param1 和 param2:是在使用**cv2.HOUGH_GRADIENT
** 方法时的特定参数
param1(可选):阈值1,决定边缘强度的阈值
param2:阈值2,控制圆心识别的精确度。较高的 param2
值意味着对圆的检测更严格,只有 在累加器中积累了足够高的响应值才认为是真实的圆;较低的 param2
值则会降低 检测的门槛,可能会检测到更多潜在的圆,但也可能包含更多的误检结果
