Python计算机视觉编程(二)---SIFT、Harris特征

小咪咪 2022-03-07 17:50 498阅读 0赞

图像局部描述符

本文工作

Harris

  1. 角点检测
  2. 在图像间寻找对应点

SIFT

  1. 检测关键点
  2. 描述子匹配
  3. 地理标记图像匹配

工具包的安装

  1. vlfeat
  2. Graphviz
  3. pydot
检测感兴趣点

对比Harris和SIFT,将Harris角点检测的显示在了图像的最后,这两种算法选择了不同的坐标。

  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. from matplotlib.font_manager import FontProperties
  8. font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
  9. imname = 'E:\\study_work\\python\\images\\school4.jpg'
  10. im = array(Image.open(imname).convert('L'))
  11. sift.process_image(imname, 'school.sift')
  12. l1, d1 = sift.read_features_from_file('school.sift')
  13. figure()
  14. gray()
  15. subplot(131)
  16. sift.plot_features(im, l1, circle=False)
  17. title(u'SIFT特征',fontproperties=font)
  18. subplot(132)
  19. sift.plot_features(im, l1, circle=True)
  20. title(u'用圆圈表示SIFT特征尺度',fontproperties=font)
  21. # 检测harris角点
  22. harrisim = harris.compute_harris_response(im)
  23. subplot(133)
  24. filtered_coords = harris.get_harris_points(harrisim, 6, 0.1)
  25. imshow(im)
  26. plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
  27. axis('off')
  28. title(u'Harris角点',fontproperties=font)
  29. show()

在这里插入图片描述

描述子匹配

Harris
Harris角点检测器可以给出图像中检测到兴趣点,但它并没有提供在图像间对兴趣点进行比较的方法,我们需要在每个角点添加描述子,以及对这些描述子进行比较。

  1. # -*- coding: utf-8 -*-
  2. from pylab import *
  3. from PIL import Image
  4. from PCV.localdescriptors import harris
  5. from PCV.tools.imtools import imresize
  6. """
  7. This is the Harris point matching example in Figure 2-2.
  8. """
  9. # Figure 2-2下面的图
  10. im1 = array(Image.open("E:\\study_work\\python\\images\\school11.jpg").convert("L"))
  11. im2 = array(Image.open("E:\\study_work\\python\\images\\school12.jpg").convert("L"))
  12. # resize加快匹配速度
  13. im1 = imresize(im1, (im1.shape[1]/2, im1.shape[0]/2))
  14. im2 = imresize(im2, (im2.shape[1]/2, im2.shape[0]/2))
  15. wid = 5
  16. harrisim = harris.compute_harris_response(im1, 5)
  17. filtered_coords1 = harris.get_harris_points(harrisim, wid+1)
  18. d1 = harris.get_descriptors(im1, filtered_coords1, wid)
  19. harrisim = harris.compute_harris_response(im2, 5)
  20. filtered_coords2 = harris.get_harris_points(harrisim, wid+1)
  21. d2 = harris.get_descriptors(im2, filtered_coords2, wid)
  22. print 'starting matching'
  23. matches = harris.match_twosided(d1, d2)
  24. figure()
  25. gray()
  26. harris.plot_matches(im1, im2, filtered_coords1, filtered_coords2, matches)
  27. show()

在这里插入图片描述
如图,可以看到结果中有许多错误的匹配,而SIFT能够较好地提高特征描述点检测与描述。

