回顾,上节课你学了什么?
R=cv.matchTemplate(img,template,method)
minVal,maxVal,minLoc,maxLoc=cv.minMaxLoc(R)
lines=cv.HoughLines(img,rho,theta,threshold)
circles=cv.HoughCircles(img,method,dp,minDist,param1=100,param2=100
,minRadius=0,maxRadius=0)
目录
1.图像的角点特征
面特征和边缘特征比较大,无法唯一识别位置,角点特征能够唯一确定位置。一般认为角点和斑点都是较好的图像特征。
2.Harris角点检测
【1】原理
通过局部小窗口观察图像,如果沿着任意方向(u,v)灰度都会变化最大,则认为是角点。
定义灰度差异总和E,角点检测就是使得E最大:
I(x, y)----------------局部窗口的图像灰度,
I(x + u, y + v)-----平移后的图像灰度,
w(x, y)--------------窗口函数,该可以是矩形窗口,也可以是对每一个像素赋予不同权重的高斯窗口
I(x + u, y + v) 一阶泰勒展开有:
Ix,沿x方向导数; Iy,沿y方向导数;可用Soble算子公式计算
代入上述公式:
M决定E大小,M又是Ix,Iy的二次项函数,可以表示为椭圆,俩个轴分别为特征值λ1和λ2,方向为特征矢量决定
如果λ1和λ2都很小认为是面
如果λ1和λ2,有一个远大于另一个,则认为是边缘
如果λ1和λ2都很大,且数值差别不大,则认为是角点
Harris给出的角点计算方法并不需要计算具体的特征值,而是计算一个角点响应值R来判断角点。R的计算公式为:
其中
α常数在0.04-0.06之间
如果R绝对值很小认为是面
如果R<0,则认为是边缘
如果R>0,,则认为是角点
【2】代码API
R=cv.cornerHarris(img,blockSize,ksize,k)
img:输入图像必须是float32可用函数np.float32()
blockSize:角点检测考虑的领域大小
ksize:Sobel算子求导使用的卷积核大小
k:角点检测方程中的自由参数0.04-0.06之间
举例
#8.1
import cv2 as cv import numpy as np import matplotlib.pyplot as plt #解决中文显示问题,固定格式,直接复制下面俩行代码就行 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False #1.读取灰度图像 pic1 =cv.imread("10.jpeg") gray=cv.cvtColor(pic1,cv.COLOR_BGR2GRAY) #2.中值去噪 grayb=cv.medianBlur(gray,5) #3.图像格式转换 grayf=np.float32(grayb) #4.Harris角点检测 R=cv.cornerHarris(grayf,3,3,0.04) #5.绘制角点 pic2=pic1.copy() pic2[R>(0.001*M.max())]=(0,0,255)#该位置为false不会改变,为true改变 #绘制图像 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,10)) axes[0,0].set_title("原图") axes[0,0].imshow(pic1[:,:,::-1]) axes[0,1].set_title("灰度图") axes[0,1].imshow(gray,plt.cm.gray) axes[1,0].set_title("中值去噪") axes[1,0].imshow(grayb,plt.cm.gray) axes[1,1].set_title("绘制角点") axes[1,1].imshow(pic2[:,:,::-1]) plt.show() cv.waitKey(0)
结果:
3.Shi-tomas角点检测
【1】原理
Shi-tomas算法是对Harris算法的改进,只要λ1和λ2中最小特征值大于一个阈值则认为它是角点
R>阈值为角点
【2】代码API
corners=cv.goodFeaturesToTrack(img,maxCorners,qualityLevel,minDistance)
corners:获得角点的集合[[[x1,y1]],[[x2,y2]],[[x3,y3]]...]
img:灰度图
maxCorners:获取角点数目
qualityLevel:最低接受角点质量在0-1之间
minDistance:角点之间最小的欧式距离,避免得到相邻特征点,容差
array=矩阵.ravel() #将矩阵拉伸成为一维数组,针对于有多个[]嵌套组合的数组效果好
矩阵.astype("int") #将矩阵转为int矩阵
举例
#8.2
import cv2 as cv import numpy as np import matplotlib.pyplot as plt #解决中文显示问题,固定格式,直接复制下面俩行代码就行 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False #1.读取灰度图像 pic1 =cv.imread("10.jpeg") gray=cv.cvtColor(pic1,cv.COLOR_BGR2GRAY) #2.Shi-tomax角点检测 corners=cv.goodFeaturesToTrack(gray,100,0.4,10).astype("int") #3.绘制角点 pic2=pic1.copy() for c in corners: x,y=c.ravel() cv.circle(pic2,(x,y),5,(0,0,255),-1) #绘制图像 fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,10)) axes[0,0].set_title("原图") axes[0,0].imshow(pic1[:,:,::-1]) axes[0,1].set_title("灰度图") axes[0,1].imshow(gray,plt.cm.gray) axes[1,1].set_title("绘制角点") axes[1,1].imshow(pic2[:,:,::-1]) plt.show() cv.waitKey(0)
结果:
总结,这节课你学到了什么?
R=cv.cornerHarris(img,blockSize,ksize,k)
corners=cv.goodFeaturesToTrack(img,maxCorners,qualityLevel,minDistance)
array=矩阵.ravel()
矩阵.astype("int")