计算机视觉——SIFT特征匹配

一、SIFT特征匹配原理

1.1简介

  SIFT,也叫尺度不变特征变换算法,是David Lowe于1999年提出的局部特征描述子。SIFT算法的实质是:“不同的尺度空间上查找关键点(特征点),并计算出关键点的方向”。

1.2特点

Sift算子具有以下特性:
(1)Sift特征是图像的局部特征,对平移、旋转、尺度缩放、亮度变化、遮挡和噪声等具有良好的不变性,对视觉变化、仿射变换也保持一定程度的稳定性。
(2)独特性好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配。
(3)多量性,即使少数的几个物体也可以产生大量Sift特征向量。
(4)速度相对较快,经优化的Sift匹配算法甚至可以达到实时的要求。
(5)可扩展性强,可以很方便的与其他形式的特征向量进行联合。

1.3算法步骤

  1. 尺度空间极值检测
      搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
       Lowe使用更为高效的高斯差分算子(DOG)进行极值检测,如下:
    在这里插入图片描述 对应DOG算子建立DOG金字塔(如下图)使用DOG金字塔,每组中相邻上下两层图像相减,得到高斯差分图像。通过高斯差分图像可以看出图像像素值的变化情况。
    在这里插入图片描述

此处高斯金字塔的构建主要为两部分
(1)对图像做不同尺度的高斯模糊
(2)对图像做降采样(隔点采样)
在这里插入图片描述

  当我们得到DoG之后,图像在尺度空间中搜寻局部极值。为了寻找DoG函数的极值点, 每一个像素点要和它所有的相邻点比较,看其是否比它的图像域和尺度域 的相邻点大或者小。如下图所示
在这里插入图片描述
2. 关键点定位
  检测到的极值点是离散空间的极值点,以下通过拟合三维二次函数来精确确定关键点的位置和尺度,同时去除低对比度的关键点和不稳定的边缘响应点(因为DoG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力。
在这里插入图片描述

3…方向确定
  利用直方图统计领域内像素对应的梯度和幅值:梯度方向角为横轴刻度,取45度为一个单位,那么横轴就有8个刻度;纵轴是对应梯度的幅值累加值。取幅值最高的方向为主方向。
在这里插入图片描述
4.关键点描述
  确定描述子采样区域后,生成描述子,为了保证特征矢量具有旋转不变性,需要以特征点为中心,将特征点附近邻域内图像梯度的位置和方向旋转一个方向角θ,即将原图像x轴转到与主方向相同的方向。而后生成特征匹配点。
在这里插入图片描述
关于原理的详细解释可见这位博主的博客非常详细的sift算法原理解析

二、数据集

  本数据集为自行采集的16张主体物体主要为建筑的图像。
在这里插入图片描述

三、SIFT特征检测兴趣点

代码
处理图像部分源码:

def process_image(imagename, resultname, params="--edge-thresh 10 --peak-thresh 5"):
    """ 处理一幅图像,然后将结果保存在文件中"""
 
    if imagename[-3:] != 'pgm':
        #创建一个pgm文件
        im = Image.open(imagename).convert('L')
        im.save('tmp.pgm')
        imagename ='tmp.pgm'
    cmmd = str("sift "+imagename+" --output="+resultname+" "+params)
    os.system(cmmd)
    print ('processed', imagename, 'to', resultname)

读取并保存特征值部分源码:


def read_features_from_file(filename):
    """读取特征属性值,然后将其以矩阵的形式返回"""
    f = loadtxt(filename)
    return f[:,:4], f[:,4:] #特征位置,描述子
 
def write_featrues_to_file(filename, locs, desc):
    """将特征位置和描述子保存到文件中"""
    savetxt(filename, hstack((locs,desc)))

显示特征图像部分源码:

def plot_features(im, locs, circle=False):
    """显示带有特征的图像
       输入:im(数组图像),locs(每个特征的行、列、尺度和朝向)"""
 
    def draw_circle(c,r):
        t = arange(0,1.01,.01)*2*pi
        x = r*cos(t) + c[0]
        y = r*sin(t) + c[1]
        plot(x, y, 'b', linewidth=2)
 
    imshow(im)
    if circle:
        for p in locs:
            draw_circle(p[:2], p[2])
    else:
        plot(locs[:,0], locs[:,1], 'ob')
    axis('off')

主体源码:

# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from PCV.localdescriptors import sift
from PCV.localdescriptors import harris

# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)

imname = 'image/15.jpg'
im = array(Image.open(imname).convert('L'))
sift.process_image(imname, '15.sift')
l1, d1 = sift.read_features_from_file('15.sift')

figure()
gray()
subplot(131)
sift.plot_features(im, l1, circle=False)
title(u'SIFT特征',fontproperties=font)
subplot(132)
sift.plot_features(im, l1, circle=True)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值