• python—sift特征提取


    一、SIFT提出的目的和意义

    二、SIFT的特征简介

    三、SIFT算法实现步骤简述

    四、图像集

    五、匹配地理标记图像

    • 代码
    • 结果截图
    • 小结 

    六、SIFT算法代码实现

    • 代码
    • 结果截图
    • 小结 

    七、图像全景拼接RANSAC

    八、SIFT实验总结

    九、实验遇到的问题

    一、SIFT提出的目的和意义

    1999年David G.Lowe教授总结了基于特征不变技术的检测方法,在图像尺度空间基础上,提出了对图像缩放、旋转保持不变性的图像局部特征描述算子-SIFT(尺度不变特征变换),该算法在2004年被加以完善。

     
    二、SIFT的特征简介
    SIFT算法可以解决的问题
    1.  目标的旋转、缩放、平移(RST)
    2. 图像仿射/投影变换(视点viewpoint)
    3. 弱光照影响(illumination)
    4. 部分目标遮挡(occlusion)
    5. 杂物场景(clutter)
    6. 噪声
     
     三、SIFT算法实现步骤简述
    SIFT算法的实质可以归为在不同尺度空间上查找特征点(关键点)的问题。SIFT算法实现特征匹配主要有三个流程,1、提取关键点;2、对关键点附加详细的信息(局部特征),即描述符;3、通过特征点(附带上特征向量的关键点)的两两比较找出相互匹配的若干对特征点,建立景物间的对应关系。
     

                                                                             图1
    需要配置vfleat安装包
    使用开源工具包 VLFeat 提供的二进制文件来计算图像的 SIFT特征 。这里附上VLFeat 工具包链接http://www.vlfeat.org/ 
    操作步骤:
    1.把vlfeat文件夹下win64中的sift.exe和vl.dll这两个文件复制到项目的文件夹中

    2.修改PCV文件夹内的(我的PCV位置为D:Anaconda2Libsite-packagesPCV))文件夹里面的localdescriptors文件夹中的sift.py文件,用记事本打开,修改其中的cmmd内的路径cmmd=str(r"D: ewsift.exe“+imagename+” --output="+resultname+" "+params) (路径是你项目文件夹中的sift.exe的路径)一定要在括号里加上r。
     
     
     
    四、图像集
    一共19 张图像

                                                                                                                         图2

    五、匹配地理标记图像        

     1、做此实验我们需用pydot工具包中的GraphViz,可以点击https://graphviz.gitlab.io/_pages/Download/Download_windows.html下载安装包,安装步骤如下:

          配置环境: 保存graphviz安装时,一定要记住保存路径,方便找到你的安装包安装中的gvedit.exe的位置,我的是C:Program Files (x86)Graphviz2.38in

    把gvedit.exe发送到桌面快捷方式,然后去系统里点击高级系统设置->点击环境变量->点击系统变量的path选择编辑->输入C:Program Files (x86)Graphviz2.38in,之后就确定保存。

     接下来是验证环境配置是否成功,输入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算法角度不变性,还有色彩影响不是很大,并且只要有一点特征点匹配度的图片就会相连起来,第二部分和第三部分依然如此。

                                                                        

    六、SIFT算法代码实现
    1、单张图片的sift特征提取Harris角点提取、用圆圈表示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:windowsfontsSimSun.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:windowsfontsSimSun.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:Anaconda2Libsite-packages目录中找到pydot.py ,用记事本打开,把self.prog = 'dot‘改成self.prog = r'C:Program Files (x86)Graphviz2.38indot.exe',保存,关掉运行软件再打开就可以了。

     2、运行代码出现这样的结果

     我用的项目的路径,出现以上报错,把路径改成了图片的路径,图片的后缀改成.jpg就可以了。

     3、因为图片像素过高,运行时间会过长,结果一直出不来,还以为是代码出来了错误,但是不报错,想着可能是照片是自己拍的,像素过高了,就去降低了图片的像素,运行速率变快,结果就出来了。

  • 相关阅读:
    Java并发初识
    go交叉编译
    MRC与ARC混合开发配置
    Hibernate配置文件
    LEFT JOIN重复数据
    Ext.ViewPort布局
    Hibernate学习映射文件
    AjaxMethod方法
    DataBinder
    subsonic 获取记录数量
  • 原文地址:https://www.cnblogs.com/wyf-1999-1--6/p/12455251.html
Copyright © 2020-2023  润新知