AI备忘录 - SIFT
type: channel
link: https://www.aiuai.cn/tag/SIFT/
items: Python - VLFeat sift 特征提取
items: OpenCV - 特征匹配中的 ratio test
items: OpenCV - SIFT 特征提取示例函数
items: OpenCV - SIFT 特征匹配RANSAC优化
items: OpenCV - BF和FLANN特征匹配算法
items: RootSIFT - SIFT 图像特征的扩展
items: OpenCV - SIFT 参数及计算返回结果说明
items: 基于SIFT和BoW的图像内容检索
items: SIFT- Search Site Local Invariant Feature[转]
items: SIFT特征之杂七杂八解析

Python - VLFeat sift 特征提取
type: item
date: 2021-03-03T21:46:00+08:00
description: 关于 VLFeat 的说明可参考：[1] - VLFeat指南——SIFT检测器和描述子 - 2014.11.20[2] - 图像检索(1): 再论SIFT-基于vlfeat实现 - 2018.06.13VLFeat 的参数说明可见：https://www.vlfeat.org/api/sift_8h.html1. 命令行实现1.1. 下载编译vlfeat下载： https://www.vlfeat.org/download.htmlGithub：https://www.github.com/vlfeat/vlfeat.git由于 VLFeat 0.9.21 编译后运行 sift 输出的结果为空，这里采用 VLFeat 0.9.20.wget https://www.vlfeat.org/download/vlfeat-0.9.21.tar.gz tar -xzvf vlfeat-0.9.21.tar.gz cd vlfeat-0.9.20 make即可以在 vlfeat-0.9.20/bin 路径生成 sift 工具.1.2. Python 调用命令行Vlfeat sift：https://www.vlfeat.org/man/sift.htmlimport os from PIL import Image def vlfeat_sift_extract(img_file, params="--edge-thresh 10 --peak-thresh 1"): img_pil = Image.open(img_file).convert('L') gray_imgfile = os.path.basename(img_file) + '.pgm' img_pil.save(gray_imgfile) # sift_file = os.path.basename(img_file) + '.sift' cmd_str = "vlfeat-0.9.20/bin/glnxa64/sift {} --output={} {}".format(gray_imgfile, sift_file, params) msg = os.system(cmd_str) print('[INFO]msg: ', msg)2. Cyvlfeat 实现2.1. 安装Github - menpo/cyvlfeatConda 安装(推荐)：#https://anaconda.org/menpo/cyvlfeat conda install -c conda-forge cyvlfeat # 或pip #pip install cyvlfeat (调用时可能会出错)2.2. 示例import numpy as np from cyvlfeat.sift import sift as vlsift def vlfeat_sift_extract(img_file): img_cv2 = cv2.imread(img_file) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY).astype(np.float32) kp, des = vlsift(gray, peak_thresh=5.0, compute_descriptor=True, float_descriptors=True) sift_vector = kp + des # sift_file = os.path.basename(img_file) + '.sift' np.savetxt(sift_file, np.array(sift_vector), fmt='%0.8f')3. SIFT 可视化import numpy as np import matplotlib.pyplot as plt from PIL import Image def vis_sifts(imgfile, locs, circle=True): def draw_circle(c,r): t = np.arange(0,1.01,.01)*2*np.pi x = r*np.cos(t) + c[0] y = r*np.sin(t) + c[1] plt.plot(x,y,'b',linewidth=2) plt.figure(figsize=(10, 8)) img_pil = Image.open(imgfile) plt.imshow(img_pil) if circle: for p in locs: draw_circle(p[:2],p[2]) else: plt.plot(locs[:,0],locs[:,1],'ob') plt.axis('off') …

OpenCV - 特征匹配中的 ratio test
type: item
date: 2021-02-28T16:20:00+08:00
description: import cv2 # def match_snn(desc1, desc2, snn_th = 0.8): index_params = dict(algorithm=1, trees=4) search_params = dict(checks=128) # or pass empty dictionary matcher = cv2.FlannBasedMatcher(index_params, search_params) matches = matcher.knnMatch(desc1.astype(np.float32), desc2.astype(np.float32), k=2) #ratio test good_matches = [] for m,n in matches: if m.distance < snn_th * n.distance: good_matches.append(m) return good_matches取图像1中的某个关键点，并找出其与图像2中距离最近的前两个关键点，在这两个关键点中，若最近的距离除以次近的距离小于某个阈值，则接受这一对匹配点. 由于特征空间的高维性，相近的距离可能有大量的错误匹配，从而它的ratio值比较高. Lowe推荐ratio的取值为0.8，但通过对大量存在尺度、旋转和亮度变化的两幅图片进行匹配，实验结果表明ratio取值在0. 4~0. 6为最佳，小于0. 4会造成非常少的匹配点，大于0. 6会造成大量的错误匹配点.

