基于OpenCV的BOW特征提取

本文介绍了如何在OpenCV中利用SIFT特征提取和BOW(Bag of Words)模型进行图像处理。首先,通过SIFT算子提取关键点信息,接着进行聚类形成词典。然后,通过计算直方图得到BOW特征,用于图像匹配和后续的分类任务。文章提供了代码解析和Demo示例。
部署运行你感兴趣的模型镜像

1. 前言

在OpenCV中使用SIFT特征提取算子进行特征提取是跟简单的事情了,通过调用API也就下面几行代码的事情

cv::SiftFeatureDetector detector;
std::vector<cv::KeyPoint> keypoint;
detector.detect(image, keypoint); //image是需要进行特征提取的图像
std::cout << "\ndetected SIFT feature point size: " << keypoint.size() << "\n";

//获得每个特征点的128维特征向量
cv::SiftDescriptorExtractor extractor;
cv::Mat des1;   //descriptor
extractor.compute(image, keypoint, des1);

但是在进行诸如匹配的时候由于提取出来的SIFT特征样本的数目是不同的,这就需要进行映射抽取,这就讲到了今天说到的BOW特征,抽取到BOW特征之后可以简单得进行欧式距离的比较,或是放入后面的分类器进行训练。

2. 实现原理

BOW模型的处理过程:
1. SIFT特征提取。SIFT 特征提取是求出图像的关键点信息,包括角度,大小以及强度。关键点,也就是能够代表图像关键信息的部分,这也是Bag of words中单词的组成。一个图像通常有很多的关键点。
2. 聚类。我们将每幅图像中的关键点信息添加到词袋中,并定义聚类中心的数量N。然后将词袋中的关键点通过Kmeans算法聚类到N个类中。同时得到这N个类的中心点组成N*128的dictionary,每个中心都可以代表这个类。
3. 求图像的直方图。将图像的关键点信息重新放到词包中,根据落在每个类中关键点的数量来得到图像的直方图,大小为1*N。将每幅图像进行处理,得到图像在BOW模型下的特征。
4. 图像匹配。将测试图像进行相同的处理,同样也得到1*N的特征。根据测试图像与训练图像特征之间的距离,并将距离较小的图像作为检索的结果。

3. 代码解析

在生成BOW特征过程中主要涉及到特征聚类产生BOW特征描述(归一化直方图)。
首先来看聚类,聚类使用到的是BOWKMeansTrainer 这个类,

class BOWKMeansTrainer : public BOWTrainer
{
public:
    BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
                      int attempts=3, int flags=KMEANS_PP_CENTERS );
    virtual ~BOWKMeansTrainer(){}

    // Returns trained vocabulary (i.e. cluster centers).
    virtual Mat cluster() const;
    virtual Mat cluster( const Mat& descriptors ) const;

protected:
    ...
};

这里主要使用的是它的构造函数,调用的时候定好需要分出的类数目,其它的参数默认就好。第二个是成员函数cluster(const Mat& descriptors)。
之后是生成BOW特征,使用到的类是BOWImgDescriptorExtractor,基于视觉词典包算法来计算一个图像的特征描述子的类。算法步骤如下:
1. 给定一幅图像及其图像特征检测子(关键点)集,计算特征描述子。
2. 给定每一个图像特征检测子对应的特征描述子,从视觉词典中寻找最近的词。
3. 计算视觉词典包图像特征描述子.该结果为一个归一化后的直方图.直方图向量中第i个 值是视觉词典中的第i个词在给定图像中的频率。
该类的接口定义为:

class BOWImgDescriptorExtractor
{
public:
    BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
                               const Ptr<DescriptorMatcher>& dmatcher );
    virtual ~BOWImgDescriptorExtractor(){}

    void setVocabulary( const Mat& vocabulary );
    const Mat& getVocabulary() const;
    void compute( const Mat& image, vector<KeyPoint>& keypoints,
                  Mat& imgDescriptor,
                  vector<vector<int> >* pointIdxsOfClusters=0,
                  Mat* descriptors=0 );
    int descriptorSize() const;
    int descriptorType() const;

protected:
    ...
};

这里主要调用compute成员函数

4. Demo代码

cv::initModule_nonfree();
cv::BOWKMeansTrainer bowTraining(feature_num);                  //定义一个对象,生成聚类中心cluster_num(聚类的数目)个,其余的默认参数
cv::Mat dictionary = bowTraining.cluster(feature_discriptor);   //按照设置好的聚类数目进行聚类,生成字典集,也就是聚类中心 ,feature_discriptor是SIFT生成的特征描述

//聚类中心的映射初始化
cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("SIFT"); //引号里面修改特征种类。  
cv::Ptr<cv::DescriptorMatcher>  matcher = cv::DescriptorMatcher::create("BruteForce"); //引号里面修改匹配类型;  
cv::BOWImgDescriptorExtractor bowDE(extractor, matcher);    //直方图统计
bowDE.setVocabulary(dictionary);    //dictionary是通过前面聚类得到的词典

std::vector<cv::KeyPoint> keypoints;
cv::SiftFeatureDetector detector;
cv::Mat descriptors;
detector.detect(img, keypoints);    //SIFT提取图像的特征点
bowDE.compute(img, keypoints, descriptors); //提取该图像的BOW特征描述

5. 参考资料

  1. opencv 中关于BOW模型的实现以及相关的函数解释
  2. 物体目标分类
  3. 学习OpenCV——BOW特征提取函数(特征点篇)

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值