SIFT

  1. import cv2
  2. import numpy as np
  3. def drawMatchesKnn_cv2(img1_gray, kp1, img2_gray, kp2, goodMatch):
  4. h1, w1 = img1_gray.shape[:2]
  5. h2, w2 = img2_gray.shape[:2]
  6. vis = np.zeros((max(h1, h2), w1 + w2, 3), np.uint8)
  7. vis[:h1, :w1] = img1_gray
  8. vis[:h2, w1:w1 + w2] = img2_gray
  9. p1 = [kpp.queryIdx for kpp in goodMatch]
  10. p2 = [kpp.trainIdx for kpp in goodMatch]
  11. post1 = np.int32([kp1[pp].pt for pp in p1])
  12. post2 = np.int32([kp2[pp].pt for pp in p2]) + (w1, 0)
  13. for (x1, y1), (x2, y2) in zip(post1, post2):
  14. cv2.line(vis, (x1, y1), (x2, y2), (0, 0, 255))
  15. cv2.namedWindow("match", cv2.WINDOW_NORMAL)
  16. cv2.imshow("match", vis)
  17. img1_gray = cv2.imread("E:\\study_work\\python\\images\\school11.jpg")
  18. img2_gray = cv2.imread("E:\\study_work\\python\\images\\school12.jpg")
  19. sift = cv2.SIFT()
  20. # sift = cv2.SURF()
  21. kp1, des1 = sift.detectAndCompute(img1_gray, None)
  22. kp2, des2 = sift.detectAndCompute(img2_gray, None)
  23. # BFmatcher with default parms
  24. bf = cv2.BFMatcher(cv2.NORM_L2)
  25. matches = bf.knnMatch(des1, des2, k=2)
  26. goodMatch = []
  27. for m, n in matches:
  28. if m.distance < 0.50 * n.distance:
  29. goodMatch.append(m)
  30. drawMatchesKnn_cv2(img1_gray, kp1, img2_gray, kp2, goodMatch[:20])
  31. cv2.waitKey(0)
  32. cv2.destroyAllWindows()

在这里插入图片描述
SIFT是采用opencv-python进行实践的,由结果可以看出同前面的harris对比,SIFT检测出的匹配较为精准

地理标记图像匹配

自己准备一个图像集,博主的图像集存放在E:/study_work/python/images中
此算法是用于对图像的地理位置进行匹配并描绘出关系图(注:图像一定要resize以下,不然太大,对电脑性能有影响)

  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. """ This is the example graph illustration of matching images from Figure 2-10.
  8. To download the images, see ch2_download_panoramio.py."""
  9. #download_path = "panoimages" # set this to the path where you downloaded the panoramio images
  10. #path = "/FULLPATH/panoimages/" # path to save thumbnails (pydot needs the full system path)
  11. download_path = "E:/study_work/python/images" # set this to the path where you downloaded the panoramio images
  12. path = "E:/study_work/python/images/" # path to save thumbnails (pydot needs the full system path)
  13. # list of downloaded filenames
  14. imlist = imtools.get_imlist(download_path)
  15. nbr_images = len(imlist)
  16. # extract features
  17. featlist = [imname[:-3] + 'sift' for imname in imlist]
  18. for i, imname in enumerate(imlist):
  19. sift.process_image(imname, featlist[i])
  20. matchscores = zeros((nbr_images, nbr_images))
  21. for i in range(nbr_images):
  22. for j in range(i, nbr_images): # only compute upper triangle
  23. print 'comparing ', imlist[i], imlist[j]
  24. l1, d1 = sift.read_features_from_file(featlist[i])
  25. l2, d2 = sift.read_features_from_file(featlist[j])
  26. matches = sift.match_twosided(d1, d2)
  27. nbr_matches = sum(matches > 0)
  28. print 'number of matches = ', nbr_matches
  29. matchscores[i, j] = nbr_matches
  30. print "The match scores is: \n", matchscores
  31. # copy values
  32. for i in range(nbr_images):
  33. for j in range(i + 1, nbr_images): # no need to copy diagonal
  34. matchscores[j, i] = matchscores[i, j]
  35. #可视化
  36. threshold = 2 # min number of matches needed to create link
  37. g = pydot.Dot(graph_type='graph') # don't want the default directed graph
  38. for i in range(nbr_images):
  39. for j in range(i + 1, nbr_images):
  40. if matchscores[i, j] > threshold:
  41. # first image in pair
  42. im = Image.open(imlist[i])
  43. im.thumbnail((100, 100))
  44. filename = path + str(i) + '.png'
  45. im.save(filename) # need temporary files of the right size
  46. g.add_node(pydot.Node(str(i), fontcolor='transparent', shape='rectangle', image=filename))
  47. # second image in pair
  48. im = Image.open(imlist[j])
  49. im.thumbnail((100, 100))
  50. filename = path + str(j) + '.png'
  51. im.save(filename) # need temporary files of the right size
  52. g.add_node(pydot.Node(str(j), fontcolor='transparent', shape='rectangle', image=filename))
  53. g.add_edge(pydot.Edge(str(i), str(j)))
  54. g.write_png('jimei.png')