OpenCV - SIFT 特征提取示例函数
type: item
date: 2021-02-27T21:35:00+08:00
description: From: https://github.com/ducha-aiki/affnet/blob/master/examples/SIFT-AffNet-HardNet-kornia-matching.ipynbimport cv2 import numpy as np def extract_sift_keypoints_upright(img, n_feat = 5000): sift = cv2.xfeatures2d.SIFT_create(2 * n_feat, contrastThreshold=-10000, edgeThreshold=-10000) keypoints = sift.detect(img, None) response = np.array([kp.response for kp in keypoints]) respSort = np.argsort(response)[::-1] kpts = [cv2.KeyPoint(keypoints[i].pt[0], keypoints[i].pt[1], keypoints[i].size, 0) for i in respSort] kpts_unique = [] for x in kpts: if x not in kpts_unique: kpts_unique.append(x) return kpts_unique[:n_feat] # def match_snn(desc1, desc2, snn_th = 0.8): index_params = dict(algorithm=1, trees=4) search_params = dict(checks=128) # or pass empty dictionary matcher = cv2.FlannBasedMatcher(index_params, search_params) matches = matcher.knnMatch(desc1.astype(np.float32), desc2.astype(np.float32), k=2) good_matches = [] for m,n in matches: if m.distance < snn_th * n.distance: good_matches.append(m) return good_matches

OpenCV - SIFT 特征匹配RANSAC优化
type: item
date: 2021-02-27T18:37:00+08:00
description: 参考：Feature Matching + Homography to find Objects1. 实现如：import numpy as np import cv2 from matplotlib import pyplot as plt MIN_MATCH_COUNT = 10 img1 = cv2.imread('box.png',0) # queryImage img2 = cv2.imread('box_in_scene.png',0) # trainImage # Initiate SIFT detector sift = cv2.SIFT() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks = 50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1,des2,k=2) # store all the good matches as per Lowe's ratio test. good = [] for m,n in matches: if m.distance < 0.7*n.distance: good.append(m) # if len(good)>MIN_MATCH_COUNT: src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) #M: 3x3 变换矩阵. M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0) matchesMask = mask.ravel().tolist() h,w,_ = img1.shape pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts,M) img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA) else: print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT) matchesMask = None # draw_params = dict(matchColor = (0,255,0), # draw matches in green color singlePointColor = None, matchesMask = matchesMask, # draw only inliers flags = 2) img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params) plt.imshow(img3, 'gray'),plt.show()如图：2. 参考[1] - 在OpenCV3中进行特征点筛选与优化-Python版 - 2018.01.12[2] - 为何RANSAC算法提纯SIFT算法后仍存在误匹配对？- 知乎[3] - SIFT图像匹配及其python实现 - 2020.07.09[4] - 【Python计算机视觉编程】第二章 SIFT特征提取与检索及RANSAC实例 - 2020.03.08

