SIFT描述子及特征匹配——python实现

数据集

因为疫情原因没有口罩出门,本实验取了某游戏中英雄的正面,左右侧面,背面全身像作为数据集,共4位英雄,16张全身像。

SIFT描述子

1.原理

SIFT描述子生成过程中,考虑的是该特征点邻域特征点的分布情况(而没有利用全局信息)。本步骤中主要计算过程包括:确定特征点的方向和生成特征描述符。
描述子生成步骤:
1.构造高斯差分空间图像。
2.寻找极大极小值点
3.精确定位极值点
4.选取特征点主方向
5. 构造特征点描述算子。

2.代码

# -*- 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 = 'C:\Python\Pictrue\wangzhe11.jpg'
im = array(Image.open(imname).convert('L'))
sift.process_image(imname, 'empire.sift')
l1, d1 = sift.read_features_from_file('empire.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)
title(u'用圆圈表示SIFT特征尺度',fontproperties=font)

# 检测harris角点
harrisim = harris.compute_harris_response(im)

subplot(133)
filtered_coords = harris.get_harris_points(harrisim, 6, 0.1)
imshow(im)
plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
axis('off')
title(u'特征点',fontproperties=font)

show()

3.结果

sift描述子兴趣点展示
在这里插入图片描述

4.分析

由于代码中的阈值为0.1,直接过滤了亮度较低的点,同时SIFT描述子消除了边界上的点,所以有些建模较平坦或是灰度化后图像亮度较低的英雄会找不到特征点,如下图
在这里插入图片描述

描述子匹配

1.原理

匹配六步骤:
1.生成高斯差分金字塔(DOG金字塔),尺度空间构建
2. 空间极值点检测(关键点的初步查探)
3. 稳定关键点的精确定位
4. 稳定关键点方向信息分配
5. 关键点描述
6. 特征点匹配
具体原理在下面博客中有详细介绍,这里不多赘述

https://www.learnopencv.com/histogram-of-oriented-gradients/

2.代码

from PIL import Image
from pylab import *
import sys
from PCV.localdescriptors import sift


if len(sys.argv) >= 3:
  im1f, im2f = sys.argv[1], sys.argv[2]
else:
#  im1f = '../data/sf_view1.jpg'
#  im2f = '../data/sf_view2.jpg'
  im1f = 'C:\Python\Pictrue\wangzhe\wangzhe1.jpg'
  im2f = 'C:\Python\Pictrue\wangzhe\wangzhe12.jpg'
#  im1f = '../data/climbing_1_small.jpg'
#  im2f = '../data/climbing_2_small.jpg'
im1 = array(Image.open(im1f))
im2 = array(Image.open(im2f))

sift.process_image(im1f, 'out_sift_1.txt')
l1, d1 = sift.read_features_from_file('out_sift_1.txt')
figure()
gray()
subplot(121)
sift.plot_features(im1, l1, circle=False)

sift.process_image(im2f, 'out_sift_2.txt')
l2, d2 = sift.read_features_from_file('out_sift_2.txt')
subplot(122)
sift.plot_features(im2, l2, circle=False)

#matches = sift.match(d1, d2)
matches = sift.match_twosided(d1, d2)
print '{} matches'.format(len(matches.nonzero()[0]))

figure()
gray()
sift.plot_matches(im1, im2, l1, l2, matches, show_below=True)
show()

3.结果

匹配成功1(旋转):
在这里插入图片描述
匹配成功2(全身和特写):
在这里插入图片描述
匹配不成功:
在这里插入图片描述
值得一提的是,我也拿了同一英雄两款差别不大的皮肤进行特征匹配,匹配的结果却不尽如人意:
在这里插入图片描述

4.分析

该小节匹配不成功情况特地选用同系列画风相近皮肤的英雄来做特征匹配,由实验结果可知:对同一英雄进行旋转,匹配成功;对同一英雄进行全身和特写匹配,匹配都成功,需要指出的是,由于英雄有动态特效,每一个时刻英雄的形态可能会有一些细微变化,所以全身和特写这一组匹配的match不多,但仍然是匹配成功;,对不同英雄进行特征匹配匹配失败;同种英雄两个相近皮肤的光照是不一样的,特征匹配也少,由此可见光照对SIFT特征匹配还是有一定影响的。
综上所述可以得到:匹配具有角度和旋转不变性,尺度不变性。

图片可视化匹配

1.原理

1.对图像使用SIFT特征提取,将特征保存在和图像同名的.sift文件中。
2.通过图像间是否具有匹配的局部描述子来定义图像间的连接,确认连接关系。
3.如果图像匹配的数目高于一个阈值(如2),则使用边来连接相应的图像节点。

2.代码

# -*- coding: utf-8 -*-
from pylab import *
from PIL import Image
from PCV.localdescriptors import sift
from PCV.tools import imtools
import pydot
import os

os.environ["PATH"] += os.pathsep + 'E:/Graphviz/bin

""" This is the example graph illustration of matching images from Figure 2-10.
To download the images, see ch2_download_panoramio.py."""

#download_path = "panoimages"  # set this to the path where you downloaded the panoramio images
#path = "/FULLPATH/panoimages/"  # path to save thumbnails (pydot needs the full system path)

download_path = 'C:\Python\Pictrue\wangzhe'  # set this to the path where you downloaded the panoramio images
path = 'C:\Python\Pictrue\wangzhe'  # path to save thumbnails (pydot needs the full system path)

# list of downloaded filenames
imlist = imtools.get_imlist(download_path)
nbr_images = len(imlist)

# extract features
featlist = [imname[:-3] + 'sift' for imname in imlist]
for i, imname in enumerate(imlist):
    sift.process_image(imname, featlist[i])

matchscores = zeros((nbr_images, nbr_images))

for i in range(nbr_images):
    for j in range(i, nbr_images):  # only compute upper triangle
        print 'comparing ', imlist[i], imlist[j]
        l1, d1 = sift.read_features_from_file(featlist[i])
        l2, d2 = sift.read_features_from_file(featlist[j])
        matches = sift.match_twosided(d1, d2)
        nbr_matches = sum(matches > 0)
        print 'number of matches = ', nbr_matches
        matchscores[i, j] = nbr_matches
print "The match scores is: \n", matchscores

# copy values
for i in range(nbr_images):
    for j in range(i + 1, nbr_images):  # no need to copy diagonal
        matchscores[j, i] = matchscores[i, j]

#可视化

threshold = 2  # min number of matches needed to create link

g = pydot.Dot(graph_type='graph')  # don't want the default directed graph

for i in range(nbr_images):
    for j in range(i + 1, nbr_images):
        if matchscores[i, j] > threshold:
            # first image in pair
            im = Image.open(imlist[i])
            im.thumbnail((100, 100))
            filename = path + str(i) + '.png'
            im.save(filename)  # need temporary files of the right size
            g.add_node(pydot.Node(str(i), fontcolor='transparent', shape='rectangle', image=filename))

            # second image in pair
            im = Image.open(imlist[j])
            im.thumbnail((100, 100))
            filename = path + str(j) + '.png'
            im.save(filename)  # need temporary files of the right size
            g.add_node(pydot.Node(str(j), fontcolor='transparent', shape='rectangle', image=filename))

            g.add_edge(pydot.Edge(str(i), str(j)))
g.write_png('lyc.png')

3.结果

在这里插入图片描述

4.分析

输入一张图片,能在数据集中匹配成功,但是如果图片尺寸过大或者图片数量过多会导致匹配时间过长。

遇到的问题及解决方法

1.图片尺寸不同,无法进行特征匹配

由于图片是裁剪而成所以尺寸有些许不同,可是该算法只能对尺寸相同图片进行匹配
解决:使用PS将数据集中图片改成相同大小尺寸
在这里插入图片描述

2.VLfeat无法使用

在安装好VLfeat以后会出现下图错误
在这里插入图片描述
解决方法如下图
在这里插入图片描述

3.下载安装pydot时报错

在这里插入图片描述
百度后发现应该先安装graphviz再安装pydot
graphviz使用

https://graphviz.gitlab.io/_pages/Download/Download_windows.html

然后试了很多方法都不行,最后用了以下步骤
1.先装的全删了
2.换下载源
3.在navigator中下载graphviz
4.配置graphviz的环境变量
5.pip install pydot

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章