RootSIFT---SIFT图像特征的扩展

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 x x 后,进行如下处理,即可得到 RootSIFT:

[1] - 对特征向量 x x x 进行 l 1 l_1 l1 的归一化得到 x ′ x' x ;

[2] - 对 x ′ x' x的每一个元素求平方根;

[3] - 进行 l 2 l_2 l2归一化.(可选)

  • [3]中,是否进行l2归一化,有些不一致. 在[RootSIFT]论文 中并没有指出需要进行 l2 归一化,但是在 presentation, 却有 l2归一化.

参考:图像检索(4):IF-IDF,RootSift,VLAD – RootSIFT

1. RootSIFT 实现

Python 实现如:

import 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=%s " % (len(kps), descs.shape)
 
# extract RootSIFT descriptors
root_sift = RootSIFT()
(kps, descs) = root_sift.compute(image, kps)
print "RootSIFT: kps=%d, descriptors=%s " % (len(kps), descs.shape)

C++ 实现:

for(int i = 0; i < siftFeature.rows; i ++)
{
    // Conver to float type
    Mat f;
    siftFeature.row(i).convertTo(f,CV_32FC1);

    normalize(f,f,1,0,NORM_L1); // l1 normalize
    sqrt(f,f); // sqrt-root  root-sift
    rootSiftFeature.push_back(f);
}

2. 基于 RootSIFT 的相似图搜索

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV小项目 这是一个个人在使用OpenCV过程中写的一些小项目,以及一些非常有用的OpenCV代码,有些代码是对某论文中的部分实现。 注意:代码是在Xcode里写的,如果要在win下测试,遇到问题自己修改。 opencv-rootsift-py 用python和OpenCV写的一个rootsift实现,其中RootSIFT部分的代码参照Implementing RootSIFT in Python and OpenCV这篇文章所写,通过这个你可以了解Three things everyone should know to improve object retrieval这篇文章中RootSIFT是怎么实现的。 sift(asift)-match-with-ransac-cpp 用C++和OpenCV写的一个图像匹配实现,里面包含了采用1NN匹配可视化、1NN匹配后经RANSAC剔除错配点可视化、1NN/2NN<0.8匹配可视化、1NN/2NN<0.8经 RANSAC剔除错配点可视化四个过程,其中1NN/2NN<0.8匹配过程是Lowe的Raw feature match,具体可以阅读Lowe的Distinctive image features from scale-invariant keypoints这篇文章。这个对图像检索重排非常有用。另外里面还有用OpenCV写的ASIFT,这部分来源于OPENCV ASIFT C++ IMPLEMENTATION,ASIFT还可以到官网页面下载,ASIFT提取的关键点 比SIFT要多得多,速度非常慢,不推荐在对要求实时性的应用中使用。 更多详细的分析可以阅读博文SIFT(ASIFT) Matching with RANSAC。 有用链接 OpenCV3.0文档 // 测试sparse unsigned int centersNum = 10; vector descrNums; descrNums.push_back(8); descrNums.push_back(12); //unsigned int T[] = {1, 2, 1, 3, 2, 5, 4, 3, 10, 5; 4, 2, 6, 5, 2, 5, 4, 6, 2, 4}; unsigned int T[] = {1, 2, 1, 3, 2, 5, 4, 3, 10, 5, 4, 2, 6, 5, 2, 5, 4, 6, 2, 4}; sp_mat Hist(descrNums.size(), centersNum); static long int count = 0; for (int i = 0; i < descrNums.size(); i++){ unsigned int* desrcElementsTmp = new unsigned int[descrNums[i]]; memcpy(desrcElementsTmp, T + count, descrNums[i] * sizeof(T[0])); //cout << desrcElementsTmp[0] << '\t' << desrcElementsTmp[1] << '\t' << desrcElementsTmp[2] << '\t' << desrcElementsTmp[3] << '\t' << desrcElementsTmp[4] << '\t' <<endl; //cout << desrcElementsTmp[5] << '\t' << desrcElementsTmp[6] << '\t' << desrcElementsTmp[7] << '\t' << desrcElementsTmp[8] << '\t' << desrcElementsTmp[9] << '\t' << desrcElementsTmp[10] << '\t' <<endl; //cout << endl; sp_mat X(1, centersNum); X.zeros(); for (int j = 0; j < descrNums[i]; j++){ X(0, desrcElementsTmp[j]-1) += 1; } X.print("X:"); X = X/norm(X, 2); Hist.row(i) = X; count = count + descrNums[i]; delete desrcElementsTmp; } //Hist.print("Hist:");

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值