返回顶部
首页 > 资讯 > 后端开发 > Python >图像检索之基于vlfeat实现SIFT特征
  • 493
分享到

图像检索之基于vlfeat实现SIFT特征

2024-04-02 19:04:59 493人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

概述 基于内容的图像检索技术是采用某种算法来提取图像中的特征,并将特征存储起来,组成图像特征数据库。当需要检索图像时,采用相同的特征提取技术提取出待检索图像的特征,并根据某种相似性准

概述

基于内容的图像检索技术是采用某种算法来提取图像中的特征,并将特征存储起来,组成图像特征数据库。当需要检索图像时,采用相同的特征提取技术提取出待检索图像的特征,并根据某种相似性准则计算得到特征数据库中图像与待检索图像的相关度,最后通过由大到小排序,得到与待检索图像最相关的图像,实现图像检索。图像检索的结果优劣取决于图像特征提取的好坏,在面对海量数据检索环境中,我们还需要考虑到图像比对(图像相似性考量)的过程,采用高效的算法快速找到相似图像也至关重要。

在构建图像特征库的时候,通常不会使用原始的图像特征,这是由于Raw Feature有很多冗余信息,而且维度过高在构建特征数据库和匹配的时候效率较低。所以,通常要对提取到的原始特征进行重新编码。比较常用的三种编码方式:

  • BoF , Bog of Feature 源于文本处理的词袋模型(Bog,Bag of Words)
  • VLAD , Vector of Aggragate Locally Descriptor
  • FV , fisher vector

构建图像特征数据库,通常有以下几个步骤:

  • 图像预处理流程(增强,旋转,滤波,缩放等)
  • 特征提取(全局特征,局部特征:SIFT,SURF,CNN等)
  • 对每张图片提取的原始特征重新编码(BoF,VLAD,FV)形成图像的特征库

图像的特征库构建完成后,在检索阶段,主要涉及到特征的相似性度量准则,排序,搜索

  • 提取图像的特征,
  • 特征编码
  • 在图像特征库中进行检索
  • 返回相似性较高的结果

SIFT特征

SIFT特征的讲解已经很多了,之前的博客也有过介绍。本文就借助vlfeat对SIFT特征的提取过程做一个总结
一个SIFT特征有两部分组成:关键点(keypoint)和对应特征描述子(Descriptor)。使用SIFT detector 进行SIFT关键点的提取,然后使用SIFT descriptor计算关键点的描述子。也可以独立的使用SIFT detector进行SIFT 关键点的提取,或者使用SIFT descriptor进行别的关键点描述子的计算。

一个SIFT keypoint是一块圆形区域并且带有方向,使用4个参数描述该区域的几何结构:

  • keypoint的中心位置的坐标(x,y)
  • keypoint的scale(圆形区域的半径r)
  • keypoint的方向(使用弧度表示的角度θ)

一个SIFT关键点由4个参数确定:

  • 高斯尺度的组数o=log2min(m,n)−3=log2(512)−3=6
  • 构建第0组,将原图像进行上采样,宽和高增加一倍得到图像I0。
  • 第0层I0∗G(x,y,σ0)
  • 第1层I0∗G(x,y,kσ0)
  • 第2层I0∗G(x,y,k2σ0)
  • 构建第1组,将I0进行降采样,得到图像I1
  • 第0层I1∗G(x,y,2σ0)
  • 第1层I1∗G(x,y,2kσ0)
  • 第2层I1∗G(x,y,2k2σ0)
  • ...
  • 构建第o组,第s层 io∗G(x,y,2oksσ)

在Lowe的算法实现中\(\sigma_0 = 1.6,o_min = -1\)。\(o_min = -1\)表示金字塔的第0组是原图像上采样得到的,宽和高加一倍。

DoG 极值点检测

高斯图像金字塔构建完成后,将同一组的相邻两层相减就得到了\(DoG\)金字塔。

每组的层数\(S = 3\),也就是说每组可以得到两层的\(DoG\)图像,以第一组为例:其尺度为\(\sigma,k\sigma\),只有两项是无法求取极值的,需要左右两边都有尺度。由于无法比较取得极值,那么我们就需要继续对每组的图像进行高斯模糊,使得尺度形成\(\sigma,k\sigma,k^2\sigma,k^3\sigma,k^4\sigma\)这样就可以选择中间的三项\(k\sigma,k^2\sigma,k^3\sigma\)

