harris detected算法浅析+python代码实现浅析

一、Harris Detected算法浅析

昨晚在课程中学习了一个叫拐角检测的算法:harris detected算法,该算法的成效:

上图是我自己画的一个不规则的四方形(准确的说还不是,左上角的拐点还有线段突出),再看下这张:

再来一张:

 这三张图的成效可以说还是能做到通过拐点的标记然后连线后大致能知道物体是什么的,暂且不去猜测该算法的具体用处在哪,在这里引用:https://blog.csdn.net/Zachary_Co/article/details/78819928

 

特征点:

定义:在图像中一般有具体的坐标,并具有某些数学特征,如局部最大或最小灰度、以及某些梯度特征等。

角点:

定义:

可以简单的认为是两条边的交点,又称拐点。比较严格的定义则是在邻域内具有两个主方向的特征点,也就是说在两个方向上灰度变化剧烈。

如下图所示(引用地址:https://blog.csdn.net/Zachary_Co/article/details/78819928),在各个方向上移动小窗口,如果在所有方向上移动,窗口内灰度都发生变化,则认为是角点;如果所有方向都不变化,则是均匀区域(就是图片内的区域);如果灰度只在一个方向上变化,则可能是图像边缘

 

 

我作为一个初学者,看到这还是能看懂的,接下来,引用另一个作者的观点:

(引用出处:https://www.cnblogs.com/DOMLX/p/8763369.html

 

该作者阐述思想是:

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

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

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

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

该作者是从框子里的区域移动是否会影响图片的像素值的方向去阐述的。 

综合上述的介绍,我大概知道了是怎么回事,于是整理了相关的资料,进行了相关的公式推导:

上述公式可以理解为当窗口移动(不管什么方向,不管此时在什么位置)(u,v)个距离后的差异总和,要想检测到拐点,就要让E(u,v)的值最大化才对,那么到底多大才对?

暂且不谈论上述红体字的问题,我先接着解释,要让E(u,v)最大,作者说必须使方程右侧的第二项的取值最大,即:

那么按照网上的做法,将窗口平移后的图像进行泰勒一阶展开:

所以:

 到了这步我会在想,这怎么去求E(u,v)的值?看到网上的做法是,我怀疑这里是在求E(u,v)的特征值,但是数学这块都忘记了差不多了,明天给老师发邮件问下吧。 (注意:(这里 I x 和 I y 是图像在 x 和 y 方向的导数))

图1

之后, 作者到这就将E(u,v)函数从本质上解释成了椭圆函数:

图2

 

 

 

TA说道:

二次项函数本质上是一个椭圆函数,所以将图2中的公式改写为下面的椭圆公式。椭圆的曲率和尺寸可由M(x,y)的特征值λ1,λ2决定,椭圆方向由M(x,y)的特征向量决定,所以图2中的公式顺利转化为图三中的椭圆公式了:

图3

 

重点来了,先停止,分析下实际平移过程中我们的平移窗口与边缘的导数情况:

 

然后根据公下列公式进行打分评估,R值很大的话就是拐点:

 

解释上述公式:

其中det(M)就是行列式M(一个具体的值),trace(M)为矩阵M的迹,R值越大,说明E(u,v)越大,表明该像素点是拐点

 

k为参数,取值范围为[0.04,0.06],λ 1 和 λ 2 是矩阵 M 的特征值所以根据这些特征中我们可以判断一个区域是否是角点,边界或者是平面。

当 λ 1 和 λ 2 都小时,|R| 也小,这个区域就是一个平面。

当 λ 1 <<λ 2 或者 λ 1 >> λ 2 ,R 小于 0,这个区域是边缘。(>>表示远大于)

当 λ 1 和 λ 2 都很大,并且 λ 1 ~λ 2 中的时,R 也很大,(λ 1 和 λ 2 中的最小值都大于阈值)说明这个区域是角点。

所以我们记住当λ 1 和 λ 2 都很大,并且 λ 1 值与λ 2 相当,该像素点就是拐点。

用下图表示:

 

从上图中看到:在Edge边缘处,椭圆很扁,左上角的 λ 1 <<λ 2 时为什么椭圆是往x轴方向伸长,右下角的λ 1 >>λ 2,为什么椭圆是往y轴伸长? 

其实通过公式推导出在拐角处的边缘处λ 1 和 λ 2之间的大小即椭圆的长轴与短轴的大小,本人觉得是不管是当λ 1 和>λ 2的时候还是当λ 1 <λ 2的时候都不足以确定此处的边缘相对于x轴是平行的还是垂直的。

二、OpenCV 中的 Harris 角点检测

# -*- coding: utf-8 -*-
"""
Created on %(date)s

@author: %(peng.zhou)s
"""


import cv2

import numpy as np

 

#读入图像并转化为float类型,用于传递给harris函数

filename = 'F:/04 Hobby/begi2.jpg'

 

img = cv2.imread(filename)
new_img=cv2.resize(img,(400,600))
cv2.imwrite("F:/04 Hobby/new_img.png",new_img)
#imgre3=cv2.imread('F:/04 Hobby/cutsize.png')
print(str("图片尺寸是:"),new_img.shape)
new_img2=cv2.imread("F:/04 Hobby/new_img.png")

 

gray_img = cv2.cvtColor(new_img2, cv2.COLOR_BGR2GRAY)

 

gray_img = np.float32(gray_img)

 

#对图像执行harris

Harris_detector = cv2.cornerHarris(gray_img, 2, 3, 0.04)

 

#腐蚀harris结果

dst = cv2.dilate(Harris_detector, None)

 

# 设置阈值

thres = 0.01*dst.max()

 

new_img2[dst > thres] = [255,0,0]

 

cv2.imshow('Harris_Detected', new_img2)

 

cv2.waitKey()

在opencv中调用cv2.cornerHarris(Img,blocksize,ksize-soble,k-harris)就是用来进行拐点检测的,其中参数解释如下:

  • img - 数据类型为 float32 的输入图像。
  • blockSize - 角点检测中要考虑的领域大小。
  • ksize - Sobel 求导中使用的窗口大小
  • k - Harris 角点检测方程中的自由参数,取值参数为 [0.04,0.06].

其中new_img2[dst > thres] = [255,0,0]中就是给满足dst > thres条件的像素点上蓝色,([0,0,255]就是红色),其中dst就是前文所说的R值,是所有像素点的R值组成的,若评估某像素点是否是拐点,其中thres = 0.01*dst.max()的意思就是当大于所有像素点的评估出来的R值中的最大值Rmax时,判断该像素点是拐点。

上述就是总结要点了,可能会有些许瑕疵,因为这是我第一次分析图像处理的第一个算法,掌握了套路后,后面的记录会更详细的。

代码在上面已经贴出来了,注意要下载cv包以及修改加载图片的目录即可。

在前进的道路上一起努力。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值