一、SIFT提出的目的和意義
二、SIFT的特征簡介
三、SIFT算法實現步驟簡述
四、圖像集
五、匹配地理標記圖像
- 代碼
- 結果截圖
- 小結
六、SIFT算法代碼實現
- 代碼
- 結果截圖
- 小結
七、圖像全景拼接RANSAC
八、SIFT實驗總結
九、實驗遇到的問題
一、SIFT提出的目的和意義
1999年David G.Lowe教授總結了基於特征不變技術的檢測方法,在圖像尺度空間基礎上,提出了對圖像縮放、旋轉保持不變性的圖像局部特征描述算子-SIFT(尺度不變特征變換),該算法在2004年被加以完善。
- 目標的旋轉、縮放、平移(RST)
- 圖像仿射/投影變換(視點viewpoint)
- 弱光照影響(illumination)
- 部分目標遮擋(occlusion)
- 雜物場景(clutter)
- 噪聲
操作步驟:
1.把vlfeat文件夾下win64中的sift.exe和vl.dll這兩個文件復制到項目的文件夾中

2.修改PCV文件夾內的(我的PCV位置為D:\Anaconda2\Lib\site-packages\PCV))文件夾里面的localdescriptors文件夾中的sift.py文件,用記事本打開,修改其中的cmmd內的路徑cmmd=str(r"D:\new\sift.exe“+imagename+” --output="+resultname+" "+params) (路徑是你項目文件夾中的sift.exe的路徑)一定要在括號里加上r。


