计算机视觉第三次实验——SIFT特征提取与检索

计算机视觉第三次实验——SIFT特征提取与检索

一,安装VLfeat
1.1 下载地址

首先,在使用SIFT算法的时候,我们需要用到python的第三方库VLfeat。其中包含了SIFT算法以及其他的函数方法。下载链接: http://www.vlfeat.org/download/

1.2 注意

这里应该下载0.9.20版本的才可用,我下载的是vIfeat-0.9.20-bin.tar.gz。下载完后解压)

接下来需要进行的操作步骤:
1、把vIfeat文件夹 下win64中的sift.exe和v.dI这两个文件复制到项目的文件夹中。
2、修改Anaconda文件夹下的PCV (我的PCV位置E:\Anaconda\Anaconda3\Lib\site-packages\PCV)文件夹里面的localdescriptors文件夹中的sift.py文件,使用记事本打开,修改其中的cmmd内的路径为: cmmd =str(r"D:\PythonWork\SIFT\sift.exe “+ imagename+”–output=” + resultname+" "+params) (路径是你项目文件夹中的ift.exe的路径)然后要记得在括号内加r! !不然会出错! !

然后就能够运行了。如果在运行过程中提示关于print的错误,记得根据错误提醒的文件夹,去修改相应的print语法, 3.5的python的print用法是需要加括号。

二,获取像素集

在这里插入图片描述

三,描述子代码了实现
3.1 代码
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from numpy import *
import os

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')

imname = r'C:\Users\59287\PycharmProjects\untitled1\sift\15.jpg'
im1 = array(Image.open(imname).convert('L'))
process_image(imname, '15.sift')
l1,d1 = read_features_from_file('15.sift')

figure()
gray()
plot_features(im1, l1, circle=True)
show()

3.2 结果

在这里插入图片描述

四,匹配描述子代码实现

对于将一幅图像中的特征匹配到另一幅图像的特征,一种稳健的准则(是由 Lowe 提出的)是使用这两个特征距离和两个最匹配特征距离的比率。相比于图像 中的其他特征,该准则保证能够找到足够相似的唯一特征。使用该方法可以使错误 的匹配数降低。

4.1代码
# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from numpy import *
import os

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')

def match(desc1, desc2):
    """对于第一幅图像中的每个描述子,选取其在第二幅图像中的匹配
    输入:desc1(第一幅图像中的描述子),desc2(第二幅图像中的描述子)"""
    desc1 = array([d/linalg.norm(d) for d in desc1])
    desc2 = array([d/linalg.norm(d) for d in desc2])

    dist_ratio = 0.6
    desc1_size = desc1.shape
    matchscores = zeros((desc1_size[0],1),'int')
    desc2t = desc2.T #预先计算矩阵转置
    for i in range(desc1_size[0]):
        dotprods = dot(desc1[i,:],desc2t) #向量点乘
        dotprods = 0.9999*dotprods
        # 反余弦和反排序,返回第二幅图像中特征的索引
        indx = argsort(arccos(dotprods))

        #检查最近邻的角度是否小于dist_ratio乘以第二近邻的角度
        if arccos(dotprods)[indx[0]] < dist_ratio * arccos(dotprods)[indx[1]]:
            matchscores[i] = int(indx[0])

    return matchscores

def match_twosided(desc1, desc2):
    """双向对称版本的match()"""
    matches_12 = match(desc1, desc2)
    matches_21 = match(desc2, desc1)

    ndx_12 = matches_12.nonzero()[0]

    # 去除不对称的匹配
    for n in ndx_12:
        if matches_21[int(matches_12[n])] != n:
            matches_12[n] = 0

    return matches_12

def appendimages(im1, im2):
    """返回将两幅图像并排拼接成的一幅新图像"""
    #选取具有最少行数的图像,然后填充足够的空行
    rows1 = im1.shape[0]
    rows2 = im2.shape[0]

    if rows1 < rows2:
        im1 = concatenate((im1, zeros((rows2-rows1,im1.shape[1]))),axis=0)
    elif rows1 >rows2:
        im2 = concatenate((im2, zeros((rows1-rows2,im2.shape[1]))),axis=0)
    return concatenate((im1,im2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值