检测关键点,就是在\(DoG\)的图像空间中寻找极值点,每个像素点要和其图像域(同一尺度空间)和尺度域(相邻的尺度空间)的所有相邻点进行比较,当其大于(或者小于)所有相邻点时,改点就是极值点。如图所示,中间的检测点要和其所在图像的\(3 \times 3\)邻域8个像素点,以及其相邻的上下两层的\(3\times 3\)领域18个像素点,共26个像素点进行比较。

删除不好的极值点

删除两类极值点

  • 在对比度比较低低的区域检测到的极值点
  • 在图像的边缘部分检测到的极值点

确定关键点的方向

统计关键点邻域像素的梯度方向分布来确定关键点的方向。具体步骤如下:

  • 计算以特征点为中心,以\(3 \times1.5 \sigma\)为半径的区域图像的幅角和幅值,每个像点\(L(x,y)\)的梯度的模\(m(x,y)\)以及方向\(\theta(x,y)\)可通过下面公式求得

  • 统计像素点的幅角和幅值的直方图,梯度方向的直方图的横轴是梯度方向的角度(梯度方向的范围是0到360度,直方图每36度一个柱共10个柱,或者没45度一个柱共8个柱),纵轴是梯度方向对应梯度幅值的累加,在直方图的峰值就是特征点的主方向。在梯度直方图中,当存在一个相当于主峰值80%能量的柱值时,则可以将这个方向认为是该特征点辅助方向。所以,一个特征点可能检测到多个方向(也可以理解为,一个特征点可能产生多个坐标、尺度相同,但是方向不同的特征点)。

得到特征点的主方向后,对于每个特征点可以得到三个信息\(k(x,y,r,\theta)\),即位置、尺度和方向。由此可以确定一个SIFT特征区域,一个SIFT特征区域由三个值表示,中心表示特征点位置,半径表示关键点的尺度,箭头表示主方向。
具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等,但是方向不同的特征点。

计算关键点描述子

在检测部分已经得到了SIFT关键点的位置,尺度和方向信息,生成关键点的描述子,就是使用一个向量来描述关键点及其邻域像素的信息。
由以下步骤生成描述子:

  • 为了保证旋转不变性,将关键点为中心的邻域像素的坐标轴进行旋转,将\(x\)轴旋转至关键点主方向,如下图:

  • 分块计算邻域内像素的梯度方向直方图,以关键点为中心的\(16\times16\)的区域内,划分\(4\times4\)个块,分别计算每个块的梯度直方图,如下图:

每个块的梯度直方方向直方图的计算方式,和求关键点主方向时类似:此时每个区域的梯度直方图在0-360之间划分为8个方向区间,每个区间为45度,即每个种子点有8个方向的梯度强度信息,最后将得到的\(4\times4\times8=128\)维的特征向量。

  • 为了去除光照变化的影响,需对上述生成的特征向量进行归一化处理。在归一化处理后,在128维的单位向量中,对大于0.2的要进行截断处理,即大于0.2的值只取0.2,然后重新进行一次归一化处理,其目的是为了提高鉴别性。0.2 是实验得出的经验值。

vlfeat实现的sift特征提取

vlfeat是一个开源的轻量级的计算机视觉库,主要实现图像局部特征的提取和匹配以及一些常用的聚类算法。其对sift特征提取的各个步骤进行了封装,使用的方法如下:

1.调用vl_sift_new初始化VlSiftFilt,设置sift提取时参数信息,如:图像的大小,Octave的个数,每个Octave的中的层数,起始的Octave的index. 各个参数的具体含义可以参考上面sift特征提取的方法。

2.设置剔除不稳定关键点的阈值。在上面提到,sift在进行极值检查后,要剔除两类不稳定的极值点:1.对比度较低区域的极值点;2.边缘部分的极值点。 可以调用

  • vl_sift_set_peak_thresh设置接受极值点是一个关键点的最小对比度。 该值越小,提取到的关键点就越多。
  • y vl_sift_set_edge_thresh()设置一个极值点是在边缘上的阈值。 该值越小,提取到的关键点就越多。

这两个参数对最终提取到的特征点个数有很大的影响。

3.初始化工作完成后,可以循环的对尺度空间的每个Octave进行处理了

  • 调用 vl_sift_process_first_octave()vl_sift_process_next_octave()来计算下一个DoG尺度空间。
  • 调用vl_sift_detect进行关键点提取
  • 对每一个提取到的关键点

vl_sift_calc_keypoint_orientations计算关键点的方向,可能多于一个

