ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-03-28

2021-03-28 23:30:30  阅读:240  来源: 互联网

标签:03 matches 28 im1 sift im2 2021 图像 关键点


[计算机视觉]匹配地理标记图像

一、sift原理

SIFT算法概述

尺度不变特征转换即SIFT (Scale-invariant feature transform)是一种计算机视觉的算法。它用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量,此算法由 David Lowe在1999年所发表,2004年完善总结。 其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。SIFT算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。

在这里插入图片描述

Sfit特征提取和匹配具体步骤

  1. 生成高斯差分金字塔(DOG金字塔),尺度空间构建

  2. 空间极值点检测(关键点的初步查探)

  3. 稳定关键点的精确定位

  4. 关键点描述

  5. 特征点匹配
    示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

**

生成高斯差分金字塔(DOG金字塔),尺度空间构建

**

主要思想是通过对原始图像进行尺度变换,获得图像多尺度下的尺度空间表示序列,对这些序列进行尺度空间主轮廓的提取,并以该主轮廓作为一种特征向量,实现边缘、角点检测不同分辨率上的关键点提取等。

各尺度下图像的模糊度逐渐变大,能够模拟人在距离目标由近到远时目标物体在视网膜上的形成过程。

为了在尺度空间中找到稳定不变的极值点,在SIFT算法中使用了高斯差分(DOG)函数D(x,y,σ)D(x,y,σ),定义为
D(x,y,σ)=[G(x,y,kσ)−G(x,y,σ)]∗I(x,y)
=L(x,y,kσ)−L(x,y,σ)
其中 kσkσ和 σσ是连续的两个图像的平滑尺度,所得到的差分图像再高斯差分金字塔中

高斯模糊——降低图像中的噪点,强调了图像的重要特征。进行高斯模糊之和,纹理和次要细节将从图像中删除,并且保留形状和边缘之类的相关信息。
在这里插入图片描述
实现DOG——初始图像与不同σ值的高斯函数卷积,得到一垛模糊后图像,然后将这一垛图像临近两两相减得到对应的DOG。一副图像可以产生几组图像,一组图像包括几层图像。s为每组层数一般为3~5层,最后可以将s和k的关系确立为k=2^(1/s)
在这里插入图片描述

**尺度空间检测极值点

**——DOG上某个像素要和本尺度的8个像素以及上下相邻尺度各9个相邻像素共26个像素值进行比较,以确定是否为局部最大或最小值。如果它是相邻像素中最高或者最低的像素,则确定该像素点是尺度空间的极值点之一。
在这里插入图片描述

*稳定关键点的精确定位

DOG值对噪声和边缘比较敏感,所以在第2步的尺度空间中检测到的局部极值点还要经过进一步的筛选,去除不稳定和错误检测出的极值点,另一点就是在构建高斯金字塔过程中采用了下采样的图像,在下采样图像中提取的极值点对应在原始图像中的确切位置,也是要在本步骤中解决的问题。

关键点描述*

兴趣点(关键点)位置描述子给出兴趣点的位置 和尺度信息,为了实现旋转不变性,基于每个点周围图像梯度的方向和大小,sift描述算子使用主方向描述参考方向,主方向使用直方图来衡量。sift描述算子在每个像素点附近选取子区域网格,在每个子区域计算图像梯度方向直方图,拼接起来组成描述算子向量。sift描述算子是由44个子区域,每个子区域有8个方向,会产生128个小区间直方图(448=128)也就是一张图像的每一个像素点都有128维的特征向量来唯一标识,即使方向有变换,也可以通过主方向来同步变换达到旋转不变性。
在这里插入图片描述
David G.Lowed的实验结果表明:对每个关键点,采用4
4*8共128维向量的描述子进项关键点表征,综合效果最佳:
在这里插入图片描述

特征点匹配

分别对模板图(参考图)和实时图(观测图)建立关键点描述子集合。目标的识别是通过两点集内关键点描述子的比对来完成具有128维的关键点描述子的相似性度量采用欧式距离。

sift特征点提取和匹配


```python
from pylab import *
from PIL import Image
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 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')
    return

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
        # 反余弦和反排序,返回第二幅图像中特征的索引
        index = argsort(arccos(dotprods))

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

    return matchscores

def match_twosided(desc1,decs2):
    """双向对称版本的match"""

    matches_12 = match(desc1, decs2)
    matches_21 = match(decs2, decs2)

    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):
    """返回将两幅图像并排拼接成的一幅新图像"""

    # 选取具有最少行数的图像,然后填充足够的空行
    row1 = im1.shape[0]
    row2 = im2.shape[0]

    if row1 < row2:
        im1 = concatenate((im1,zeros((row2-row1,im1.shape[1]))), axis=0)
    elif row1 > row2:
        im2 = concatenate((im2,zeros((row1-row2,im2.shape[1]))), axis=0)

    # 如果这些情况都没有,那么他们的行数相同,不需要进行填充

    return concatenate((im1,im2), axis=1)

def plot_matches(im1, im2, locs1, locs2, matchscores, show_below=True):
    """显示一幅带有连接匹配之间连线的图片
        输入:im1,im2(数组图像),locs1,locs2(特征位置),matchscores(match的输出),
        show_below(如果图像应该显示再匹配下方)"""

    im3 = appendimages(im1,im2)
    if show_below:
        im3 = vstack((im3,im3))

    imshow(im3)

    cols1 = im1.shape[1]
    for i in range(len(matchscores)):
        if matchscores[i] > 0:
            plot([locs1[i, 0], locs2[matchscores[i, 0], 0] + cols1], [locs1[i, 1], locs2[matchscores[i, 0], 1]], 'c')
    axis('off')

if __name__ == '__main__':
    # imname = 'xqimage08.jpg'
    # im1 = array(Image.open(imname).convert('L'))
    # process_image(imname, 'xqimage08.sift')
    # l1, d1 = read_features_from_file('xqimage08.sift')
    #
    # figure()
    # gray()
    # plot_features(im1, l1, circle=True)
    # show()

    im1f = r'p1.jpg'
    im2f = r'p6.jpg'
    im1 = array(Image.open(im1f))
    im2 = array(Image.open(im2f))

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

    process_image(im2f, 'jimei-sift2.sift')
    l2, d2 = read_features_from_file('jimei-sift2.sift')
    subplot(122)
    plot_features(im2, l2, circle=False)

    matches = match_twosided(d1, d2)
    print('{} matches'.format(len(matches.nonzero()[0])))
    figure()
    gray()
    plot_matches(im1, im2, l1, l2, matches, show_below=True)
    show()

原图:
p1:在这里插入图片描述
p2:在这里插入图片描述

结果截图:
在这里插入图片描述
在这里插入图片描述

得到的结论;
发现sift更适用于图像特征检测,旋转不变性较强、可以解决一些光线和亮度问题,且比harris灵活、匹配准确些。虽然sift算法能够解决旋转角度、光线亮度问题,但是也不是十分准确,对于旋转角度过大和光线亮度反差很大时,也会出现错误点匹配(甚至会出现找不到特征点),从图中匹配的结果看出来sift算法对旋转角度匹配点也不是很多。

标签:03,matches,28,im1,sift,im2,2021,图像,关键点
来源: https://blog.csdn.net/weixin_43423030/article/details/115284136

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有