fbow模块

简介

fbow 是图像的特征点字典库,有以下功能:

  • 可以把多个图像中的特征点存放在一起形成数据库,并以文件的方式保存
  • 可以把新图像的特征点放到数据库里匹配,得到特征向量
  • 可以计算特征向量之间的相似度

详见fbow的github

安装

  • 下载
git clone https://github.com/rmsalinas/fbow.git
#或 wget https://github.com/rmsalinas/fbow/archive/master.zip
  • 编译安装
mkdir build
cd build
cmake ..
make
sudo make install

使用

注:代码来自这里

  • cmake
set( FBOW_INCLUDE_DIRS "/usr/local/include" )
set( FBOW_LIBS "/usr/local/lib/libfbow.so" )

#add_executable( app app.cpp )
#target_link_libraries( app ${OpenCV_LIBS} ${FBOW_LIBS} )
  • 训练词典
//训练词典的参数
fbow::VocabularyCreator::Params params;
//叶子节点的个数
params.k = 10;
//树的高度
params.L = 5;
//使用的线程数量
params.nthreads=1;
//最大迭代次数
params.maxIters=0;

//词典创建工具
fbow::VocabularyCreator vocabCat;
//词典
fbow::Vocabulary vocabulary;

//创建词典,descriptors是一个vector<cv::Mat>,把要聚类的词典读进来就行
vocabCat.create(vocabulary,descriptors,"hf-net",params);

//保存词典
vocabulary.saveToFile("filename");
  • 载入词典
//先创建一个词典
fbow::Vocabulary vocab;
//然后调用下面方法
vocab.readFromFile("filename");
  • 获取评分
//这个是带权值的节点向量
fbow::fBow bowvector1;
//通过词典获取,descriptor是一个cv::Mat
bowvector1 = vocab.transform(descriptor1);

fbow::fBow bowvector2;
bowvector2 = vocab.transform(descriptor2);

//两个向量评分,调用静态方法
double score = fbow::fBow::score(bowvector1,bowvector2);
  • 获取指定层数的节点向量
fbow::fBow bowvector;
//这个是描述子属于指定层的节点向量
fbow::fBow2 bowvector1;

//层数从0开始,descriptor是一个次cv:: Mat
vocab.transform(descriptor,4,bowvector,bowvector1)
  • 增量的训练方法
void filterDes(vector<vector<Mat>> & descriptorss ,vector<vector<vector<KeyPoint>>> & keyPointss, vector<Mat> &optiDescriptors){

vector<leafNode> allLeaf;
Mat allDes = descriptorss[0][0].clone();
vector<int> globalDesToLeaf;
globalDesToLeaf.resize(1000);

for(int i = 0 ; i < allDes.rows ; i++){
    leafNode temp;
    Mat descriptor = allDes.rowRange(i , i+ 1);
    temp.points.push_back(descriptor);
    allLeaf.push_back(temp);
    globalDesToLeaf[i] = i;
}

cout << "dataset number is:"<<descriptorss.size()<< endl;

for(int l = 0 ; l < descriptorss.size() ; l++){
    vector<Mat> descriptors = descriptorss[l];
    vector<vector<KeyPoint>> keyPoints = keyPointss[l];

    /*进行分类*/
    //先初始化
    Mat lastDes = descriptors[0].clone();
    vector<int> DesToLeaf;
    DesToLeaf.resize(lastDes.rows);
    vector<KeyPoint> lastKeyPoint = keyPoints[0];

    //开始比较全局的描述子本,初始此数据的节点
    //flann进行匹配
    vector<DMatch> matchesGlobal;
    FlannBasedMatcher matcher;
    matcher.match(lastDes,allDes , matchesGlobal);
    cout << "force match is " <<matchesGlobal.size() << endl;

    for(int i = 0 ; i < matchesGlobal.size() ; i++){
        DesToLeaf[matchesGlobal[i].queryIdx] = globalDesToLeaf[matchesGlobal[i].trainIdx];
    }

    //开始分类 descriptors.size()
    for(int i = 1 ; i <  descriptors.size(); i++){
        //flann进行匹配
        vector<DMatch> matches;
        FlannBasedMatcher matcher;
        matcher.match(descriptors[i], lastDes , matches);

        //对匹配的点进行重新排位
        vector<KeyPoint> leftpoints,rightpoints;
        for(int j = 0 ; j < matches.size() ; j++){
            leftpoints.push_back(keyPoints[i][matches[j].queryIdx]);
            rightpoints.push_back(lastKeyPoint[matches[j].trainIdx]);
        }

        //生成2d点
        vector<Point2f> ps1,ps2;
        for (unsigned j = 0; j < leftpoints.size(); j++)
            ps1.push_back(leftpoints[j].pt);

        for (unsigned j = 0; j < rightpoints.size(); j++)
            ps2.push_back(rightpoints[j].pt);

        //使用ransac方法筛选
        Mat status;
        findFundamentalMat(ps1,ps2,FM_RANSAC,0.99,1,status);

        //匹配成功的加入已经存在的节点
        int index = 0;
        int statuss[1000] = {0};

        vector<int> tempDesToLeaf;
        tempDesToLeaf.resize(descriptors[i].rows);

        for (int j = 0; j < matches.size(); j++) {
            if (status.at<uchar>(0,j) != 0 && statuss[matches[j].queryIdx] != 1){
                allLeaf[DesToLeaf[matches[j].trainIdx]].points.push_back(descriptors[i].rowRange(matches[j].queryIdx , matches[j].queryIdx + 1));
                tempDesToLeaf[matches[j].queryIdx] = DesToLeaf[matches[j].trainIdx];
                statuss[matches[j].queryIdx] = 1;
                index++;
            }
        }

        //增加新的节点
        for(int j = 0 ; j < descriptors[i].rows ; j++){
            if(statuss[j]) continue;
            leafNode temp;
            Mat newDes = descriptors[i].rowRange(j , j + 1);
            temp.points.push_back(newDes);
            allLeaf.push_back(temp);
            tempDesToLeaf[j] = allLeaf.size() - 1;

            allDes.push_back(newDes);
            globalDesToLeaf.push_back(tempDesToLeaf[j]);
        }

        lastDes = descriptors[i];
        lastKeyPoint = keyPoints[i];
        DesToLeaf = tempDesToLeaf;

    }

    cout << "finally all the cluster leaf node is:" << allLeaf.size() << endl;

}

//    开始构建聚类的mat
Mat allLeafMat;
for(int i = 0 ; i < allLeaf.size() ; i++){

    Mat clusterDes = cv::Mat::zeros(1, 256, CV_32F);
    int number = allLeaf[i].points.size();
    for(int j = 0 ; j < allLeaf[i].points[0].cols ; j++){
        float temp = 0 ;
        for(int k = 0 ; k < number ; k++){
            temp += allLeaf[i].points[k].at<float>(0, j);
        }
        clusterDes.at<float>(0,j) = temp / number;
    }
    allLeafMat.push_back(clusterDes);
}
optiDescriptors.push_back(allLeafMat);
cout << "all Leaf node is:" <<allLeafMat.rows << endl;
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值