密集的SIFT袋功能

时间:2015-04-23 07:40:32

标签: opencv sift bag

我正在尝试使用OpenCV使用功能包(BoF)进行密集的SIFT特征提取。我们的想法是遵循this教程,但只需稍加改动即可使用密集的SIFT功能。

如您所知,在BoF范例的第一部分中,我们创建了可视字典。所以带有一些修改的代码是这样的:

#include<iostream>
#include<vector>
#include<dirent.h>

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/nonfree.hpp>

// This is a dense sampling of SIFT descriptors.



using namespace std;
using namespace cv;

void dense_SIFT_BoW(Mat img_raw, Mat &featuresUnclustered);
void SIFT_matcher(Mat img_raw, Mat &dictionary, Mat &bowTry, Ptr<DescriptorMatcher> &matcher);

#define DICTIONARY_BUILD 0

int main()
{
    #if DICTIONARY_BUILD == 1
    initModule_nonfree();

     // Store detected image key points.

    Mat featuresUnclustered;

    DIR *pDir = nullptr;
    string imgDir("D:/WillowActions Backup/Willow 300_200/sample/");// Directory of your images. (Change this according to where you images are)
    string imgPath;
    pDir = opendir(imgDir.c_str());
    string dirName;

    Mat img_raw; // Our loaded image.

    struct dirent *pent = nullptr; // dirent structure for directory manipulation.

    if(pDir == nullptr)
    {
        cout << "Directory pointer could not be initialized correctly ! " << endl; // Some checking.
        return 1;
    }

    int count = 0;

    cout << "Please WAIT..." << endl;

    while((pent = readdir(pDir)) != nullptr)
    {
        if(pent == nullptr)
        {
            cout << " Dirent struct could not be initialized correctly !" << endl;
            return 1;
        }

        if(!strcmp(pent->d_name,".")||!strcmp(pent->d_name,".."))
        {

        }
        else
        {
            // LOOP trough the directory to read image one by one and extract their Dense SIFT
            dirName = pent->d_name;
            imgPath = imgDir+dirName; // Overall image path... feed this to imread();
            img_raw = imread(imgPath,1);// read the image to extract denseSIFT features
            dense_SIFT_BoW(img_raw, featuresUnclustered);
            count++;
        }
    }

    cout << "Number of files in folder: " << count << endl;

   cout << featuresUnclustered.size() << endl;

   //Construct BOW k-means trainer
    // the number of bags
    int dictionarySize = 5;

    //define term criteria
    TermCriteria tc(CV_TERMCRIT_ITER, 100, 0.001);

    // retry number
    int retries = 1;

    //necessary flags
    int flags = KMEANS_PP_CENTERS;

    //Create the BOW trainer
    BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);

    //cluster the feature vectors
    Mat dictionary = bowTrainer.cluster(featuresUnclustered);

    //store the vocabulary
    FileStorage fs("D:/WillowActions Backup/Willow 300_200/Dense.xml", FileStorage::WRITE);
    fs << "Vocabulary" << dictionary;
    fs.release();

函数dense_SIFT_BoW(img_raw,featuresUnclustered)定义为:

void dense_SIFT_BoW(Mat img_raw,Mat &featuresUnclustered)
{

    Mat descriptors; // Store our dense SIFT descriptors.
    vector<KeyPoint> keypoints;

    DenseFeatureDetector detector(12.f, 1, 0.1f, 10);

    detector.detect(img_raw,keypoints);

    Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create("SIFT");

    descriptorExtractor->compute(img_raw,keypoints,descriptors);

    descriptors.setTo(0, descriptors < 0);
    descriptors = descriptors.reshape(0,1);

    featuresUnclustered.push_back(descriptors);


}

它本质上是通过每个图像的文件夹循环,为所有图像提取密集的SIFT特征并进行K-means聚类。这构建了可视字典。

这部分代码对我来说很好。即在包含256个图像文件的文件夹中,我得到一个大小为256 x 76800的字典(逐列:集群中心)。创建字典后。

现在,创建了词典。遵循BoF范例,我们希望再次提取密集的SIFT并与刚刚创建的词典进行匹配。为此,我使用最近的邻居。它本质上也是循环图像的文件夹。这就是我所拥有的:

#else

    Mat dictionary;
    FileStorage fs("D:/WillowActions Backup/Willow 300_200/Dic_Dense.xml", FileStorage::READ);
    fs["Vocabulary"] >> dictionary;
    fs.release();

    //Create a nearest neighbor matcher
    Ptr<DescriptorMatcher> matcher(new FlannBasedMatcher);

    //Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create("SIFT");

    cout << dictionary.size() << endl;

    DIR *pDir = nullptr;
    string imgDir("D:/WillowActions Backup/Willow 300_200/sample/");// Directory of your images. (Change this according to where you images are)
    string imgPath;
    pDir = opendir(imgDir.c_str());
    string dirName;

    Mat img_raw; // Our loaded image.
    Mat bowTry;

    struct dirent *pent = nullptr; // dirent structure for directory manipulation.

    if(pDir == nullptr)
    {
        cout << "Directory pointer could not be initialized correctly ! " << endl; // Some checking.
        return 1;
    }

    int count = 0;

    cout << "Please WAIT..." << endl;

    while((pent = readdir(pDir)) != nullptr)
    {
        if(pent == nullptr)
        {
            cout << " Dirent struct could not be initialized correctly !" << endl;
            return 1;
        }

        if(!strcmp(pent->d_name,".")||!strcmp(pent->d_name,".."))
        {

        }
        else
        {
            // LOOP trough the directory to read image one by one and extract dense SIFT
            dirName = pent->d_name;
            imgPath = imgDir+dirName; // Overall image path... feed this to imread();
            img_raw = imread(imgPath,1);// read the image to extract HOG features
            SIFT_matcher(img_raw, dictionary, bowTry, matcher);
            cout << count << endl;
            count++;
        }
    }

    cout << "no of images: " << count << endl;

    //open the file to write the resultant descriptor
    FileStorage fs1("D:/WillowActions Backup/Willow 300_200/Features_train.xml", FileStorage::WRITE);

    //write the new BOF descriptor to the file
    fs1 << "Vocabulary" << bowTry;



    fs1.release();


    #endif

   waitKey(0);
   return 0;

}

函数SIFT_matcher(img_raw,dictionary,bowTry,matcher)是这样的:

void SIFT_matcher(Mat img_raw, Mat &dictionary, Mat &bowTry, Ptr<DescriptorMatcher> &matcher)
{

    Mat descriptors;
    vector<KeyPoint> keypoints;
    DenseFeatureDetector detector(12.f,1,0.1f,10);

    detector.detect(img_raw,keypoints);

    Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create("SIFT");

    //create BOF descriptor extractor
    BOWImgDescriptorExtractor bowDE(descriptorExtractor, matcher);

    bowDE.setVocabulary(dictionary);


    //To store BOF representation of the image
    Mat bowDescriptor;

    //extract BOF descriptor from given image
    bowDE.compute(img_raw,keypoints,bowDescriptor);

    bowTry.push_back(bowDescriptor);

    bowDescriptor.release();

}

所以,问题在于第二部分。每当我运行第二部分时程序停止工作&#34; programX.exe已停止工作&#34;。编译器和控制台不会生成错误。也许我一直在忽视一些事情。建议,评论和帮助非常受欢迎。提前谢谢。

0 个答案:

没有答案