OpenCV - BF和FLANN特征匹配算法
type: item
date: 2021-02-20T21:25:00+08:00
description: 1. BF 匹配BF 匹配，Brute-Force Matcher，暴力匹配. 其原理比较简单，首先从集合A中选择一个特征的描述子，然后与集合B中所有的其他特征计算某种相似度，进行匹配，并返回最接近的项.OpenCV 中，首先使用 cv2.BFMatcher()创建 BFMatcher 实例，其包含两个可选参数：normType 和 crossCheck.class BFMatcher(DescriptorMatcher): def create(self, normType=None, crossCheck=None): """ normType：如 NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2. NORM_L1 和 NORM_L2 更适用于 SIFT 和 SURF 描述子; NORM_HAMMING 和 ORB、BRISK、BRIEF 一起使用； NORM_HAMMING2 用于 WTA_K==3或4 的 ORB 描述子. crossCheck：默认为 False，其寻找每个查询描述子的 k 个最近邻. 若值为 True，则 knnMatch() 算法 k=1，仅返回(i, j)的匹配结果， 即集合A中的第 i 个描述子在集合B中的第 j 个描述子是最佳匹配. 也就是说，两个集合中的两个描述子特征是互相匹配的. 其提供连续的结果. 当有足够的匹配项时，其往往能够找到最佳的匹配结果. """ pass实例化 BFMatcher 后，两个重要的方法是 BFMatcher.match() 和 BFMatcher.knnMatch(). 前者仅返回最佳匹配结果，后者返回 k 个最佳匹配结果.类似于 cv2.drawKeypoints() 画出关键点；cv2.drawMatches() 能够画出匹配结果. 其水平的堆叠两幅图像，并画出第一张图像到第二张图像的点连线，以表征最佳匹配. cv2.drawMatchKnn()能够画出 k 个最佳匹配.2. 基于ORB描述子的BF匹配示例import numpy as np import cv2 from matplotlib import pyplot as plt img1 = cv2.imread('box.png',0) # queryImage img2 = cv2.imread('box_in_scene.png',0) # trainImage # Initiate ORB detector orb = cv2.ORB() # find the keypoints and descriptors with SIFT kp1, des1 = orb.detectAndCompute(img1,None) kp2, des2 = orb.detectAndCompute(img2,None) # create BFMatcher object bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) # Match descriptors. matches = bf.match(des1,des2) # Sort them in the order of their distance. matches = sorted(matches, key = lambda x:x.distance) # Draw first 10 matches. img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2) plt.imshow(img3) plt.show()如：3. Matcher 对象matches = bf.match(des1,des2) 得到的结果是 DMatch 对象，其具有如下几个属性：DMatch.distance - 描述子间的距离，值越小越好.DMatch.trainIdx - 训练描述子的索引DMatch.queryIdx - 查询描述子的索引DMatch.imgIdx - 训练图像的索引.4. SIFT 描述子和 Ratio Test 的 BF 匹配这里采用 BFMatcher.knnMatch() 得到 k 个最佳匹配. 示例中，设置 k=2，以便于使用 D.Lowe 在论文中的 ratio test.import numpy as np import cv2 from matplotlib import pyplot as plt img1 = cv2.imread('box.png',0) # queryImage img2 = cv2.imread('box_in_scene.png',0) # …

RootSIFT - SIFT 图像特征的扩展
type: item
date: 2021-02-07T19:28:00+08:00
description: RootSift 是论文 Three things everyone should know to improve object retrieval - 2012 所提出的.A Comparative Analysis of RootSIFT and SIFT Methods for Drowsy Features Extraction - 2020当比较直方图时，使用欧氏距离通常比卡方距离或Hellinger核时的性能差，但是在使用 SIFT 特征点为什么一直都使用欧氏距离呢？不论是对 SIFT 特征点进行匹配，还是对 SIFT 特征集合进行聚类得到视觉词汇表，又或者对图像进行BoW编码，都使用的是欧氏距离. 但是 SIFT 特征描述子本质上也是一种直方图，为什么对 SIFT 特征描述子进行比较的时候要使用欧氏距离呢，有没有一种更精确的比较方法呢？SIFT 描述子统计的是关键点邻域的梯度直方图.论文作者认为之所以一直使用欧氏距离来测量 SIFT 特征的相似度，是由于在 SIFT 提出时，使用的是欧氏距离的度量，可以找出一种比较欧氏距离更为精确的度量方法. 故，提出了RootSift 对 SIFT 特征进行扩展.具体操作如下：在提取到 SIFT 描述向量 $x$ 后，进行如下处理，即可得到 RootSIFT:[1] - 对特征向量 $x$ 进行 $l_1$ 的归一化得到 $x'$;[2] - 对 $x'$ 的每一个元素求平方根；[3] - 进行 $l_2$ 归一化.(可选)[3]中，是否进行l2归一化，有些不一致. 在RootSIFT 论文 中并没有指出需要进行 l2 归一化，但是在 presentation, 却有 l2归一化. 也有认为，显式地执行L2规范化是不需要的. 通过采用L1规范，然后是平方根，已经有L2标准化的特征向量，不需要进一步的标准化.参考：图像检索(4):IF-IDF,RootSift,VLAD -- RootSIFT1. RootSIFT 实现Python 实现如：https://www.pyimagesearch.com/2015/04/13/implementing-rootsift-in-python-and-opencv/https://github.com/jrosebr1/imutils/blob/master/imutils/feature/rootsift.pyimport numpy as np import cv2 class RootSIFT: def __init__(self): # initialize the SIFT feature extractor #OpenCV2.4 # self.extractor = cv2.DescriptorExtractor_create("SIFT") #OpenCV3+ self.extractor = cv2.xfeatures2d.SIFT_create() def compute(self, image, kps, eps=1e-7): # compute SIFT descriptors kps, descs = self.extractor.compute(image, kps) # if there are no keypoints or descriptors, return an empty tuple if len(kps) == 0: return ([], None) # apply the Hellinger kernel by first L1-normalizing and taking the # square-root descs /= (descs.sum(axis=1, keepdims=True) + eps) descs = np.sqrt(descs) #descs /= (np.linalg.norm(descs, axis=1, ord=2) + eps) # return a tuple of the keypoints and descriptors return (kps, descs) # image = cv2.imread("test.jpg") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # detect Difference of Gaussian keypoints in the image sift = cv2.xfeatures2d.SIFT_create() kps, descs = sift.detectAndCompute(img1, None) print "SIFT: kps=%d, descriptors=…

