sift特征提取+Kmean+SVM分类

新手上路,从头讲起

1、工具

原版代码:http://www.cs.ubc.ca/~lowe/keypoints/

vlfeat工具:http://www.vlfeat.org/index.html

这两个工具都可以进行sift特征提取以及匹配。我使用的是vlfeat工具箱,使用环境为win10,matlab。

  • 下载:
  • 下载后得到一个压缩包:
  • 将压缩包放到任意文件夹下并解压,得到文件:
  • 在matlab中打开解压后的文件夹,进入toolbox子文件夹,如红色框;然后双击打开vl_setup.m脚本,如蓝色框。
  • 运行vl_setup.m代码。
  • 在matlab当中进入自己的工程所在文件夹就可以调用vlfeat里面的函数了。不过这个方法需要每次使用之前执行vl_setup.m文件比较麻烦。可以长期导入,方法自行百度。


2、sift特征提取

  • 我在本次实验中只需要提取sift特征,并不涉及匹配相关。
image=imread('1.jpg'); %读取图片,此处读取图片为RGB
I = single(rgb2gray(image)); %函数传入图片格式固定为二维图像的single或者double类型,因此此处转为灰度,并改数据格式为single
I=(I-min(min(I))+1)/(max(max(I))-min(min(I))+1); %因为single格式图片需要数据范围为0~1时才可以正常显示,因此在这里调整一次数据大小,方便显示。
                                                 %实际上上一步的I转为single格式之后就可以了,有无这一步的操作并不会影响特征提取。
[f,d] = vl_dsift(I) ; %特征提取,得到的f是一个2*n的矩阵,每一列是一个坐标;d是特征数据,是一个128*n的矩阵,每列是一个特征。
  • sift特征提取的详细过程讲解:https://ianlondon.github.io/blog/how-to-sift-opencv/

3、    k-mean

  • 因为sift特征的特征点个数(keypoint)对于每张图片都是不一样的,因此没有办法直接进行SVM分类。参考多方文献之后发现比较多的文献用的是一种叫做BagOfWordsModel的方法,使用该方法对sift特征进行投影并归一化使特征长度一致。
  • 相关的讨论1(有ppt):https://www.researchgate.net/post/Image_classification_using_SIFT_features_and_SVM2
  • 相关的讨论2:https://stackoverflow.com/questions/19048891/training-of-svm-classifier-using-sift-features
  • 然后看不懂BOW方法的我发现大家用的其实是K-MEAN。
X=[];
for i=1:sizepic %循环一个所有图片
    name=piclist(i).name;
    feature=load(name); %读取之前保存的每张图片的特征矩阵的*.mat文件
    d=vertcat(feature.d); %因为之间保存的时候将f和d都保存了,所以需要从feature结构体中读取矩阵d
    Xpos=[Xpos,d]; %将矩阵简单的叠加起来,这里每一列是一个keypoint,所以把矩阵横向叠加
end
Xpos=double(Xpos); %由于kmean的函数要求数据格式为single或者double,因此这里将矩阵的数据格式转换为double
[Cp, Ap] = vl_kmeans(Xpos, 50, 'verbose', 'distance', 'l1', 'algorithm', 'elkan'); %kmean聚类,具体函数详解查看vlfeat文档啊

  • 在这里有一个疑问,在参考的代码方法中,给每一个类的所有图片做一个k-mean,保证k-mean之后数据长度一致。这样使用K-mean分类后的准确高达99%。但是在测试的时候就产生了一个问题,收到的数据到底应该使用哪一个聚类中心进行特征转化,进而进行识别。
  • 针对这一问题,我做了一个测试,将所有训练数据都适应于两个聚类中心进行聚类,每张图片最终得到了两个1*50的特征,将这两个特征分别使用模型进行分类。分类结果发现96%数据都是使用A的聚类中心聚类后分类结果为A类,使用B的聚类中心进行聚类后分类结果为B。
  • 对此,我使用所有的sift特征进行k-mean聚类,对两类图片的sift特征进行聚类变换之后进行分类,发现其分类准确率降低到了90%。


4、将每一张图片的特征放入k-mean聚类中心中转换

name=list(i).name;
image=imread(name);
I = single(rgb2gray(image)) ;
I=(I-min(min(I))+1)/(max(max(I))-min(min(I))+1);

[f,d] = vl_dsift(I) ; % sift

featVec=zeros(1,50);
for j=1:size(d,2)
    fi = double(d(:,j));
    diffMat = repmat(fi, 1,50) - Cp;
    sqSum = sum(diffMat.^2,1);
    dist = sqrt(sqSum);
    [val,idx]=min(dist);
    featVec(1,idx) = 1+ featVec(1,idx) ;
end

feature(count,:)=[featVec,1]; % 将特征和标签一起放入特征集合
count=count+1;

5、分类模型

  • 使用matlab自带的APP工具进行分类,在尝试了SVM,KNN,随机森林等多种分类方法之后选择了随机森林的分类模型作为实验的分类模型。

