当前位置:   article > 正文

SIFT算法用VL_feat库实现(matlab)_vl_sift

vl_sift

sift算法是非常经典的特征提取算法,之后可以用于 对应特征匹配,从而进行图像拼接,求图像之间的转换矩阵,三维重建等工作。最近上课学习了这个算法,本打算能手敲源码,后来还是选择了调包,真香~

毕竟前人种树,后人乘凉嘛!利用好下层建筑为上层来进行服务!

目录

(1)sift特征提取步骤

     1.   建立高斯差分金字塔

       2.关键点(keypoint)位置的确定

      3. 去除不好的特征点(非极大值抑制)

       4.给关键点赋予方向

        5.特征描述子 :128维向量 4*4*8=128

(2)VLfeat介绍

(3)利用matlab 结合VLfeat进行代码实现(+代码详细解读) 


(1)sift特征提取步骤

     1.   建立高斯差分金字塔

              O组(octave 默认大小为 \log 2\left ( min(M,N) \right ) -3)照片,每组L层(L=n+3,L一般为3~5) ;一共 O*L张照片。

             每一组中每层采用不同的高斯模糊核,下一组由 上一组进行下采样得到。

               

            图片说明了每一组每一层中的照片采用的模糊核是多少。

                   (第1组的第1层为\sigma,第2组第1层为2\sigma.... 数学技巧呀)

                 此例中s=3,也就是 每一组照片的层数=s+3 为6层。

 

       2.关键点(keypoint)位置的确定

              看高斯差分金字塔为了寻找尺度空间的极值点,每一个采样点要和它所有的相邻点比较,但现在由上面的图片可以看                    出,有三个方向(x,y,尺度空间(一组内不同的高斯核,)),所以一个点应该与26个点进行比较。

                

             

      3. 去除不好的特征点(非极大值抑制)

              在实际中这个点有可能只是真正极值点附近的点,即找到的点为“亚极值点”,要进行处理一波,实际用的泰勒展开,进                 行求导来做的,这里忽略了。

               

             还有就是去掉边缘效应:https://blog.csdn.net/abcjennifer/article/details/7639681

       4.给关键点赋予方向

               

                 关键点周围图像区域分块,计算块内方向梯度直方图,确定主方向。

        5.特征描述子 :128维向量 4*4*8=128

 

(2)VLfeat介绍

              VLFeat是一个跨平台的开源机器视觉库,它囊括了当前流行的机器视觉算法,如SIFT, MSER, HOG, 同时还包含了诸如K-MEANS, Hierarchical K-means的聚类算法。它由C语言编写,并提供了Matlab接口及详细的文档。当前最新的版本是VLFeat 0.9.21 。(2019.4.11)

有了它,不需要再闭门造轮子了,直接调包!

具体的安装步骤网上很多,下载后 matlab 命令行中run('D:\VLFeat\vlfeat-0.9.18\toolbox\vl_setup')  (这个是我的存放位置)

(3)利用matlab 结合VLfeat进行代码实现(+代码详细解读) 

  1. img1ori = imread('Snowball.jpg');
  2. img1 = single(rgb2gray(img1ori)); %single就是转换成单精度的,之前肯定对double更熟悉一点吧
  3. %因为后面的vl_sift的输入须要用到单精度灰度图像
  4. %图片2要识别对于的物体
  5. img2ori = imread('Snowball.jpg');
  6. img2 = single(rgb2gray(img2ori));
  7. %% 提取SIFT特征,匹配特征点
  8. [f1, d1] = vl_sift(img1,'Levels',5,'PeakThresh', 4);
  9. [f2, d2] = vl_sift(img2,'Levels',5,'PeakThresh', 5);
  10. %f1为生成的四元组[x,y,s,th],分别是特征点的x,y坐标,s为长度空间大小,th指的是主方向
  11. %d1是特征描述子,也就是那个128维的向量
  12. [matches, scores] = vl_ubcmatch(d1, d2);
  13. [dump,scoreind]=sort(scores,'ascend');
  14. %% 绘制组合图片
  15. newfig=zeros(size(img1,1), size(img1,2)+size(img2,2),3); %新构建一个3维数组,行为图片1
  16. %行数,列为图片1和图片2的列数和
  17. newfig(:,1:size(img1,2),:) = img1ori;
  18. newfig(1:size(img2,1) ,(size(img1,2)+1):end,:)=img2ori;
  19. newfig=uint8(newfig);
  20. figure;
  21. image(newfig); % 绘制组合图片
  22. axis image
  23. % colormap(gray)
  24. %% 绘制匹配特征点
  25. figure;
  26. image(newfig); % 绘制组合图片+匹配对于的特征点
  27. axis image
  28. f2Moved=f2; %因为此时图像在x方向发生了平移的,需要平移的大小为图1的列数
  29. m=size(img1,2)
  30. f2Moved(1,:) = f2Moved(1,:)+size(img1,2);
  31. h1 = vl_plotframe(f1); %对之前的四元组在组合照片上进行绘画
  32. h2 = vl_plotframe(f2Moved);
  33. set(h1,'color','g','linewidth',2) ;
  34. set(h2,'color','r','linewidth',2);
  35. hold on
  36. % 绘制scores前10%
  37. plotRatio=0.1;
  38. for i= 1:fix(plotRatio*size(matches,2)) %fix是取整函数,这里仅画出找到的匹配的前10%
  39. idx = scoreind(i);
  40. line([f1(1,matches(1,idx)) f2Moved(1,matches(2,idx))],...
  41. [f1(2,matches(1,idx)) f2Moved(2,matches(2,idx))], 'linewidth',1, 'color','b')
  42. end
  43. hold off
  44. %倒数第四行的...是因为matlab一行装不下,属于行行连接符

运行结果 :

 

对于其中一些变量进行展示:

  

scores是上面matches到的对应点的欧式距离,后面的scoreind是对欧式距离按由小到大进行排序,储存的是距离对于的序号

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/238943
推荐阅读
相关标签
  

闽ICP备14008679号