OpenCV - SIFT 参数及计算返回结果说明
type: item
date: 2021-02-07T18:34:00+08:00
description: OpenCV 库中 SIFT 特征提取实现，如：import cv2 sift = cv2.xfeatures2d.SIFT_create() img = cv2.imread('test.jpg') kps, des = sift.detectAndCompute(img, None)1. SIFT_create() 参数def SIFT_create(nfeatures=None, nOctaveLayers=None, contrastThreshold=None, edgeThreshold=None, sigma=None): """ SIFT_create([, nfeatures[, nOctaveLayers[, contrastThreshold[, edgeThreshold[, sigma]]]]]) -> retval Use cv.SIFT_create() instead """其中，[1] - nfeatures：特征点数目（算法对检测出的特征点排名，返回最好的nfeatures个特征点）[2] - nOctaveLayers：金字塔中每组的层数（算法中会自己计算这个值）[3] - contrastThreshold：过滤掉较差的特征点的对阈值. contrastThreshold越大，返回的特征点越少.[4] - edgeThreshold：过滤掉边缘效应的阈值. edgeThreshold越大，特征点越多（被过滤掉的越少）.[5] - sigma：金字塔第0层图像高斯滤波系数.注：[1] - 参数nfeatures指定最终返回的特征点数量，并不影响SIFT特征检测的结果.[2] - 参数nOctaveLayers和sigma主要影响图像高斯金字塔的构成. [3] - contrastThreshold和edgeThreshold 会影响在DOG中寻找极值点的过程与结果.在使用OpenCV SIFT特征检测算子时，如果提取效果不够理想，可根据实际情况调整参数后进行重新提取，如：import cv2 sift = cv2.xfeatures2d.SIFT_create( nfeatures=500, contrastThreshold=0.01, edgeThreshold=30, sigma=1.6) kps, des = sift.detectAndCompute(img_cv2, None)OpenCV 默认参数：nfeatures =0 nOctaveLayers =3 contrastThreshold = 0.04 edgeThreshold = 10 sigma =1.6参考：opencv3.1的SIFT特征检测参数图文详解 - 2016.11.042. kps 与 deskps, des = sift.detectAndCompute(img, None)其中，返回值 des为 128 为向量组成的列表； kps 为关键点列表，每个元素为一个 KeyPoint，其包含信息有：[1] - angle：角度，表示关键点的方向. 为了保证方向不变形，SIFT算法通过对关键点周围邻域进行梯度运算，求得该点方向. -1为初值.[2] - class_id：当要对图片进行分类时，可以用 class_id 对每个特征点进行区分. 未设定时为-1，需要自己设定.[3] - octave：代表是从金字塔哪一层提取的得到的数据. [4] - pt：关键点的坐标(x, y).[5] - response：响应程度，代表该点强壮大小，更确切的说，是该点角点的程度.[6] - size：该点直径的大小

