在手写SIFT算法代码时,涉及关键点的精确定位,基本思想就是将高斯差分空间中提取出的极值点进行一个曲面的拟合,网上参考一个博主的代码:
https://blog.csdn.net/qq_25847123/article/details/79148333
不过是matlab版的,改写成python并将有些地方做了修改。
1 效果
最终的效果图如下:
![](https://i-blog.csdnimg.cn/blog_migrate/9f8460e21fbcb56d6a6720e8ade8eb69.png)
2 代码
import numpy as np
import math
import matplotlib.pyplot as plt
if __name__ == '__main__':
X = np.asarray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Y = np.asarray([6, 2, 3, 12, 9, 9, 7, 3, 1, 9])
Z = np.asarray([3, 2, 5, 6, 3, 9, 11, 9, 8, 12])
n = np.size(X, 0) # 必须保证 n = 1+2+3+...+m, m为整数
m = int(np.floor(math.sqrt(2 * n)) - 1) # 计算相应目标函数的阶数, 从 0 阶开始
# %% 数据计算准备
# % tt 中的内容及意义
# % 0 阶 1阶 2阶 3阶
# % x的次幂 0 , 0 1 , 0 1 2 , 0 1 2 3 , ...
# % y的次幂 0 , 1 0 . 2 1 0 , 3 2 1 0 , ...
tt = np.zeros((2, n))
k = 1
tt[0][0] = 0
tt[1][0] = 0
for i in range(1, 4):
for j in range(0, i + 1):
tt[0][k] = j
tt[1][k] = i - j
k = k + 1
# %% 根据tt, X, Y, 计算相应的系数矩阵 A
A = np.ones((n, n))
for i in range(0, n):
k = 0
for j in range(0, n):
A[i][j] = math.pow(X[i], tt[0][k]) * math.pow(Y[i], tt[1][k])
k = k + 1
c = np.matmul(np.linalg.inv(A), np.asmatrix(Z).T) # 得到目标函数的系数, 即得到 z = f(x,y) ,需对Z做共轭转置
# % % 绘制目标拟合函数图
# % z = f(x, y)
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.scatter3D(X, Y, Z) # 绘制散点图
X = np.arange(min(X), max(X), 0.5)
Y = np.arange(min(Y), max(Y), 0.5)
x, y = np.meshgrid(X, Y)
# 计算z值
z = np.zeros((np.size(x, 0), np.size(x, 1))) # % 只是赋予z和x同样的规格
for i in range(0, np.size(x, 0)):
for j in range(0, np.size(x, 1)):
for k in range(0, n):
z[i][j] = z[i][j] + c[k] * math.pow(x[i][j], tt[0][k]) * math.pow(y[i][j], tt[1][k])
ax.plot_surface(x, y, z, rstride=1, cstride=1, label='Fitting Curve', cmap='hot')
plt.show()
未经允许禁止转载~