博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《python+opencv实践》四、图像特征提取与描述——30Harris 角点检测
阅读量:4095 次
发布时间:2019-05-25

本文共 3445 字,大约阅读时间需要 11 分钟。

目标
• 理解Harris 角点检测的概念

• 学习函数:cv2.cornerHarris(),cv2.cornerSubPix()

原理

在上一节我们已经知道了角点的一个特性:向任何方向移动变化都很大。Chris_Harris 和Mike_Stephens 早在1988 年的文章《A Combined Corner and Edge Detector》中就已经提出了角点检测的方法,被称为Harris 角点检测。他把这个简单的想法转换成了数学形式。将窗口向各个方向移动(u,v)然后计算所有差异的总和。表达式如下:

窗口函数可以是正常的矩形窗口也可以是对每一个像素给予不同权重的高斯窗口。

角点检测中要使E (u; v) 的值最大。这就是说必须使方程右侧的第二项的取值最大。对上面的等式进行泰勒级数展开然后再通过几步数学换算(可以参考其他标准教材),我们得到下面的等式:

其中:

这里Ix 和Iy 是图像在x 和y 方向的导数。(可以使用函数cv2.Sobel()计算得到)。

然后就是主要部分了。他们根据一个用来判定窗口内是否包含角点的等式进行打分。

其中:

所以根据这些特征中我们可以判断一个区域是否是角点,边界或者是平面。

可以用下图来表示我们的结论:

所以Harris 角点检测的结果是一个由角点分数构成的灰度图像。选取适当的阈值对结果图像进行二值化我们就检测到了图像中的角点。我们将用一个简单的图片来演示一下。

30.1 OpenCV 中的Harris 角点检测

Open 中的函数cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]]) → dst 可以用来进行角点检测。参数如下:

Parameters:

  • src – Input single-channel 8-bit or floating-point image.
  • dst – Image to store the Harris detector responses. It has the typeCV_32FC1 and the same size assrc .
  • blockSize – Neighborhood size (see the details on ).
  • ksize – Aperture parameter for the operator.
  • k – Harris detector free parameter. See the formula below.
  • borderType – Pixel extrapolation method. See .

      • img - 数据类型为float32 的输入图像。

      • blockSize - 角点检测中要考虑的领域大小。
      • ksize - Sobel 求导中使用的窗口大小
      • k - Harris 角点检测方程中的自由参数,取值参数为[0,04,0.06].
例子如下:

# -*- coding: utf-8 -*-"""Created on Mon Jan 20 18:53:24 2014@author: duan"""import cv2import numpy as npfilename = 'chessboard.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 importantdst = 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()
                                   

30.2 亚像素级精确度的角点

有时我们需要最大精度的角点检测。OpenCV 为我们提供了函数cv2.cornerSubPix(),它可以提供亚像素级别的角点检测。下面是一个例子。首先我们要找到Harris角点,然后将角点的重心传给这个函数进行修正。Harris 角点用红色像素标出,绿色像素是修正后的像素。在使用这个函数是我们要定义一个迭代停止条件。当迭代次数达到或者精度条件满足后迭代就会停止。我们同样需要定义进
行角点搜索的邻域大小。

# -*- coding: utf-8 -*-"""Created on Mon Jan 20 18:55:47 2014@author: duan"""import cv2import numpy as npfilename = 'chessboard2.jpg'img = cv2.imread(filename)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# find Harris cornersgray = np.float32(gray)dst = cv2.cornerHarris(gray,2,3,0.04)dst = cv2.dilate(dst,None)ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0)dst = np.uint8(dst)# find centroids#connectedComponentsWithStats(InputArray image, OutputArray labels, OutputArray stats,#OutputArray centroids, int connectivity=8, int ltype=CV_32S)ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)# define the criteria to stop and refine the cornerscriteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)#Python: cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria)#zeroZone – Half of the size of the dead region in the middle of the search zone#over which the summation in the formula below is not done. It is used sometimes# to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1)# indicates that there is no such a size.# 返回值由角点坐标组成的一个数组(而非图像)corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)# Now draw themres = np.hstack((centroids,corners))#np.int0 可以用来省略小数点后面的数字(非四五入)。res = np.int0(res)img[res[:,1],res[:,0]]=[0,0,255]img[res[:,3],res[:,2]] = [0,255,0]cv2.imwrite('subpixel5.png',img)
结果如下,为了方便查看我们对角点的部分进行了放大:

你可能感兴趣的文章
bzoj-1588 1588: [HNOI2002]营业额统计(BST)
查看>>
C# 7个读写Excel文件的类库
查看>>
DevOps的基本原则与介绍
查看>>
[English] Time complexity wise this solution is the best among all
查看>>
字典(python)
查看>>
maven联通网络不能访问中央仓库
查看>>
map函数、filer函数、reduce函数的用法和区别
查看>>
用v-for进行table循环
查看>>
航测数据考点
查看>>
coredump产生的几种可能情况
查看>>
规范文档
查看>>
docker学习系列(一):docker 基础
查看>>
c语言章节10
查看>>
easyui js基础
查看>>
ubuntu安装显卡驱动和cuda
查看>>
Java String StringBuffer StringBuilder
查看>>
JavaScript---循环与闭包
查看>>
Leetcode 56: Merge Intervals
查看>>
Lua中and、or的一些特殊用法
查看>>
在IIS下部署SSL证书实现HTTPS
查看>>