cv2.cornerHarris()详解 python+OpenCV 中的 Harris 角点检测

参考文献----------OpenCV-Python-Toturial-中文版.pdf

参考博客----------http://www.bubuko.com/infodetail-2498014.html

不废话进入主题:

角点是一类具有特定特征的点,角点也是处在一个无论框框往哪边移动 框框内像素值都会变化很大的情况而定下来的点 可以这么去理解。。。。

  如上图有三个颜色的框框,如果我们对蓝色框框进行移动,无论是水平 还是垂直的方向移动 都不会对框框内像素造成很大的变化。。。这种是内部区域

  如果我们对黑色的框框进行移动,那么水平方向上移动 像素值是不会有什么太大的变化的 如果是垂直方向上移动那么就会变化很大 这种一般称为边缘区域

  最后的重点  我们对红色的框框进行移动  无论是往哪个方向进行偏移 都会对框框内的像素值 造成很大的变动   那么红色框框 框住的区域的边角点  我们就称为角点   

  通过以上的几句话 我们大家应该大概的理解了角点是什么意思了、、、、

就这样一直说下去 解释下去 肯定是比较枯燥的   大家估计都是想先看看这个cv2.cornerHarris()函数的作用是什么。。。那么我们就先来看看成果图 在解释过程

那些红色的  绿色的就是通过我们函数圈出来的角点。。。

下面就解释一下原理  后面会给出简单的示例代码

在 1988 年的文章《A CombinedCorner and Edge Detector》中就已经提出了焦点检测的方法,被称为Harris 角点检测。他把这个简单的想法转换成了数学形式。将窗口向各个方向移动(u,v)然后计算所有差异的总和。表达式如下:

窗口函数可以是正常的矩形窗口也可以是对每一个像素给予不同权重的高斯窗口 角点检测中要使 E (μ,ν) 的值最大。这就是说必须使方程右侧的第二项的取值最大。对上面的等式进行泰勒级数展开然后再通过几步数学换算(可以参考其他标准教材),我们得到下面的等式:

其中

这里 I x 和 I y 是图像在 x 和 y 方向的导数。(可以使用函数 cv2.Sobel() 计算得到)。 然后就是主要部分了。他们根据一个用来判定窗口内是否包含角点的等式进行打分。

其中

  ? λ 1 和 λ 2 是矩阵 M 的特征值所以根据这些特征中我们可以判断一个区域是否是角点,边界或者是平面。   ? 当 λ 1 和 λ 2 都小时,|R| 也小,这个区域就是一个平坦区域。   ? 当 λ 1 ? λ 2 或者 λ 1 ? λ 2 ,时 R 小于 0,这个区域是边缘   ? 当 λ 1 和 λ 2 都很大,并且 λ 1 ~λ 2 中的时,R 也很大,(λ 1 和 λ 2 中的最小值都大于阈值)说明这个区域是角点。 可以用下图来表示我们的结论:

cv2.cornerHarris()函数的返回值其实就是R值构成的灰度图像 灰度图像坐标会与原图像对应  R值就是角点分数 当R值很大的时候 就可以认为这个点是一个角点

OpenCV 中的 Harris 角点检测 Open 中的函数 cv2.cornerHarris() 可以用来进行角点检测。参数如 下:   • img - 数据类型为 float32 的输入图像。   • blockSize - 角点检测中要考虑的领域大小。   • ksize - Sobel 求导中使用的窗口大小   • k - Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06].

python 实现代码如下:

 1 # -*- coding: utf-8 -*-
 2 
 3 
 4 import cv2
 5 import numpy as np
 6 
 7 
 8 filename = 'chessboard5.jpg'
 9 img = cv2.imread(filename)