l_sift_calc_keypoint_descriptor计算每个方向的特征描述子。

4.vl_sift_delete释放资源。

具体代码如下:


// 初始化
    const string file = "../0.jpg";
    Mat img = imread(file,IMREAD_GRAYSCALE);
    Mat color_img = imread(file);
    Mat float_img;
    img.convertTo(float_img,CV_32F);

    int rows = img.rows;
    int cols = img.cols;
    VlSiftFilt* vl_sift =  vl_sift_new(cols,rows,4,3,0);
    vl_sift_set_peak_thresh(vl_sift,0.04);
    vl_sift_set_edge_thresh(vl_sift,10);

    vl_sift_pix *data = (vl_sift_pix*)(float_img.data);


    vector<VlSifTKEypoint> kpts;
    vector<float*> descriptors;

    vl_sift_extract(vl_sift,data,kpts,descriptors);
    

void vl_sift_extract(VlSiftFilt *vl_sift, vl_sift_pix* data,
                    vector<VlSiftKeypoint> &kpts,vector<float*> &descriptors) {
    
    // Detect keypoint and compute descriptor in each octave
    if(vl_sift_process_first_octave(vl_sift,data) != VL_ERR_EOF){
        while(true){
            vl_sift_detect(vl_sift);

            VlSiftKeypoint* pKpts = vl_sift->keys;
            for(int i = 0; i < vl_sift->nkeys; i ++) {

                double angles[4];
                // 计算特征点的方向,包括主方向和辅方向,最多4个
                int angleCount = vl_sift_calc_keypoint_orientations(vl_sift,angles,pKpts);

                // 对于方向多于一个的特征点,每个方向分别计算特征描述符
                // 并且将特征点复制多个
                for(int i = 0 ; i < angleCount; i ++){
                    float *des = new float[128];
                    vl_sift_calc_keypoint_descriptor(vl_sift,des,pKpts,angles[0]);
                    descriptors.push_back(des);
                    kpts.push_back(*pKpts);
                }
                pKpts ++;
            }    
            // Process next octave
            if(vl_sift_process_next_octave(vl_sift) == VL_ERR_EOF) {
                break ;
            }
        }
    }
}

vlfeat中sift提取接受的是float类型的数据,所以要先将读到的数据图像转换为float
OpenCV中的sift提取的对比结果如下:

  1. vlfeat提取的特征点是用绿色画出来的,共有1961个特征点。
  2. OpenCV的是蓝色,有4617个特征点。

Summary

几年前写过一篇关于SIFT的文章,SIFT特征详解 当时多是从理论上。现在在做图像检索的时候,发现还是有很多东西理解的不是很清晰,比如:关键点的多个方向,不稳定极值点的剔除以及梯度方向直方图计算等等。

正在做一个图像检索的项目,陆续将项目的中学到一些知识总结下来,下一篇是关于均值聚类的,对提取到的图像特征进行聚类生成视觉特征(Visul Feature)

到此这篇关于图像检索之基于vlfeat实现SIFT的文章就介绍到这了,更多相关图像检索vlfeat内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 图像检索之基于vlfeat实现SIFT特征

