Harris角点检测、SIFT特征匹配、地理特征匹配

目录

1、Harris角点检测

1.1 角点  

1.2 Harris角点检测的基本思想

1.3 Harris角点检测算法的数学表达

1.4 Harris角点计算流程 

 1.5代码

2、SIFT(尺度不变特征变换)

2.1 SIFT算法实现步骤

 2.2 代码实现

 3、地理特征匹配


1、Harris角点检测

1.1 角点  

     局部窗口向任意方向的移动都导致图像灰度的明显变化。
     图像局部曲率突变的点。

1.2 Harris角点检测的基本思想

1.3 Harris角点检测算法的数学表达

   将图像窗口平移 [ u,v ] 产生灰度变化 E ( u,v ):
E(u,v)=\sum_{x{,y}}w(x,y)[I(x+u,y+v)-I(x,y)]^{2}

  w(x,y)是窗口函数,I(x,y)是图像灰度,I(x+u,y+u)是平移后的图像灰度。

  将 I ( x + u , y + v ) 函数在( x , y )处泰勒展开,得:
I(x+u,y+v)=I(x,y)+I_x{u}+I_y{v}+O(u^{2},v^{2})

于是对于局部微小的移动量 [ u,v ] ,可以近似得到下面的表达

 E(u,v)\cong \begin{bmatrix} u\\ v\end{bmatrix}M\begin{bmatrix} u & v\end{bmatrix}

其中 M 2\times 2 矩阵,可由图像的导数求得:

特征都比较小,窗口处于平坦区域

特征值都比较大,窗口中含有角点

特征值一个大,一个小,窗口中含有边缘

 角点响应函数R:

1.4 Harris角点计算流程 

    对角点响应函数 R 进行阈值处理: R > threshold
     提取 R 的局部极大值

 1.5代码

(1)Harris角点检测代码:

from pylab import *
from PIL import Image
from PCV.localdescriptors import harris

# 读入图像
im = array(Image.open(r'E:\Python Project\JSJSJ\photo\2.jpg').convert('L'))

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

# Harris响应函数
harrisim1 = 255 - harrisim
figure()
gray()
# 画出Harris响应图
subplot(141)
imshow(harrisim1)
axis('off')
axis('equal')
# 阈值
threshold = [0.01, 0.05, 0.1]
for i, thres in enumerate(threshold):
    filtered_coords = harris.get_harris_points(harrisim, 6, thres)
    subplot(1, 4, i + 2)
    imshow(im)
    print(im.shape)
    plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
    axis('off')
show()

 原图:

 Harris角点检测图:

 选择像素值高于阈值的所有图像点,会产生很好的角点检测结果。

(2)Harris匹配


from pylab import *
from PIL import Image

from PCV.localdescriptors import harris
from PCV.tools.imtools import imresize


im1 = array(Image.open( r'E:\Python Project\JSJSJ\photo\3.jpg').convert("L"))
im2 = array(Image.open( r'E:\Python Project\JSJSJ\photo\4.jpg').convert("L"))

im1 = imresize(im1, (int(im1.shape[1]/2), int(im1.shape[0]/2)))
im2 = imresize(im2, (int(im2.shape[1]/2), int(im2.shape[0]/2)))

wid = 5
harrisim = harris.compute_harris_response(im1, 5)
filtered_coords1 = harris.get_harris_points(harrisim, wid+1)
d1 = harris.get_descriptors(im1, filtered_coords1, wid)

harrisim = harris.compute_harris_response(im2, 5)
filtered_coords2 = harris.get_harris_points(harrisim, wid+1)
d2 = harris.get_descriptors(im2, filtered_coords2, wid)

print ('starting matching')
matches = harris.match_twosided(d1, d2)

figure()
gray()
harris.plot_matches(im1, im2, filtered_coords1, filtered_coords2, matches)
show()

     Harris匹配存在不正确的匹配,是因为图像像素块的互相关矩阵具有较弱的描述性。这些描述符还有一个问题,它们不具有尺度不变和旋转不变性,算法中像素块的大小也会影响对应匹配的结果。

2、SIFT(尺度不变特征变换)

2.1 SIFT算法实现步骤

     实质可以归为在不同尺度空间上查找特征点(关键点)的问题。

      SIFT算法实现特征匹配主要有三个流程, 1、提取关键点;2、对关键点附加详细的信息(局部特征),即描述符;3、通过特征点(附带上特征向量的关键点)的两两比较找出相互匹配的若干对特征点,建立景物间的对应关系。
       SIFT要查找的特征点:是一些十分突出的点,不会因光照、尺度、旋转等因素的改变而消
失,比如 角点 边缘点 暗区域的亮点 以及 亮区域的暗点。 假定两幅图像中有相同的景物,那么使用某种算法分别提取各自的特征点,这些点之间会有相互对应的匹配关系。 
     尺度空间主要思想 是通过对原始 图像进行尺度变换 ,获得图像多尺度下的空间表示。从而实现边缘、角点检测和不同分辨率上的特征提取,以满足 特征点的尺度不变性。

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

 2.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 = r'E:\Python Project\JSJSJ\photo\3.jpg'
    im2f = r'E:\Python Project\JSJSJ\photo\4.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_twosided(d1, d2)
print('{} matches'.format(len(matches.nonzero()[0])))

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

 两幅不同角度图像的角点检测: SIFT匹配结果:

 3、地理特征匹配

      • 输入同一场景的序列图像
      • 通过SIFT算法对地理标记图像进行两两匹配,构造连接矩阵
      • 可视化图像连接关系
from numpy import zeros
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 + r'D:\software\Anaconda3\Graphviz\bin'

download_path = r"E:\lab\photo" 
path = r"E:\lab\photo" 

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


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)


for i in range(nbr_images):
    for j in range(i + 1, nbr_images): 
        matchscores[j, i] = matchscores[i, j]

# 可视化
threshold = 2  

g = pydot.Dot(graph_type='graph')  

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

           
            im = Image.open(imlist[j])
            im.thumbnail((100, 100))
            filename = path + str(j) + '.png'
            im.save(filename)  
            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('1.png')

测试图:

结果:

猜你喜欢

转载自blog.csdn.net/qq_41275123/article/details/123715823