圖2
五、匹配地理標記圖像
1、做此實驗我們需用pydot工具包中的GraphViz,可以點擊https://graphviz.gitlab.io/_pages/Download/Download_windows.html下載安裝包,安裝步驟如下:
配置環境: 保存graphviz安裝時,一定要記住保存路徑,方便找到你的安裝包安裝中的gvedit.exe的位置,我的是C:\Program Files (x86)\Graphviz2.38\bin
把gvedit.exe發送到桌面快捷方式,然后去系統里點擊高級系統設置->點擊環境變量->點擊系統變量的path選擇編輯->輸入C:\Program Files (x86)\Graphviz2.38\bin,之后就確定保存。
接下來是驗證環境配置是否成功,輸入dot -version命令,成功如下:
然后依次執行以下命令:
pip install graphviz
pip install pydot
成功如下:
d
2、實驗代碼:
1 # -*- coding: utf-8 -*- 2 from pylab import * 3 from PIL import Image 4 from PCV.localdescriptors import sift 5 from PCV.tools import imtools 6 import pydot 7 8 """ This is the example graph illustration of matching images from Figure 2-10. 9 To download the images, see ch2_download_panoramio.py.""" 10 11 #download_path = "panoimages" # set this to the path where you downloaded the panoramio images 12 #path = "/FULLPATH/panoimages/" # path to save thumbnails (pydot needs the full system path) 13 14 #download_path = "F:\\dropbox\\Dropbox\\translation\\pcv-notebook\\data\\panoimages" # set this to the path where you downloaded the panoramio images 15 #path = "F:\\dropbox\\Dropbox\\translation\\pcv-notebook\\data\\panoimages\\" # path to save thumbnails (pydot needs the full system path) 16 download_path = "D:/new" 17 path = "D:/new" 18 # list of downloaded filenames 19 imlist = imtools.get_imlist(download_path) 20 nbr_images = len(imlist) 21 22 # extract features 23 featlist = [imname[:-3] + 'sift' for imname in imlist] 24 for i, imname in enumerate(imlist): 25 sift.process_image(imname, featlist[i]) 26 27 matchscores = zeros((nbr_images, nbr_images)) 28 29 for i in range(nbr_images): 30 for j in range(i, nbr_images): # only compute upper triangle 31 print 'comparing ', imlist[i], imlist[j] 32 l1, d1 = sift.read_features_from_file(featlist[i]) 33 l2, d2 = sift.read_features_from_file(featlist[j]) 34 matches = sift.match_twosided(d1, d2) 35 nbr_matches = sum(matches > 0) 36 print 'number of matches = ', nbr_matches 37 matchscores[i, j] = nbr_matches 38 print "The match scores is: %d", matchscores 39 40 #np.savetxt(("../data/panoimages/panoramio_matches.txt",matchscores) 41 42 # copy values 43 for i in range(nbr_images): 44 for j in range(i + 1, nbr_images): # no need to copy diagonal 45 matchscores[j, i] = matchscores[i, j] 46 47 threshold = 2 # min number of matches needed to create link 48 49 g = pydot.Dot(graph_type='graph') # don't want the default directed graph 50 51 for i in range(nbr_images): 52 for j in range(i + 1, nbr_images): 53 if matchscores[i, j] > threshold: 54 # first image in pair 55 im = Image.open(imlist[i]) 56 im.thumbnail((100, 100)) 57 filename = path + str(i) + '.png' 58 im.save(filename) # need temporary files of the right size 59 g.add_node(pydot.Node(str(i), fontcolor='transparent', shape='rectangle', image=filename)) 60 61 # second image in pair 62 im = Image.open(imlist[j]) 63 im.thumbnail((100, 100)) 64 filename = path + str(j) + '.png' 65 im.save(filename) # need temporary files of the right size 66 g.add_node(pydot.Node(str(j), fontcolor='transparent', shape='rectangle', image=filename)) 67 68 g.add_edge(pydot.Edge(str(i), str(j))) 69 g.write_png('protect2.png')
3、結果截圖:
實驗小結:圖像集一共有十九張圖片,運行出來只有十七張圖片,我拍攝的照片范圍過小,只選擇了六個地點拍攝,沒有顯示出來的兩張圖片是跟以上圖片沒有太多相似的特征點的。顯示出來的第一個連線的部分,是在同一個位置拍攝,只是從不同的角度,但是提取出來的特征點匹配度很高,說明了sift算法角度不變性,還有色彩影響不是很大,並且只要有一點特征點匹配度的圖片就會相連起來,第二部分和第三部分依然如此。
代碼:
1 # -*- coding: utf-8 -*- 2 from PIL import Image 3 from pylab import * 4 from PCV.localdescriptors import sift 5 from PCV.localdescriptors import harris 6 7 # 添加中文字體支持 8 from matplotlib.font_manager import FontProperties 9 font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14) 10 11 imname = 'siftt/24.jpg' 12 im = array(Image.open(imname).convert('L')) 13 sift.process_image(imname, '24.sift') 14 l1, d1 = sift.read_features_from_file('24.sift') 15 16 figure() 17 gray() 18 subplot(131) 19 sift.plot_features(im, l1, circle=False) 20 title(u'SIFT特征',fontproperties=font) 21 subplot(132) 22 sift.plot_features(im, l1, circle=True) 23 title(u'用圓圈表示SIFT特征尺度',fontproperties=font) 24 25 # 檢測harris角點 26 harrisim = harris.compute_harris_response(im) 27 28 subplot(133) 29 filtered_coords = harris.get_harris_points(harrisim, 6, 0.1) 30 imshow(im) 31 plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*') 32 axis('off') 33 title(u'Harris角點',fontproperties=font) 34 35 show()
原圖
運行結果:
小結:由圖看出,sift算法檢測出來的特征點比harris角點算法檢測出的角點多。sift算法測出來的特征點大多數都是重合的。
2、圖像集里的所有圖像的sift特征提取
代碼:
1 # -*- coding: utf-8 -*- 2 from PIL import Image 3 from pylab import * 4 from PCV.localdescriptors import sift 5 from PCV.localdescriptors import harris 6 from PCV.tools.imtools import get_imlist # 導入原書的PCV模塊 7 8 # 添加中文字體支持 9 from matplotlib.font_manager import FontProperties 10 font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14) 11 12 # 獲取project2_data文件夾下的圖片文件名(包括后綴名) 13 filelist = get_imlist('siftt/') 14 15 for infile in filelist: # 對文件夾下的每張圖片進行如下操作 16 print(infile) # 輸出文件名 17 18 im = array(Image.open(infile).convert('L')) 19 sift.process_image(infile, 'infile.sift') 20 l1, d1 = sift.read_features_from_file('infile.sift') 21 i=1 22 23 figure(i) 24 i=i+1 25 gray() 26 27 subplot(131) 28 sift.plot_features(im, l1, circle=False) 29 title(u'SIFT特征',fontproperties=font) 30 31 subplot(132) 32 sift.plot_features(im, l1, circle=True) 33 title(u'用圓圈表示SIFT特征尺度',fontproperties=font) 34 35 # 檢測harris角點 36 harrisim = harris.compute_harris_response(im) 37 38 subplot(133) 39 filtered_coords = harris.get_harris_points(harrisim, 6, 0.1) 40 imshow(im) 41 plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*') 42 axis('off') 43 title(u'Harris角點',fontproperties=font) 44 45 show()
結果截圖:
3、兩張圖片,計算sift特征匹配結果
代碼:
1 # -*- coding: utf-8 -*- 2 from PIL import Image 3 from pylab import * 4 from numpy import * 5 import os 6 7 def process_image(imagename, resultname, params="--edge-thresh 10 --peak-thresh 5"): 8 """ 處理一幅圖像,然后將結果保存在文件中""" 9 if imagename[-3:] != 'pgm': 10 #創建一個pgm文件 11 im = Image.open(imagename).convert('L') 12 im.save('tmp.pgm') 13 imagename ='tmp.pgm' 14 cmmd = str("sift "+imagename+" --output="+resultname+" "+params) 15 os.system(cmmd) 16 print 'processed', imagename, 'to', resultname 17 18 def read_features_from_file(filename): 19 """讀取特征屬性值,然后將其以矩陣的形式返回""" 20 f = loadtxt(filename) 21 return f[:,:4], f[:,4:] #特征位置,描述子 22 23 def write_featrues_to_file(filename, locs, desc): 24 """將特征位置和描述子保存到文件中""" 25 savetxt(filename, hstack((locs,desc))) 26 27 def plot_features(im, locs, circle=False): 28 """顯示帶有特征的圖像 29 輸入:im(數組圖像),locs(每個特征的行、列、尺度和朝向)""" 30 31 def draw_circle(c,r): 32 t = arange(0,1.01,.01)*2*pi 33 x = r*cos(t) + c[0] 34 y = r*sin(t) + c[1] 35 plot(x, y, 'b', linewidth=2) 36 37 imshow(im) 38 if circle: 39 for p in locs: 40 draw_circle(p[:2], p[2]) 41 else: 42 plot(locs[:,0], locs[:,1], 'ob') 43 axis('off') 44 45 def match(desc1, desc2): 46 """對於第一幅圖像中的每個描述子,選取其在第二幅圖像中的匹配 47 輸入:desc1(第一幅圖像中的描述子),desc2(第二幅圖像中的描述子)""" 48 desc1 = array([d/linalg.norm(d) for d in desc1]) 49 desc2 = array([d/linalg.norm(d) for d in desc2]) 50 dist_ratio = 0.6 51 desc1_size = desc1.shape 52 matchscores = zeros((desc1_size[0],1),'int') 53 desc2t = desc2.T #預先計算矩陣轉置 54 for i in range(desc1_size[0]): 55 dotprods = dot(desc1[i,:],desc2t) #向量點乘 56 dotprods = 0.9999*dotprods 57 # 反余弦和反排序,返回第二幅圖像中特征的索引 58 indx = argsort(arccos(dotprods)) 59 #檢查最近鄰的角度是否小於dist_ratio乘以第二近鄰的角度 60 if arccos(dotprods)[indx[0]] < dist_ratio * arccos(dotprods)[indx[1]]: 61 matchscores[i] = int(indx[0]) 62 return matchscores 63 64 def match_twosided(desc1, desc2): 65 """雙向對稱版本的match()""" 66 matches_12 = match(desc1, desc2) 67 matches_21 = match(desc2, desc1) 68 ndx_12 = matches_12.nonzero()[0] 69 # 去除不對稱的匹配 70 for n in ndx_12: 71 if matches_21[int(matches_12[n])] != n: 72 matches_12[n] = 0 73 return matches_12 74 75 def appendimages(im1, im2): 76 """返回將兩幅圖像並排拼接成的一幅新圖像""" 77 #選取具有最少行數的圖像,然后填充足夠的空行 78 rows1 = im1.shape[0] 79 rows2 = im2.shape[0] 80 if rows1 < rows2: 81 im1 = concatenate((im1, zeros((rows2-rows1,im1.shape[1]))),axis=0) 82 elif rows1 >rows2: 83 im2 = concatenate((im2, zeros((rows1-rows2,im2.shape[1]))),axis=0) 84 return concatenate((im1,im2), axis=1) 85 86 def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True): 87 """ 顯示一幅帶有連接匹配之間連線的圖片 88 輸入:im1, im2(數組圖像), locs1,locs2(特征位置),matchscores(match()的輸出), 89 show_below(如果圖像應該顯示在匹配的下方) 90 """ 91 im3=appendimages(im1, im2) 92 if show_below: 93 im3=vstack((im3, im3)) 94 imshow(im3) 95 cols1 = im1.shape[1] 96 for i in range(len(matchscores)): 97 if matchscores[i]>0: 98 plot([locs1[i,0],locs2[matchscores[i,0],0]+cols1], [locs1[i,1],locs2[matchscores[i,0],1]],'c') 99 axis('off') 100 101 im1f = 'siftt/25.jpg' 102 im2f = 'siftt/26.jpg' 103 104 im1 = array(Image.open(im1f)) 105 im2 = array(Image.open(im2f)) 106 107 process_image(im1f, 'out_sift_1.txt') 108 l1,d1 = read_features_from_file('out_sift_1.txt') 109 figure() 110 gray() 111 subplot(121) 112 plot_features(im1, l1, circle=False) 113 114 process_image(im2f, 'out_sift_2.txt') 115 l2,d2 = read_features_from_file('out_sift_2.txt') 116 subplot(122) 117 plot_features(im2, l2, circle=False) 118 119 matches = match_twosided(d1, d2) 120 print '{} matches'.format(len(matches.nonzero()[0])) 121 122 figure() 123 gray() 124 plot_matches(im1, im2, l1, l2, matches, show_below=True) 125 show()
結果截圖:
小結:用siftt算法提取兩張圖的特征點,然后雙向匹配兩張圖片的描述子,用線將兩幅圖相匹配的描述子相連,連的線越多,說明這兩幅圖的匹配度越高,兩幅圖越相似。
4、給定一張圖片,輸出匹配度最高的三張圖片
代碼:
1 # -*- coding: utf-8 -*- 2 from PIL import Image 3 from pylab import * 4 from numpy import * 5 import os 6 from PCV.tools.imtools import get_imlist # 導入原書的PCV模塊 7 import matplotlib.pyplot as plt # plt 用於顯示圖片 8 import matplotlib.image as mpimg # mpimg 用於讀取圖片 9 10 def process_image(imagename, resultname, params="--edge-thresh 10 --peak-thresh 5"): 11 """ 處理一幅圖像,然后將結果保存在文件中""" 12 if imagename[-3:] != 'pgm': 13 #創建一個pgm文件 14 im = Image.open(imagename).convert('L') 15 im.save('tmp.pgm') 16 imagename ='tmp.pgm' 17 cmmd = str("sift "+imagename+" --output="+resultname+" "+params) 18 os.system(cmmd) 19 print 'processed', imagename, 'to', resultname 20 21 def read_features_from_file(filename): 22 """讀取特征屬性值,然后將其以矩陣的形式返回""" 23 f = loadtxt(filename) 24 return f[:,:4], f[:,4:] #特征位置,描述子 25 26 def write_featrues_to_file(filename, locs, desc): 27 """將特征位置和描述子保存到文件中""" 28 savetxt(filename, hstack((locs,desc))) 29 30 def plot_features(im, locs, circle=False): 31 """顯示帶有特征的圖像 32 輸入:im(數組圖像),locs(每個特征的行、列、尺度和朝向)""" 33 34 def draw_circle(c,r): 35 t = arange(0,1.01,.01)*2*pi 36 x = r*cos(t) + c[0] 37 y = r*sin(t) + c[1] 38 plot(x, y, 'b', linewidth=2) 39 40 imshow(im) 41 if circle: 42 for p in locs: 43 draw_circle(p[:2], p[2]) 44 else: 45 plot(locs[:,0], locs[:,1], 'ob') 46 axis('off') 47 48 def match(desc1, desc2): 49 """對於第一幅圖像中的每個描述子,選取其在第二幅圖像中的匹配 50 輸入:desc1(第一幅圖像中的描述子),desc2(第二幅圖像中的描述子)""" 51 desc1 = array([d/linalg.norm(d) for d in desc1]) 52 desc2 = array([d/linalg.norm(d) for d in desc2]) 53 dist_ratio = 0.6 54 desc1_size = desc1.shape 55 matchscores = zeros((desc1_size[0],1),'int') 56 desc2t = desc2.T #預先計算矩陣轉置 57 for i in range(desc1_size[0]): 58 dotprods = dot(desc1[i,:],desc2t) #向量點乘 59 dotprods = 0.9999*dotprods 60 # 反余弦和反排序,返回第二幅圖像中特征的索引 61 indx = argsort(arccos(dotprods)) 62 #檢查最近鄰的角度是否小於dist_ratio乘以第二近鄰的角度 63 if arccos(dotprods)[indx[0]] < dist_ratio * arccos(dotprods)[indx[1]]: 64 matchscores[i] = int(indx[0]) 65 return matchscores 66 67 def match_twosided(desc1, desc2): 68 """雙向對稱版本的match()""" 69 matches_12 = match(desc1, desc2) 70 matches_21 = match(desc2, desc1) 71 ndx_12 = matches_12.nonzero()[0] 72 # 去除不對稱的匹配 73 for n in ndx_12: 74 if matches_21[int(matches_12[n])] != n: 75 matches_12[n] = 0 76 return matches_12 77 78 def appendimages(im1, im2): 79 """返回將兩幅圖像並排拼接成的一幅新圖像""" 80 #選取具有最少行數的圖像,然后填充足夠的空行 81 rows1 = im1.shape[0] 82 rows2 = im2.shape[0] 83 if rows1 < rows2: 84 im1 = concatenate((im1, zeros((rows2-rows1,im1.shape[1]))),axis=0) 85 elif rows1 >rows2: 86 im2 = concatenate((im2, zeros((rows1-rows2,im2.shape[1]))),axis=0) 87 return concatenate((im1,im2), axis=1) 88 89 def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True): 90 """ 顯示一幅帶有連接匹配之間連線的圖片 91 輸入:im1, im2(數組圖像), locs1,locs2(特征位置),matchscores(match()的輸出), 92 show_below(如果圖像應該顯示在匹配的下方) 93 """ 94 im3=appendimages(im1, im2) 95 if show_below: 96 im3=vstack((im3, im3)) 97 imshow(im3) 98 cols1 = im1.shape[1] 99 for i in range(len(matchscores)): 100 if matchscores[i]>0: 101 plot([locs1[i,0],locs2[matchscores[i,0],0]+cols1], [locs1[i,1],locs2[matchscores[i,0],1]],'c') 102 axis('off') 103 104 # 獲取project2_data文件夾下的圖片文件名(包括后綴名) 105 filelist = get_imlist('project2_data/') 106 107 # 輸入的圖片 108 im1f = '23.jpg' 109 im1 = array(Image.open(im1f)) 110 process_image(im1f, 'out_sift_1.txt') 111 l1, d1 = read_features_from_file('out_sift_1.txt') 112 113 i=0 114 num = [0]*30 #存放匹配值 115 for infile in filelist: # 對文件夾下的每張圖片進行如下操作 116 im2 = array(Image.open(infile)) 117 process_image(infile, 'out_sift_2.txt') 118 l2, d2 = read_features_from_file('out_sift_2.txt') 119 matches = match_twosided(d1, d2) 120 num[i] = len(matches.nonzero()[0]) 121 i=i+1 122 print '{} matches'.format(num[i-1]) #輸出匹配值 123 124 i=1 125 figure() 126 while i<4: #循環三次,輸出匹配最多的三張圖片 127 index=num.index(max(num)) 128 print index, filelist[index] 129 lena = mpimg.imread(filelist[index]) # 讀取當前匹配最大值的圖片 130 # 此時 lena 就已經是一個 np.array 了,可以對它進行任意處理 131 # lena.shape # (512, 512, 3) 132 subplot(1,3,i) 133 plt.imshow(lena) # 顯示圖片 134 plt.axis('off') # 不顯示坐標軸 135 num[index] = 0 #將當前最大值清零 136 i=i+1 137 show()
結果截圖:
給定的圖片
輸出的圖片
小結:通過用給定的圖匹配圖像集中的每張圖片的描述子,然后用線與圖像集中的圖片的描述子相連,匹配度最高的圖片就會被輸出。
七、圖像全景拼接RANSAC
7.1 RANSAC算法原理
OpenCV中濾除誤匹配對采用RANSAC算法尋找一個最佳單應性矩陣H,矩陣大小為3×3。RANSAC目的是找到最優的參數矩陣使得滿足該矩陣的數據點個數最多,通常令h33=1來歸一化矩陣。由於單應性矩陣有8個未知參數,至少需要8個線性方程求解,對應到點位置信息上,一組點對可以列出兩個方程,則至少包含4組匹配點對。
RANSAC算法從匹配數據集中隨機抽出4個樣本並保證這4個樣本之間不共線,計算出單應性矩陣,然后利用這個模型測試
所有數據,並計算滿足這個模型數據點的個數與投影誤差(即代價函數),若此模型為最優模型,則對應的代價函數最小。
7.2 RANSAC算法步驟
1. 隨機從數據集中隨機抽出4個樣本數據 (此4個樣本之間不能共線),計算出變換矩陣H,記為模型M;
2. 計算數據集中所有數據與模型M的投影誤差,若誤差小於閾值,加入內點集 I ;
3. 如果當前內點集 I 元素個數大於最優內點集 I_best , 則更新 I_best = I,同時更新迭代次數k ;
4. 如果迭代次數大於k,則退出 ; 否則迭代次數加1,並重復上述步驟;
注:迭代次數k在不大於最大迭代次數的情況下,是在不斷更新而不是固定的;p為置信度,一般取0.995;w為"內點"的比例 ; m為計算模型所需要的最少樣本數=4;
7.3 RANSAC 基本假設
測試的數據都是由"局外點"組成的,建立模型,局外點是不能適應該模型的數據,也就是不合適該模型的局外點就是噪聲。
7.4 RANSAC 局外點產生的原因
A、噪聲的極值
B、錯誤的測量方法
C、對數據的錯誤假設
7.5實驗代碼
1 from pylab import * 2 from PIL import Image 3 import warp 4 import homography 5 import sift 6 7 # set paths to data folder 8 featname = ['D:/new/jia/' + str(i + 1) + '.sift' for i in range(3)] 9 imname = ['D:/new/jia/' + str(i + 1) + '.jpg' for i in range(3)] 10 11 # extract features and match 12 l = {} 13 d = {} 14 for i in range(3): 15 sift.process_image(imname[i], featname[i]) 16 l[i], d[i] = sift.read_features_from_file(featname[i]) 17 18 matches = {} 19 for i in range(2): 20 matches[i] = sift.match(d[i + 1], d[i]) 21 22 # visualize the matches (Figure 3-11 in the book) 23 for i in range(2): 24 im1 = array(Image.open(imname[i])) 25 im2 = array(Image.open(imname[i + 1])) 26 figure() 27 sift.plot_matches(im2, im1, l[i + 1], l[i], matches[i], show_below=True) 28 29 30 # function to convert the matches to hom. points 31 def convert_points(j): 32 ndx = matches[j].nonzero()[0] 33 fp = homography.make_homog(l[j + 1][ndx, :2].T) 34 ndx2 = [int(matches[j][i]) for i in ndx] 35 tp = homography.make_homog(l[j][ndx2, :2].T) 36 37 # switch x and y - TODO this should move elsewhere 38 fp = vstack([fp[1], fp[0], fp[2]]) 39 tp = vstack([tp[1], tp[0], tp[2]]) 40 return fp, tp 41 42 43 # estimate the homographies 44 model = homography.RansacModel() 45 46 fp,tp = convert_points(1) 47 H_12 = homography.H_from_ransac(fp,tp,model)[0] #im 1 to 2 48 49 fp,tp = convert_points(0) 50 H_01 = homography.H_from_ransac(fp,tp,model)[0] #im 0 to 1 51 52 53 # warp the images 54 delta = 1000 # for padding and translation 55 56 im1 = array(Image.open(imname[1]), "uint8") 57 im2 = array(Image.open(imname[2]), "uint8") 58 im_12 = warp.panorama(H_12,im1,im2,delta,delta) 59 60 im1 = array(Image.open(imname[0]), "f") 61 im_02 = warp.panorama(dot(H_12,H_01),im1,im_12,delta,delta) 62 63 figure() 64 imshow(array(im_02, "uint8")) 65 axis('off') 66 show()
7.6結果截圖
單一的環境圖片
分析:我拍攝的是四張圖片,環境很單一,同一個場景,不同的角度,由結果截圖看出前面一張圖片的拼接點較多,從第二張看出刪除點較為明顯,一看就可以看出來那些點被刪除了,刪除后覺得看到的連線比較清晰,連接的線條變少。
分析:這組圖片是同一個地點拍的,環境比較豐富,從不同的角度拍攝,第一張圖片跟第二張的不同點相當的明顯,第一張的連線很多,拼接的效果很成功,連線很多,看出有重復點,覆蓋匹配點,第二張的圖片相似點較少,連線也不多,說明了,相似度高的匹配程度就高,拼接效果也好,相似度低的就相反。
7.7遇到的問題
因為運行之前沒有導入包,就產生了錯誤,然后我就導入了warp包
報錯
1 Arrays cannot be empty
矩陣為空,我就重新改了圖像的像素,提取sift特征
然后由報錯
1 did not meet fit acceptance criteria
這是因為圖片的水平落差比較大,我們得再拍一組照片。改了圖片的下高速,圖片的像素都改成一樣,不能太大也不能太小,我改成的是600*600.
八、SIFT實驗總結
1、sift算法提取特征點穩定,不會因為光照、旋轉、尺度等因素而改變圖像的特征點。
2、圖像的尺度越大,圖像就會越模糊。
3、sift算法可以對多張圖像進行快速的、准確的關鍵點匹配,產生大量的特征點,可以適用於生活中的很多運用。
4、sift算法提取的特征點會有重疊。
5、在用sift算法提取特征時,應該降低圖片的像素,像素過高會導致運行時間過長或失敗。
九、實驗遇到的問題
出現的問題:1、運行代碼時出現這樣的錯誤:
在D:\Anaconda2\Lib\site-packages目錄中找到pydot.py ,用記事本打開,把self.prog = 'dot‘改成self.prog = r'C:\Program Files (x86)\Graphviz2.38\bin\dot.exe',保存,關掉運行軟件再打開就可以了。
2、運行代碼出現這樣的結果
我用的項目的路徑,出現以上報錯,把路徑改成了圖片的路徑,圖片的后綴改成.jpg就可以了。
3、因為圖片像素過高,運行時間會過長,結果一直出不來,還以為是代碼出來了錯誤,但是不報錯,想着可能是照片是自己拍的,像素過高了,就去降低了圖片的像素,運行速率變快,結果就出來了。