计算机视觉-图像局部描述符

一、Harris角点检测算法 1.什么是角点 局部窗口沿各方向移动,均产生明显变化的点;图像局部曲率突变的点;轮廓之间的交点;
对于同一场景,即使视角发生变化,通常具备稳定性质的特征;
该点附近区域的像素点无论在梯度方向上还是其梯度幅值上有着较大变化;
2.基本思想 使用一个固定小窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。
3.角点检测算法实例 代码

# -*- codeing =utf-8 -*- # @Time : 2021/3/22 19:03 # @Author : ArLin # @File : demo1.py # @Software: PyCharm # -*- coding: utf-8 -*- from pylab import * from PIL import Image from PCV.localdescriptors import harris# 读入图像 im = array(Image.open('../JMU/14.jpg').convert('L'))# 检测harris角点 harrisim = harris.compute_harris_response(im)# Harris响应函数 harrisim1 = 255 - harrisimfigure() gray()#画出Harris响应图 subplot(141) imshow(harrisim1) print (harrisim1.shape) 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()

运行结果
计算机视觉-图像局部描述符
文章图片

4.图像中寻找对应点 代码
# -*- codeing =utf-8 -*- # @Time : 2021/3/22 19:23 # @Author : ArLin # @File : demo2.py # @Software: PyCharm # -*- coding: utf-8 -*- from pylab import * from PIL import Image from PCV.localdescriptors import harris from PCV.tools.imtools import imresizeim1 = array(Image.open("C:/Users/cool/Desktop/hhc.jpg").convert("L")) im2 = array(Image.open("C:/Users/cool/Desktop/hhc2.jpg").convert("L"))# resize加快匹配速度 im1 = imresize(im1, (im1.shape[1]//2, im1.shape[0]//2)) im2 = imresize(im2, (im2.shape[1]//2, 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()

运行结果
计算机视觉-图像局部描述符
文章图片

5.小结 Harris角点检测算法优点:
旋转不变性,椭圆转过一定角度但是其形状保持不变(特征值保持不变)。
对于图像灰度的仿射变化具有部分的不变性,由于仅仅使用了图像的一介导数,对于图像灰度平移变化不变;
对于图像灰度尺度变化不变。
Harris角点检测算法缺点:
它对尺度很敏感,不具备几何尺度不变性。
提取的角点是像素级的
二、SIFT(尺度不变特征变换) 1.什么是特征点 十分突出的点,不会因光照、尺度、旋转等因素的改变而消失,比如角点、边缘点、暗区域的亮点以及亮区域的暗点。
2.SIFT解决了什么问题 【计算机视觉-图像局部描述符】●目标的旋转、缩放、平移(RST)
●图像仿射/投影变换(视点viewpoint )
●弱光照影响( ilumination)
●部分目标遮挡(occlusion)
●杂物场景( clutter)
3.SIFT特征点生成 (1)构建尺度空间,检测极值点,获得尺度不变性;
(2)特征点过滤并进行精确定位;
(3)为特征点分配方向值;
(4)计算变换参数
当两幅图像的Sift特征向量生成以后,下一步就可以采用关键点特征向量的欧式距离来作为两幅图像中关键点的相似性判定度量。取图1的某个关键点,通过遍历找到图像2中的距离最近的两个关键点。在这两个关键点中,如果次近距离除以最近距离小于某个阙值,则判定为一对匹配点。
4.匹配特征点 代码实现
from PIL import Image from pylab import * import sys from PCV.localdescriptors import siftif 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:/Users/cool/Desktop/hhc.jpg' im2f = 'C:/Users/cool/Desktop/hhc1.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()

运行结果
计算机视觉-图像局部描述符
文章图片

5.小结 SIFT优点:
1.特性独特性,也就是特征点可分辨性高,类似指纹,适合在海量数据中匹配。
2.多量性,提供的特征多。
3.高速性,就是速度快。
4.可扩展,能与其他特征向量联合使用。
SIFT缺点:
SIFT采用henssian矩阵获取图像局部最值还是十分稳定的,
但是在求主方向阶段太过于依赖局部区域像素的梯度方向,
有可能使得找到的主方向不准确,后面的特征向量提取以及匹配都严重依赖于主方向,即使不大偏差角度也可以造成后面特征匹配的放大误差,从而匹配不成功;
另外图像金字塔的层取得不足够紧密也会使得尺度有误差,后面的特征向量提取同样依赖相应的度,发明者在这个问题上的折中解决方法是取适量的层然后进行插值。
SIFT是一种只利用到灰度性质的算法,忽略了色彩信息.
三、实战:匹配地理标记图像 代码实现
# -*- codeing =utf-8 -*- # @Time : 2021/3/23 10:45 # @Author : ArLin # @File : demo8.py # @Software: PyCharm # -*- coding: utf-8 -*- from pylab import * from PIL import Image from PCV.localdescriptors import sift from PCV.tools import imtools import pydot""" This is the example graph illustration of matching images from Figure 2-10. To download the images, see ch2_download_panoramio.py."""download_path = "D:\python\pytharm\demo\pythonProject\JsVision\jmujpg"# set this to the path where you downloaded the panoramio images path = "D:\python\pytharm\demo\pythonProject\JsVision\jmujpg"# 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 linkg = pydot.Dot(graph_type='graph')# don't want the default directed graphfor 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((200, 200)) 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('seeingJMU3.png')

    推荐阅读