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

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