基于SIFT和BoW的图像内容检索
type: item
date: 2021-02-05T21:22:00+08:00
description: 摘自：策略算法工程师之路-基于内容的图像检索BoW - Bag of WordsSIFT - Scale Invariant Feature Transform,基于SIFT和CNN特征的通用检索流程 - AIUAIFrom: https://www.robots.ox.ac.uk/~vgg/publications/2012/Arandjelovic12/presentation.pdf1. BoW 模型BoW 模型最初被用在文本分类中，将文档表示成特征矢量. BoW 模型基本思想是，假定对于一个文本，忽略其词序和语法、句法，仅仅将其看做是一些词汇的集合，而文本中的每个词汇都是独立的. 如：文档1：John likes to watch movies. Mary likes too文档2：John also likes to watch football games.对于给定词典:Vocabulary ={ "John": 1, "likes":2, "to": 3, "watch":4, "movies":5, "also":6, "football":7, "games":8, "Mary": 9, "too": 10 } 上述文档可以表示成:文档1： [1, 2, 1, 1, 1, 0, 0, 0, 1, 1]文档2： [1, 1,1, 1, 0, 1, 1, 1, 0, 0]在计算机图像处理中也借鉴了BOW的思想，假设一张图像是有若干视觉词汇组成. 什么样的视觉词典是期望的?光照不敏感尺度不敏感视角变化不敏感旋转不变...2. SIFTSIFT特征之杂七杂八解析 - AIUAISIFT 算法简单来讲，可分为以下几步：2.1. 多分辨率图像金字塔想象人从不同距离看同一个事物，不同尺度的同一个事物从不同视角反映了事物的本质. 距离越远尺度越小更反映事物的全局特性，相反更反映事物的局部特性.2.2. 极值点检测为了寻找尺度空间的极值点，每个像素点要和其图像域(同一尺度空间)和尺度域(相邻的尺度空间)的所有相邻点进行比较，当其大于(或者小于)所有相邻点时，改点就是极值点. 如图所示，中间的检测点要和其所在图像的3×3邻域8个像素点，以及其相邻的上下两层的3×3领域18个像素点，共26个像素点进行比较. 2.3. 特征点梯度直方图生成通过对特征点周围的像素进行分块，计算块内梯度直方图，生成具有独特性的向量，这个向量是该区域图像信息的一种抽象，具有唯一性. 得到的梯度直方图就是最后SIFT特征向量. SIFT特征点的检测实例如图：3. SIFT 特征构建 BoW对提取的SIFT特征点K-means聚类:如下三个Cluster:如此，每个Cluster的中心即是需要的视觉词典(Visual Vocabulary)，如下:对图像检测出的SIFT特征点，指派给离它最近的中心点(将这一步称为hard-assignment)，如此得到图像的视觉词汇分布. 基于BOW的图像检索算法可以描述如下:[1] - 提取图像库中所有图像的局部特征(如SIFT、SURF、ORB等)，得到特征集合 $F$.[2] - 对特征集合 $F$ 进行聚类，得到 $k$ 个聚类中心 $\lbrace C_i | i = 1,...,k \rbrace$，每个聚类中心 $C_i$ 表示一个视觉词汇. 聚类中心的集合就是视觉词典.[3] - 计算特征 $f_i$ 属于哪个词汇 $C_i$(距离该聚类中心的距离最近.)[4] - 统计每个词汇 $C_i$ 在各图像中出现的频次，得到一维的特征向量，即 BoW 表示.基于BOW的方法仅仅关注图像的局部特征而忽略了图像的全局语义，导致会召回不少语义差异较大的图像.4. Python 实现import cv2 import numpy as np from sklearn.cluster import KMeans from scipy.cluster.vq import * from sklearn import preprocessing from PIL import Image #加载数据集 imgFiles = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'] #聚类中心数/视觉词典数 numWords = 64 #提取图像SIFT特征 sift = cv2.xfeatures2d.SIFT_create() des_list=[] for i in range(0, len(imgFiles)): img=cv2.imread(imgFiles[i]) #转换成灰度图像 gray=cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) #sift kp, …

SIFT- Search Site Local Invariant Feature[转]
type: item
date: 2021-02-02T18:16:00+08:00
description: 原文：Local Invariant Feature Detectors学习、记录、备忘.

