SIFT算法之关键点查找
1. 综述
利用SIFT算法找到输入图像的关键点,预期效果如下图所示。
2. 基本实现
2.1 读入图像并利用PIL.ImageOps.grayscale() 函数转换成灰度图,除以255以normalize到[0,1]范围内。
2.2 利用scipy函数scipy.ndimage.gaussian_laplace(input, sigma, output=None, mode='reflect', cval=0.0, **kwargs) 来对图像进行gaussian Laplacian 算子卷积。(函数参数解读见附录1)。 注意此处需要进行scale normalize的操作,对结果乘以sigma*2(可以求平方得到squared laplacian response in scale space. 求平方是为了将白点和黑点统一化)
设置不同的一系列不同的sigma值分别对图像进行卷积。得到一个三维的矩阵,第三个维度为sigma
(由于gaussian Laplacian算子不可以通过分解来降维,所以当sigma变大的时候卷积速度会大幅度下降,所以可以采用skimage.transform.resize(matrix, size = (newx,newy))的方法对图像进行不同程度的降采样然后用同一个gaussian Laplacian算子卷积后再upsample到原来的大小,这个方法可以大幅度提升卷积速度)
2.3 对这个三维的scale space进行nonmaximum suppress,找到矩阵的三维极大值。输出(x,y, 1.414 * sigma)作为圆心坐标(可能会用到IOU,没有实现)
2.4 画图,利用如下函数
def show_all_circles(image, circles, color='r'): """ image: numpy array, representing the grayscsale image cx, cy: numpy arrays or lists, centers of the detected blobs rad: numpy array or list, radius of the detected blobs """ import matplotlib.pyplot as plt from matplotlib.patches import Circle fig, ax = plt.subplots() ax.set_aspect('equal') ax.imshow(image, cmap='gray') for circle in circles: circ = Circle((circle[1], circle[0]), circle[2], color=color, fill=False) ax.add_patch(circ) plt.title('%i circles' % len(circles)) plt.show() return 0
3. 实验结果
4. Difference of Gaussian
In David G. Lowe’s paper, Difference of Gaussian can be viewed as an approximationof the Gaussian Laplace filter. The formula is given as follows:
G(x,y,kσ)-G(x,y,σ)≈(k-1)σ^2 ∇^2 G
TheLHS of the above equation is the original scale-invariant Gaussian Laplacianresponse and the RHS is the difference of two gaussian responses.
What we have to do is to downsample theimage from the original size to several levels and a Gaussian filter with samesigma is applied to each level of image. Rescale every downsampled responsematrix to the original image size and stack each matrix and finally get a 3D arrayand the shape of which is [level, x, y]. Get (levels -1) differences between eachpair of adjacent layers. The rest work of nonmaximum suppression is similar toLaplacian Gaussian method.
(以上英文段落引自本人实验报告)
附录
1. filter函数参数解读
scipy.ndimage.gaussian_laplace(input, sigma, output=None, mode='reflect', cval=0.0, **kwargs)
Parameters: | input : array_like
sigma : scalar or sequence of scalars
output : array, optional
mode : str or sequence, optional
cval : scalar, optional
Extra keyword arguments will be passed to gaussian_filter(). |
---|
2. 如何由函数gaussian_filter的truncate 和 sigma参数确定filter的宽度?
以下引自 Stack Overflow https://stackoverflow.com/questions/25216382/gaussian-filter-in-scip
---------------------------------分割线-----------------------------------------
Check out the source code here: https://github.com/scipy/scipy/blob/master/scipy/ndimage/filters.py
You'll see that gaussian_filter
calls gaussian_filter1d
for each axis. In gaussian_filter1d
, the width of the filter is determined implicitly by the values of sigma
and truncate
. In effect, the width w
is
w = 2*int(truncate*sigma + 0.5) + 1
So
(w