在这里插入图片描述
关键点匹配是采用Kd树的数据结构来完成搜索,具体原理见SIFT算法原理,如上图所示,此算法得到两组图像,由图像内容可看出匹配地理位置得出的结果还是较为准确的。

安装工具包
1、安装VLFeat
进行上述事项前,需要先安装开源工具包VLFeat,可以在www.vlfeat.org上下载,如下图所示(ps:要下载0.9.20版本,不能下载0.9.21版本的,0.9.21版本不稳定,博主已经掉过坑)
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
下载完之后解压(博主电脑是windows64位的,所以选择win64),复制此文件夹并将win64放进PCV所在目录
在这里插入图片描述
放到此目录下(这是博主的PCV所在地,你们根据自己的做相应的改变)在这里插入图片描述
打开PCV中的localdescriptors文件夹,找到sift.py并打开
在这里插入图片描述
在sift.py中找到如下代码,并将cmmd中的路径改为sift.exe的所在路径(就是刚刚存放在同PCV目录的win64文件夹的里头),这里要特别注意以下,sift.exe路径后一定要加个空格!这可是个大坑

  1. def process_image(imagename,resultname,params="--edge-thresh 10 --peak-thresh 5"):
  2. """ process an image and save the results in a file"""
  3. # path = os.path.abspath(os.path.join(os.path.dirname("__file__"),os.path.pardir))
  4. # path = path+"\\utils\\win32vlfeat\\sift.exe "
  5. if imagename[-3:] != 'pgm':
  6. #create a pgm file
  7. im = Image.open(imagename).convert('L')
  8. im.save('tmp.pgm')
  9. imagename = 'tmp.pgm'
  10. cmmd = str("D:\\Pycharm\\test\\win64_vlfeat\\sift.exe "+imagename+" --output="+resultname+
  11. " "+params)
  12. os.system(cmmd)
  13. print 'processed', imagename, 'to', resultname

好了,现在vlfeat工具包安装完成
2、安装Graphviz和pydot
注意:一定要先安装Graphviz!注意顺序
安装Graphviz
在官网上下载graphviz-2.38.msi
在这里插入图片描述
下载好之后双击graphviz-2.38.msi,选择安装路径(这个路径要记住,后面要配置环境变量)
安装完成之后配置环境变量
右键我的电脑->属性->高级系统设置->环境变量->系统变量->Path,在Path里添加Graphviz-2.38文件夹下的bin
在这里插入图片描述
在命令行界面中输入dot -version检测是否安装成功,出现如下界面则说明安装成功
在这里插入图片描述
安装pydot
在命令行界面中输入pip install pydot==1.1.0
在python工具下运行

  1. import pydot
  2. g = pydot.Dot(graph_type='graph')
  3. g.add_node(pydot.Node(str(0), fontcolor='transparent'))
  4. for i in range(5):
  5. g.add_node(pydot.Node(str(i + 1)))
  6. g.add_edge(pydot.Edge(str(0), str(i + 1)))
  7. for j in range(5):
  8. g.add_node(pydot.Node(str(j + 1) + '0' + str(i + 1)))
  9. g.add_edge(pydot.Edge(str(j + 1) + '0' + str(i + 1), str(j + 1)))
  10. g.write_png(E:/study_work/python/images/test.png', prog='neato')

出现下图则说明安装成功
在这里插入图片描述

参考
Pytthon计算机视觉编程第二章

发表评论

表情:
评论列表 (有 0 条评论,498人围观)

还没有评论,来说两句吧...

相关阅读

    相关 机器视觉-点特征检测

    特征检测和匹配是计算机视觉的一个基本问题,点特征检测和匹配在图像拼接和自动三维重建方面更是有着广泛的用途。 点特征的检测和匹配一般有两种方法: 1) 在图像中寻找那些使用局

    相关 计算机视觉

    1、捕获摄像头的帧   VideoCapture类可以获得摄像头的帧流。但对摄像头而言,通常不是用视频的文件名来构造VideoCapture类,而是需要传递摄像头的设备索引(

    相关 OpenCV-Python计算机视觉开发利器

    人工智能,一个已经被谈论了几十年的概念(最早是图灵在1950年提出)。如今这几年,相关技术的发展速度是越来越快。高大上如无人驾驶、智能安防、AI辅助诊断,接地气如刷脸支付、内容