您现在的位置是:主页 > news > 广州海珠做网站/发软文的网站
广州海珠做网站/发软文的网站
admin2025/4/29 3:10:09【news】
简介广州海珠做网站,发软文的网站,多店铺商城系统开发,高端建设响应式网站Harris角点检测论文“A combined corner and edge detector”,关于HARRIS角点检测有很多文章已经说的挺好的,如[3][4],在这篇文章,将简单介绍Harris角点检测,更主要是研究背后的数学原理,以及更深层次的理解…
Harris角点检测论文“A combined corner and edge detector”,关于HARRIS角点检测有很多文章已经说的挺好的,如[3][4],在这篇文章,将简单介绍Harris角点检测,更主要是研究背后的数学原理,以及更深层次的理解协方差矩阵,特征值和特征向量在图像中更多的应用。并用简单的python代码实现该算法
Harris角点检测的基本思想是,当一个
滑动窗口中心位于位于角点
位置的时候, 滑动窗口微小的
方向的移动造成窗口内的像素变化是非常大的,
图片来自[3]
窗口所有的像素在移动
的变化量可以用加权(w可用高斯核)的均方差表示:
图片来自[3]
根据泰勒公式
于是:
在这里M为半正定矩阵
,是一个椭圆方程,可参考[5]
椭圆方程二维空间
写成矩阵形式:
特征值为
特征向量
对于
由矩阵正交分解得到,可以理解为将
映射到特征向量坐标系,
那么现在我们知道,对于M来说,我们可以求得该矩阵特征值,特征值大小就代表着像素灰度值沿着对应特征向量方向变化的快慢了。特征值与角点的关系[4]
关于特征值,特征向量求法:
特征值
特征向量
判断是否为角点的响应值k一般取值0.04~0.06
为什么R可以很好的区分角点,可以画一张图来可视化一下图片来自[4]
代码实现以及结果如下,可以看出在角点响应最大,edge响应最小:
# -*- coding: utf-8 -*-
"""Created on Tue May 26 17:30:42 2020@author: 73766"""
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as signal
import math
import cv2
img = cv2.imread("D:\\datas\\2020.png")
img = np.mean(np.float32(img), axis=2)
suanzi_x = np.array([[1, 0, -1],
[ 2, 0, -2],
[ 1, 0, -1]])
suanzi_y = np.array([[ 1, 2, 1],
[ 0, 0, 0],
[ -1, -2, -1]])
grad_x = signal.convolve2d(img,suanzi_x,mode="same")
grad_y = signal.convolve2d(img,suanzi_y,mode="same")
Ixx = grad_x*grad_x
Iyy = grad_y*grad_y
Ixy = grad_x*grad_y
#加权的W,这里权重都取1
Ixx_w =cv2.blur(Ixx,(3,3))
Iyy_w =cv2.blur(Iyy,(3,3))
Ixy_w =cv2.blur(Ixy,(3,3))
H = img.shape[0]
L = img.shape[1]
corners = np.zeros((H,L),dtype=np.float32)
for i in range(H):
for j in range(L):
ixx = Ixx_w[i,j]
iyy = Iyy_w[i,j]
ixy = Ixy_w[i,j]
trace_ = ixx + iyy
det = ixx * iyy - ixy*ixy
corners[i][j] = det - 0.05*trace_**2
plt.figure()
plt.imshow(img,"gray") # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()
plt.figure()
plt.imshow(corners,"gray") # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()
现在我们知道,
大小可以反映哪里是角点,哪里是边缘。那么,怎么知道边缘的方向呢?
有一种可行办法就是利用大的特征值对应的特征向量,计算该向量与坐标轴的夹角,就是边缘的方向,具体可参考[1],该论文还给出另一种判断脊线的方法,
来判断脊线响应强弱。根据公式(8),可以得到夹角计算方式如下:
代码和结果如下:
# -*- coding: utf-8 -*-
"""
Created on Tue May 26 17:30:42 2020
@author: Cheng
"""
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as signal
import math
import cv2
def get_nodes(i,j,B,theta):
print(theta/3.14*180)
x1 = i*B + B//2
y1 = j*B + B//2
x0 = x1 + B//2 * np.cos(theta)
y0 = y1 - B//2 * np.sin(theta)
return x0,y0,x1,y1
def draw_angle(img,Theta,B):
H = img.shape[0]//B
L = img.shape[1]//B
for i in range(H):
for j in range(L):
theta = Theta[i][j]/180*3.1415
x0,y0,x1,y1 = get_nodes(j,i,B,theta)
cv2.circle(img, (int(x1), int(y1)), 2, (0, 0, 255), 0)
cv2.line(img, (int(x0), int(y0)), (int(x1), int(y1)), (255, 0, 0), 2)
img1 = cv2.imread("D:\\datas\\luoxuan1.png")
img = np.mean(np.float32(img1), axis=2)
suanzi_x = np.array([[1, 0, -1],
[ 2, 0, -2],
[ 1, 0, -1]])
suanzi_y = np.array([[ 1, 2, 1],
[ 0, 0, 0],
[ -1, -2, -1]])
grad_x = signal.convolve2d(img,suanzi_x,mode="same")
grad_y = signal.convolve2d(img,suanzi_y,mode="same")
Ixx = grad_x*grad_x
Iyy = grad_y*grad_y
Ixy = grad_x*grad_y
#加权的W,这里权重都取1
Ixx_w =cv2.blur(Ixx,(9,9))
Iyy_w =cv2.blur(Iyy,(9,9))
Ixy_w =cv2.blur(Ixy,(9,9))
B = 30
H = img.shape[0]//B
L = img.shape[1]//B
theta = np.zeros((H,L),dtype=np.float32)
edges = np.zeros((H,L),dtype=np.float32)
for i in range(H):
for j in range(L):
ixx = Ixx_w[i*B+B//2,j*B+B//2]
iyy = Iyy_w[i*B+B//2,j*B+B//2]
ixy = Ixy_w[i*B+B//2,j*B+B//2]
vec1 = np.array([2*ixy,ixx - iyy - np.sqrt((ixx - iyy)**2 + 4*ixy ** 2)])
theta[i][j] = math.atan2(vec1[1], vec1[0])/3.1415*180 + 180
draw_angle(img1,theta,B)
plt.figure()
plt.imshow(img1,"gray") # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()
plt.figure()
plt.imshow(theta) # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()原图来自网络
参考文献
[1].Image field categorization and edge/corner detection from gradient covariance
[2].A combined corner and edge detector