6、分类测试

lab = module.predictFcn(featVec); #传入与训练模型一致的50维特征进行分类




其他参考网站链接

  • 参考代码:https://blog.csdn.net/u012874151/article/details/45457085

博主的代码是python代码,很详细。

  • 算法思路:https://blog.csdn.net/m0_37393277/article/details/74987165

博主很详细的讲解了sift+kmean+svm的算法思想,博主的论文里面的东西在博客当中基本已经讲解清楚了,除了一个不同数量聚类中心的对比试验在论文中详细讲解,其他都讲完了。

  • sift应用实例:https://blog.csdn.net/abcjennifer/article/details/7365882






### 回答1: SIFT(尺度不变特征转换)是一种图像特征提取算法,而RANSAC(随机抽样一致性)是一种用于剔除误匹配点的算法。下面是关于如何在OpenCV 3.0中实现这两种算法的简要步骤。 首先,打开一个图像并加载其所需的库: ``` import cv2 import numpy as np ``` 然后,我们可以从图像中提取SIFT特征: ``` # 加载图像 img = cv2.imread('image.jpg',0) # 创建SIFT对象 sift = cv2.xfeatures2d.SIFT_create() # 检测并计算SIFT特征 keypoints, descriptors = sift.detectAndCompute(img, None) ``` 接下来,我们可以使用RANSAC算法来剔除误匹配点: ``` # 创建FLANN匹配器对象 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) # 在两幅图像之间匹配特征点 matches = flann.knnMatch(descriptors1, descriptors2, k=2) # 进行RANSAC过滤 good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) # 绘制匹配结果 result = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, flags=2) cv2.imshow('Matches', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,我们首先创建了一个FLANN(快速最近邻搜索)匹配器对象,然后使用`knnMatch`函数在两幅图像之间进行特征点的匹配。最后,我们使用RANSAC算法对匹配点进行过滤,并将结果绘制出来。 以上是在OpenCV 3.0中实现SIFT特征提取和RANSAC误匹配点剔除的简要步骤。实际操作中还可以进行更详细的参数设置和优化,以便得到更好的匹配结果。 ### 回答2: OpenCV 3.0 是一个非常强大的计算机视觉库,它提供了许多功能来处理图像处理和计算机视觉任务。其中包括使用SIFT算法进行特征提取使用RANSAC算法进行误匹配点的剔除。 首先,SIFT(尺度不变特征变换)是一种用于在图像中检测和描述关键点的算法。在OpenCV 3.0中,你可以使用`cv2.xfeatures2d.SIFT_create()`来创建一个SIFT对象。然后,你可以使用`detectAndCompute()`方法来检测并计算图像的关键点和特征描述符。通过调用这个方法,你将得到检测到的关键点和对应的特征描述符。 接下来,我们可以使用RANSAC(随机样本一致性)算法来剔除误匹配点。RANSAC算法能够通过随机选择样本子集并估计模型参数来寻找数据中的局内点。在OpenCV 3.0中,你可以使用`cv2.RANSAC`作为参数来创建一个RANSAC对象。然后,你可以使用`findHomography()`方法来计算通过RANSAC算法筛选后的匹配点之间的透视变换矩阵。这个矩阵可以用来剔除误匹配点。 总结一下,OpenCV 3.0可以通过`cv2.xfeatures2d.SIFT_create()`方法进行SIFT特征提取,并使用RANSAC算法来剔除误匹配点。这两个功能都是非常有用的计算机视觉任务,能够帮助我们更好地处理和分析图像。 ### 回答3: 在OpenCV 3.0中,可以使用SIFT算法进行图像的特征提取,并采用RANSAC算法剔除误匹配点。 SIFT(Scale-Invariant Feature Transform)特征提取算法是一种基于尺度空间的特征提取方法,它可以提取图像中的稳定特征点和其对应的描述子。在OpenCV中,可以使用sift.detectAndCompute()函数来提取图像的SIFT特征点和描述子。 RANSAC(Random Sample Consensus)算法是一种鲁棒的参数估计算法,它可以从一组数据中剔除异常点,从而得到准确的模型参数。在特征匹配中,可以使用RANSAC算法来剔除误匹配点,以提高匹配的准确性。 具体实现的步骤如下: 1. 导入OpenCV和Numpy库,并读取需要进行特征匹配的两幅图像。 ```python import cv2 import numpy as np img1 = cv2.imread('image1.jpg', 0) img2 = cv2.imread('image2.jpg', 0) ``` 2. 创建SIFT对象,并使用sift.detectAndCompute()函数提取图像的SIFT特征点和描述子。 ```python sift = cv2.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) ``` 3. 使用FLANN匹配器对两幅图像的描述子进行匹配。 ```python FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1, des2, k=2) ``` 4. 运用RANSAC算法剔除误匹配点。 ```python good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) ``` 通过以上步骤,我们可以得到经过RANSAC算法筛选后的匹配点,并且可以通过M矩阵获取图像的对应关系。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值