原文作者:aircraft

原文地址:https://www.cnblogs.com/DOMLX/p/8763369.html

参考文献----------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 实现代码如下:

 # -*- coding: utf-8 -*-

 import cv2
import numpy as np filename = 'chessboard5.jpg'
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = np.float32(gray) # 输入图像必须是 float32 ,最后一个参数在 0.04 到 0.05 之间
dst = cv2.cornerHarris(gray,2,3,0.04) #result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None) # Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255] cv2.imshow('dst',img)
if cv2.waitKey(0) & 0xff == 27:
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   可以根据图像自己选取不过如果太小的话 可能会多圈出几个不同的角点 代码结果上面已经看过了 在放出来一次吧:
      

若有兴趣交流分享技术,可关注本人公众号,里面会不定期的分享各种编程教程,和共享源码,诸如研究分享关于c/c++,python,前端,后端,opencv,halcon,opengl,机器学习深度学习之类有关于基础编程,图像处理和机器视觉开发的知识

cv2.cornerHarris()详解 python+OpenCV 中的 Harris 角点检测的更多相关文章

  1. 详解Python编程中基本的数学计算使用

    详解Python编程中基本的数学计算使用 在Python中,对数的规定比较简单,基本在小学数学水平即可理解. 那么,做为零基础学习这,也就从计算小学数学题目开始吧.因为从这里开始,数学的基础知识列位肯 ...

  2. OpenCV教程(43) harris角的检测(1)

          计算机视觉中,我们经常要匹配两幅图像.匹配的的方式就是通过比较两幅图像中的公共特征,比如边,角,以及图像块(blob)等,来对两幅图像进行匹配.      相对于边,角更适合描述图像特征, ...

  3. Opencv学习笔记------Harris角点检测

    image算法测试iteratoralgorithmfeatures 原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/73 ...

  4. OpenCV教程(45) harris角的检测(3)

          在前面一篇教程中,我们通过取局部最大值的方法来处理检测结果,但是从图像中可以看到harris角的分布并不均匀,在纹理颜色比较深的地方检测的harris角结果更密集一些.本章中,我们使用一个 ...

  5. OpenCV教程(44) harris角的检测(2)

          在上一篇教程中,我们得到的harris特征角二值图中,角的数目特别多,本章我们用一个局部最大化的方法,只保留局部值最大的harris特征角. // Harris角计算 cv::corner ...

  6. 【OpenCV十六新手教程】OpenCV角检测Harris角点检测

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...

  7. 举例详解Python中的split()函数的使用方法

    这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下   函数:sp ...

  8. 详解Python中re.sub--转载

    [背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...

  9. 详解Python中内置的NotImplemented类型的用法

    它是什么? ? 1 2 >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Pyth ...

随机推荐

  1. 九度oj题目1002:Grading

    //不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...

  2. 关于browser-sync(在多个设备上进行网页调试)的问题点总结

    最近在看响应式网站的开发视频,其中有一部分非常有用,就是在多个设备上进行网页调试,通过使用browser-sync来实现,具体的步骤可以参照官网(http://www.browsersync.cn/) ...

  3. 关于classpath

    classpath是用来设计JAVA类文件(.class)所在的路径 classpath的主要作用就是当你在一个shell窗口下执行命令时,可以从在classpath中设置的目录搜索,不用一层再一层的 ...

  4. linux中的颜色控制

    \033[031m  xxx  \033[0m  ---------------------->中间的xxx部分显示为红色,不接后面的\033[0m,则以后显示的都是红色,\033表示开始和结束 ...

  5. docker初次体验-管理MySQL+tomcat镜像

    引言 平时经常用linux,我没少吃苦后悔linux没好好研究研究.装一些软件配一些环境时很是害怕,多亏有了docker.docker是一个应用容器引擎,可以管理很多的软件镜像,这些镜像被官方放在了d ...

  6. 简单的 Promise 实现 一

    const Promise = function(fn){ let state = { pending: "pending", fulfilled: "fulfilled ...

  7. Angular组件——父子组件通讯

    Angular组件间通讯 组件树,1号是根组件AppComponent. 组件之间松耦合,组件之间知道的越少越好. 组件4里面点击按钮,触发组件5的初始化逻辑. 传统做法:在按钮4的点击事件里调用组件 ...

  8. 【Flask】 使用Flask-Moment进行日期时间的管理

    Flask-Moment Flask-Moment又是一个flask的扩展模块,用来处理时间日期等信息.用这个模块主要是考虑到两点,第一是为了让不同时区的用户看到的都是各自时区的实际时间,而不是服务器 ...

  9. iptables.sh 初始化防火墙配置

    #!/bin/bash iptables -F iptables -X iptables -Z iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT ...

  10. codeforce round#466(div.2) B. Our Tanya is Crying Out Loud

    B. Our Tanya is Crying Out Loud time limit per test1 second memory limit per test256 megabytes input ...