本文链接: https://lsjlt.com/news/159889.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 图像检索之基于vlfeat实现SIFT特征
    概述 基于内容的图像检索技术是采用某种算法来提取图像中的特征,并将特征存储起来,组成图像特征数据库。当需要检索图像时,采用相同的特征提取技术提取出待检索图像的特征,并根据某种相似性准...
    99+
    2024-04-02
  • 基于OpenCV实现小型的图像数据库检索功能
    本文对前面的几篇文章进行个总结,实现一个小型的图像检索应用。 一个小型的图像检索应用可以分为两部分: train,构建图像集的特征数据库。 retrieval,检索...
    99+
    2024-04-02
  • Python基于Pytorch的特征图提取实例
    目录简述单个图片的提取神经网络的构建特征图的提取可视化展示完整代码总结简述 为了方便理解卷积神经网络的运行过程,需要对卷积神经网络的运行结果进行可视化的展示。 大致可分为如下步骤: ...
    99+
    2024-04-02
  • Python Pytorch学习之图像检索实践
    目录背景图像表现搜索随着电子商务和在线网站的出现,图像检索在我们的日常生活中的应用一直在增加。 亚马逊、阿里巴巴、Myntra等公司一直在大量利用图像检索技术。当然,只有当通常的信息...
    99+
    2024-04-02
  • OpenCV图像特征提取之Shi-Tomasi角点检测算法详解
    目录一.Shi-Tomasi 角点检测算法二.Shi-Tomasi角点检测API函数接口一.Shi-Tomasi 角点检测算法 Harris角点检测基本数学公式如下: &n...
    99+
    2024-04-02
  • 基于Matlab图像处理的公路裂缝检测实现
    目录一、简介1案例背景2理论基础3程序实现二、部分源代码三、运行结果一、简介 1 案例背景 随着国家对公路建设的大力投入,我国的公路通车总里程己经位居世界前列,这样进一步促进了我国经...
    99+
    2024-04-02
  • python OpenCV实现图像特征匹配示例详解
    目录目标Brute-Force匹配器的基础使用ORB描述符进行Brute-Force匹配什么是Matcher对象?带有SIFT描述符和比例测试的Brute-Force匹配基于匹配器的...
    99+
    2023-05-17
    python OpenCV图像特征匹配 python OpenCV
  • 基于OpenCV实现图像分割
    本文实例为大家分享了基于OpenCV实现图像分割的具体代码,供大家参考,具体内容如下 1、图像阈值化 源代码: #include "opencv2/highgui/highgui...
    99+
    2024-04-02
  • 如何基于solr实现全文检索
    这篇文章将为大家详细讲解有关如何基于solr实现全文检索,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以...
    99+
    2023-05-30
    solr
  • Android基于OpenCV实现图像脱色
    目录脱色原理API操作效果源码脱色 Imgproc.cvtColor(rgb, gray, Imgproc.COLOR_RGB2GRAY)可以快速的实现图片脱色,其通过简单的计算将...
    99+
    2024-04-02
  • Android基于OpenCV实现图像修复
    目录图像修复API操作效果源码图像修复 实际应用中,图像常常容易受损,如存在污渍的镜头、旧照片的划痕、人为的涂画(比如马赛克),亦或是图像本身的损坏。将受到损坏的图像尽可能还原成原...
    99+
    2024-04-02
  • 基于PythonOpenCV实现图像的覆盖
    目录前言1.导入相关库2.使用OpenCV读取和显示图像3.从物体的图像中去除背景4.添加对象到背景图像5.结果展示前言 在本文中,我将展示如何将对象从一个图像添加到另一个图像。为此...
    99+
    2024-04-02
  • Android基于OpenCV实现图像金字塔
    目录图像金字塔 高斯金字塔 拉普拉斯金字塔 API 下采样上采样操作操作效果源码 图像金字塔 图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的...
    99+
    2024-04-02
  • 基于Python利用Pygame实现翻转图像
    目录前言:1、垂直翻转图像2、水平方向翻转图像前言: 要翻转图像,我们需要使用pygame.transform.flip(Surface, xbool, ybool) 方法,该方法被...
    99+
    2024-04-02
  • PythonOpenCV实现基于模板的图像拼接
    之前基于特征点的图像拼接如果是多张图,每次计算变换矩阵,都有误差,最后可以图像拼完就变形很大,基于模板的方法可以很好的解决这一问题。 import cv2 import nump...
    99+
    2024-04-02
  • Python基于ImageAI实现图像识别详解
    目录背景简介图像预测算法引入目标检测图像目标检测视频目标检测背景简介 ImageAI是一个面向计算机视觉编程的Python库,支持最先进的机器学习算法。主要图像预测,物体检测,视频对...
    99+
    2023-02-01
    Python ImageAI图像识别 Python 图像识别 Python ImageAI
  • 基于Tensorflow的图像识别怎么实现
    要实现基于Tensorflow的图像识别,可以按照以下步骤进行: 准备数据集:首先需要准备一个包含图像和对应标签的数据集,可以使...
    99+
    2024-03-13
    tensorflow
  • 基于Qt OpenCV怎么实现图像灰度化像素
    这篇文章主要介绍了基于Qt OpenCV怎么实现图像灰度化像素的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Qt OpenCV怎么实现图像灰度化像素文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-07-02
  • 基于QtOpenCV实现图像数据采集软件
    效果图 示例代码 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTimer>...
    99+
    2024-04-02
  • 基于Python实现图像的傅里叶变换
    目录前言(1)基本概念(2)读取图像信息1. 傅里叶变换(1)基本概念(2)numpy实现(3)OpevCV实现 2. 傅里叶逆变换(1)基本概念(2)代码实现前言 首先是本文总体代...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作