SIFT特征之杂七杂八解析
type: item
date: 2021-02-01T20:20:00+08:00
description: SIFT, Scale Invariant Feature Transform，尺度不变特征变换，由加拿大教授David G.Lowe提出的. SIFT特征对旋转、尺度缩放、亮度变化等保持不变性，是一种非常稳定的局部特征.注：该文是学习记录，比较杂七杂八，比较多的复制粘贴，这里提前把相关博文备注如下：[1] - SIFT特征详解-2015.10.03[2] - SIFT - 百度百科[3] - SIFT算法详解-2012.04.28[4] - SIFT特征提取分析 - 2012.06.06[5] - SIFT特征点提取 - 2018.01.15[6] - sift特征提取算法 - 2015.05.23[7] - 【动手学计算机视觉】第七讲：传统目标检测之SIFT特征 - 2019.10.30[8] - python利用opencv实现SIFT特征提取与匹配 - 2020.11.05[9] - 基于SIFT特征的图像检索 vs CNN - 2018.06.12[10] - Implementing sift in python a complete guide-2019[11] - 超强大的SIFT图像匹配技术详细指南（附Python代码）- 2019.11.20[12] - SIFT(尺度不变特征变换) - bilibili1. SIFT 特点图像的局部特征，对旋转、尺度缩放、亮度变化保持不变，对视角变化、仿射变换、噪声也保持一定程度的稳定性.独特性好，信息量丰富，适用于海量特征库进行快速、准确的匹配.多量性，即使是很少几个物体也可以产生大量的SIFT特征高速性，经优化的SIFT匹配算法甚至可以达到实时性扩招性，可以很方便的与其他的特征向量进行联合.SIFT算法可以解决的问题：目标的自身状态、场景所处的环境和成像器材的成像特性等因素影响图像配准、目标识别跟踪的性能. 而SIFT算法在一定程度上可解决：目标的旋转、缩放、平移（RST）图像仿射/投影变换（视点viewpoint）光照影响（illumination）目标遮挡（occlusion）杂物场景（clutter）噪声SIFT算法的实质是在不同的尺度空间上查找关键点(特征点)，并计算出关键点的方向. SIFT所查找到的关键点是一些十分突出，不会因光照，仿射变换和噪音等因素而变化的点，如角点、边缘点、暗区的亮点及亮区的暗点等.2. SIFT 特征检测步骤主要分四步：尺度空间的极值检测 搜索所有尺度空间上的图像，通过高斯微分函数来识别潜在的对尺度和选择不变的兴趣点.特征点定位 在每个候选的位置上，通过一个拟合精细模型来确定位置尺度，关键点的选取依据他们的稳定程度.特征方向赋值 基于图像局部的梯度方向，分配给每个关键点位置一个或多个方向，后续的所有操作都是对于关键点的方向、尺度和位置进行变换，从而提供这些特征的不变性.特征点描述 在每个特征点周围的邻域内，在选定的尺度上测量图像的局部梯度，这些梯度被变换成一种表示，这种表示允许比较大的局部形状的变形和光照变换.3. 尺度空间在一定的范围内，无论物体是大还是小，人眼都可以分辨出来. 然而计算机要有相同的能力却不是那么的容易，在未知的场景中，计算机视觉并不能提供物体的尺度大小，其中的一种方法是把物体不同尺度下的图像都提供给机器，让机器能够对物体在不同的尺度下有一个统一的认知. 在建立统一认知的过程中，要考虑的就是在图像在不同的尺度下都存在的特征点.3.1. 多分辨率图像金字塔在早期图像的多尺度通常使用图像金字塔表示形式. 图像金字塔是同一图像在不同的分辨率下得到的一组结果，其生成过程一般包括两个步骤：对原始图像进行平滑对处理后的图像进行降采样（通常是水平、垂直方向的1/2） 降采样后得到一系列不断尺寸缩小的图像. 显然，一个传统的金字塔中，每一层的图像是其上一层图像长、高的各一半. 多分辨率的图像金字塔虽然生成简单，但其本质是降采样，图像的局部特征则难以保持，也就是无法保持特征的尺度不变形.3.2. 高斯模糊使用高斯模糊技术(Gaussian Blur) 可以用来降低图像中的噪点. 对于图像中的每个像素，高斯模糊技术会基于其相邻像素计算一个值. 以下是应用高斯模糊之前和之后的图像示例. 如图所示，纹理和次要细节将从图像中删除，并且仅保留诸如形状和边缘之类的相关信息.高斯模糊成功地去除了图像中的噪点，强调了图像的重要特征.4. 高斯尺度空间可以通过图像的模糊程度来模拟人在距离物体由远到近时物体在视网膜上成像过程，距离物体越近其尺寸越大图像也越模糊，这就是高斯尺度空间，使用不同的参数模糊图像（分辨率不变），是尺度空间的另一种表现形式. 图像和高斯函数进行卷积运算能够对图像进行模糊，使用不同的“高斯核”可得到不同模糊程度的图像. 一副图像其高…