【火炉炼AI】机器学习048-Harris检测图像角点
(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
角点检测算法大致有三类:基于灰度图像的角点检测,基于二值图像的角点检测,基于轮廓曲线的角点检测。基于灰度图像的角点检测又可分为基于梯度、基于模板和基于模板梯度组合3类方法,其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测算法,Harris角点检测算法、KLT角点检测算法及SUSAN角点检测算法。
1. Harris角点检测器
Harris角点检测主要经过以下步骤:
1,对图像进行高斯滤波
2,对每个像素,估计其垂直方向的梯度大小值,使用近似于导数的核做两次一维卷积。
3,对每一像素核给定的邻域窗口:计算局部结构矩阵和响应函数。
4,选取响应函数的一个阈值,以选择最佳候选角点并完成非极大值抑制。
关于Harris角点检测器的具体算法,可以参考这篇博文:harris角点检测器
下面我们来一步一步的使用Harris来检测图像中的角点
# Harris 角点检测器
img_gray = np.float32(gray) # Harris角点检测器需要float型数据
img_harris = cv2.cornerHarris(img_gray, 7, 5, 0.04) # 使用角点检测
plt.imshow(img_harris,cmap='gray')
上面使用cv2.cornerHarris()函数检测到了图片中的角点,但是从图中可以看出,也检测出了很多边缘线条,故而我们要想办法去掉这些边缘线条而保留角点。
# 为了图像更加平滑,使用膨胀来将图像边缘减小,使得角点更突出
img_harris = cv2.dilate(img_harris, None)
plt.imshow(img_harris,cmap='gray')
从图片中可以看出,经过膨胀操作之后,边缘线条的宽度变小,而角点几乎不变。
但是我们要确定一个角点定义方法,此处我们定义像素值为最大值的1%以上为角点,从代码中可以看出:
# 确定角点的方法:此处我们定义角点为:其像素值为最大值的1%以上为角点,如下:
is_corner=img_harris > 0.01 * img_harris.max()
plt.imshow(is_corner,cmap='gray') # 将角点绘制出来看一下
上面的二值化图可以很明显的判断出哪些是角点,那么将这些角点绘制到原图中是怎么样了?
img[is_corner]=[0, 0, 255] # 用红色标注这些角点
img2=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img2)
可以从图中看出,角点检测的还是比较准确的。
########################小**********结###############################
1,角点的检测有一个难点在于cv2.cornerHarris的参数的选择,这个可能要多次尝试看效果。
2,本项目检测的角点比较准确,有一个重要原因是图片的背景是纯白,背景颜色简单,图片物体前景只是一个箱子,角点非常明显,故而检测比较容易,在其他很多情况下,可能难以简单的获得比较满意的结果。
#################################################################
注:本部分代码已经全部上传到(我的github)上,欢迎下载。
参考资料:
1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译