10 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
11 gray = np.float32(gray)
12 
13 # 输入图像必须是 float32 ,最后一个参数在 0.04 到 0.05 之间
14 dst = cv2.cornerHarris(gray,2,3,0.04)
15 
16 #result is dilated for marking the corners, not important
17 dst = cv2.dilate(dst,None)
18 
19 # Threshold for an optimal value, it may vary depending on the image.
20 img[dst>0.01*dst.max()]=[0,0,255]
21 
22 cv2.imshow('dst',img)
23 if cv2.waitKey(0) & 0xff == 27:
24     cv2.destroyAllWindows()
 dst = cv2.dilate(dst,None) 这段代码是膨胀 提升后续图像角点标注的清晰准确度  可有可无  也可以注释掉

估计大家最有疑问的应该是:
    img[dst>0.01*dst.max()]=[0,0,255]这段代码是什么意思吧     dst>0.01*dst.max()这么多返回是满足条件的dst索引值  根据索引值来设置这个点的颜色
    这里是设定一个阈值 当大于这个阈值分数的都可以判定为角点  (好像说跟没说一样是吧)hhhh
    在看上面我讲的 这里的dst其实就是一个个角度分数R组成的   当 λ 1 和 λ 2 都很大,并且 λ 1 ~λ 2 中的时,R 也很大,(λ 1 和 λ 2 中的最小值都大于阈值)说明这个区域是角点。
    那么这里为什么要大于0.01×dst.max()呢 注意了这里R是一个很大的值 我们选取里面最大的R 然后 只要dst里面的值大于百分之一的R的最大值  那么此时这个dst的R值也是很大的 可以判定他为角点
    也不一定要0.01   可以根据图像自己选取不过如果太小的话 可能会多圈出几个不同的角点

代码结果上面已经看过了 在放出来一次吧:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏MyBlog

图像增强的几个方法以及Matlab代码

灰度线性变换, 是一种空域的方法, 直接对每一个像素的灰度值进行操作 假设图像为

951
来自专栏Petrichor的专栏

深度学习: sliding window (滑动窗口)

sliding window (滑动窗口) 在深度学习中得到了极其广泛的运用。从卷积层到池化层,都能看见它的身影。

1023
来自专栏媒矿工厂

HDR关键技术—色域映射

HDR系列前几期为大家介绍了HDR的色调映射技术(Tone Mapping)。其中提到:在色调映射环节,为了便于操作,且不使图像颜色产生巨大失真,色调映射算法通...

1413
来自专栏MyBlog

图像增强的几个方法以及Matlab代码

这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比...

1444
来自专栏机器学习算法全栈工程师

人脸Haar特征与快速计算神器:积分图

背景介绍 iPhone十周年纪念之作iPhoneX刚刚发布,其搭载的“刷脸解锁”功能再次将“人脸识别”技术带入大众视野。 借iPhoneX的东风...

39611
来自专栏落影的专栏

GPUImage详细解析(十二)Sobel边界检测

前言 卷积运算是一个看似复杂的概念,今天来揭开这个神秘的面纱。 卷积矩阵:卷积矩阵是一个由权重数据组成的矩阵,中心像素周围像素的亮度乘以这些权重然后再相加就能...

3815
来自专栏贾志刚-OpenCV学堂

TensorFlow进行简单的图像处理

TensorFlow进行简单的图像处理 简单概述 作为计算机视觉开发者,使用TensorFlow进行简单的图像处理是基本技能,而TensorFlow在tf.im...

4278
来自专栏图形学与OpenGL

模拟试题B

1.灰度等级为256级,分辨率为2048*1024的显示器,至少需要的帧缓存容量为( )

931
来自专栏编程

Python数据分析-数据探索下

主题 数据探索 接着上一节的内容~ 二、数据特征分析 5. 相关性分析 (1)直接描述散点图 从散点图可以比较直观地看书两个变量的相关性。(一般分为完全正...

3429
来自专栏ml

深度学习之图像的数据增强

   在图像的深度学习中,为了丰富图像训练集,更好的提取图像特征,泛化模型(防止模型过拟合),一般都会对数据图像进行数据增强, 数据增强,常用的方式,就是旋转图...

6967

扫码关注云+社区