注释:
蓝体字是opencv249专用的修改;
黑体字是opencv3需要的修改
环境:
vs2012 32bit
叙述比较简略。不明之处可以留言
1. 配置opencv 2.4.9
需要surf支持,应该可以用orb替换
(本方法orb替换后仍然有pFirstBlock == pHead错误,建议使用opencv3)
(或者是能够使用extra module,cmake成功生成lib应该也可以)
#1.配置opencv3.0.0/3.1.0/3.2.0等
如果需要使用surf,在opencv的cmake过程需要包含opencv的extra module(非免费开放的库)
2. CMAKE DLib
需要opencv的支持
需要boost库支持(git)
生成debug和release的静态库,类型Mtd/Mt
3. 新建vs工程
4.移动文件
将DBoW2-master 中的src文件夹下的cpp文件包含进工程
将demo代码添加进来(main函数)
5.包含文件
头文件包含:
DBoW2-master的include
DLib-master的include
Opencv的include
根据编译结果灵活修改
库文件包含:
DLib-master的cmake出来的lib
Opencv的lib(opencv3以后需要自己cmake,或者是使用opencv_worldxxx.lib)可以参考opencv的配置。
6.修改代码
#1添加预编译头 #include”stdfx.h”
#2 修改FORB.cpp
void FORB::toMat8U(const std::vector<TDescriptor>&descriptors, cv::Mat &mat)
std::copy(d, d + FORB::L, p);
改成
std::copy(d, d + FORB::L,stdext::unchecked_array_iterator<unsigned char*>(p));
#3将demo中的image文件夹放到新建的vs工程中。
7.opencv3适用的main函数见9
修改main函数(opencv249版本,(pFirstBlock == pHead错误)有时候会发生)
loadFeatures
voidloadFeatures(vector<vector<vector<float> > > &features)
{
features.clear();
features.reserve(NIMAGES);
///cv::Ptr<cv::xfeatures2d::SURF>surf = cv::xfeatures2d::SURF::create(400, 4, 2, EXTENDED_SURF);// chenhui
cv::SURF surf( 400, 4, 2, EXTENDED_SURF );//chenhui
cout << "Extracting SURFfeatures..." << endl;
for(int i = 0; i < NIMAGES; ++i)
{
stringstream ss;
ss << "images/image"<< i << ".png";
cv::Mat image = cv::imread(ss.str(), 0);
cv::Mat mask;
vector<cv::KeyPoint> keypoints;
vector<float> descriptors;
/surf->detectAndCompute(image,mask, keypoints, descriptors); /// chenhui
///surf.compute(image, mask,keypoints, descriptors); /// chenhui
surf.operator()(image, mask, keypoints,descriptors);
features.push_back(vector<vector<float> >());
changeStructure(descriptors,features.back(), surf.descriptorSize());
}
}
8. 总体属性
#1属性 -> C/C++ -> 代码生成-> 代码生成 :Mtd/Mt(dubug和release两个版本);
对于opencv249,C/C++ 命令行->其他选项,输入(/D "_AFXDLL")可能可以解决(pFirstBlock == pHead错误)
9. demo的代码
/**
* File: Demo.cpp
* Date: November 2011
* Author: Dorian Galvez-Lopez
* Description: demo application of DBoW2
* License: see the LICENSE.txt file
*/
/**
* This is a modified version of TemplatedVocabulary.h from DBoW2 (see below).
* Added functions: Save and Load from text files without using cv::FileStorage.
* Date: August 2015
* Raúl Mur-Artal
*/
/*
修改后的 DBow2 demo
修改内容:
#1 使用orb提取特征
#2 需要使用由 Raúl Mur-Artal 修改的 TemplatedVocabulary.h (在orb_slam2的工程中提供)
#3 包含生成词袋和测试词袋的代码
修改时间:2017.03.22
修改说明:
#1 生成的词袋没有英文的提示信息,全部都是数据。
如果看过voc.save和voc.saveToTextFile 生成的文件,就知道这两个结果的差异就是save出来的含有英文的注释,而saveToTextFile是纯数据。
恰恰orb_slam2中所使用的词袋是 saveToTextFile 出来的,使用save的结果就读不了了(原因显而易见)。
*/
#include "stdafx.h"
#include <iostream>
#include <vector>
// DBoW2
#include "DBoW2.h" // defines Surf64Vocabulary and Surf64Database
#include <DUtils/DUtils.h>
#include <DVision/DVision.h>
// OpenCV
#include "opencv2/stitching/detail/matchers.hpp"
#include <opencv2/opencv.hpp>
// 调整到何时的路径,或者使用其他的方法加载静态库
#pragma comment( lib, "vfw32.lib" )
#pragma comment( lib, "comctl32.lib" )
#pragma comment( lib, "C:\\ippicvmt.lib" )
#if 1
// debug
#pragma comment( lib, "IlmImfd.lib" )
#pragma comment( lib, "libjasperd.lib" )
#pragma comment( lib, "libjpegd.lib" )
#pragma comment( lib, "libpngd.lib" )
#pragma comment( lib, "libtiffd.lib" )
#pragma comment( lib, "libwebpd.lib" )
#pragma comment( lib, "zlibd.lib" )
#pragma comment( lib, "opencv_core300d.lib" )
#pragma comment( lib, "opencv_highgui300d.lib" )
#pragma comment( lib, "opencv_imgproc300d.lib" )
#pragma comment( lib, "opencv_calib3d300d.lib" )
#pragma comment( lib, "opencv_features2d300d.lib" )
#pragma comment( lib, "opencv_flann300d.lib" )
#pragma comment( lib, "opencv_imgcodecs300d.lib" )
#pragma comment( lib, "opencv_objdetect300d.lib" )
#pragma comment( lib, "opencv_hal300d.lib" )
#pragma comment( lib, "opencv_photo300d.lib" )
#pragma comment( lib, "opencv_shape300d.lib" )
#pragma comment( lib, "opencv_superres300d.lib" )
#pragma comment( lib, "opencv_video300d.lib" )
#pragma comment( lib, "opencv_stitching300d.lib" )
#pragma comment( lib, "opencv_videoio300d.lib" )
#else
// release
#pragma comment( lib, "C:\\IlmImf.lib" )
#pragma comment( lib, "C:\\libjasper.lib" )
#pragma comment( lib, "C:\\libjpeg.lib" )
#pragma comment( lib, "C:\\libpng.lib" )
#pragma comment( lib, "C:\\libtiff.lib" )
#pragma comment( lib, "C:\\libwebp.lib" )
#pragma comment( lib, "C:\\zlib.lib" )
#pragma comment( lib, "C:\\opencv_core300.lib" )
#pragma comment( lib, "C:\\opencv_highgui300.lib" )
#pragma comment( lib, "C:\\opencv_imgproc300.lib" )
#pragma comment( lib, "C:\\opencv_calib3d300.lib" )
#pragma comment( lib, "C:\\opencv_features2d300.lib" )
#pragma comment( lib, "C:\\opencv_flann300.lib" )
#pragma comment( lib, "C:\\opencv_imgcodecs300.lib" )
#pragma comment( lib, "C:\\opencv_objdetect300.lib" )
#pragma comment( lib, "C:\\opencv_hal300.lib" )
#pragma comment( lib, "C:\\opencv_photo300.lib" )
#pragma comment( lib, "C:\\opencv_shape300.lib" )
#pragma comment( lib, "C:\\opencv_superres300.lib" )
#pragma comment( lib, "C:\\opencv_video300.lib" )
#pragma comment( lib, "C:\\opencv_stitching300.lib" )
#pragma comment( lib, "C:\\opencv_videoio300.lib" )
#endif
using namespace DBoW2;
using namespace DUtils;
using namespace std;
using namespace cv::detail;
// - - - - - --- - - - -- - - - - -
/// ORB Vocabulary
typedef DBoW2::TemplatedVocabulary<DBoW2::FORB::TDescriptor, DBoW2::FORB> ORBVocabulary;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void extractORBFeatures(cv::Mat &image, vector<vector<cv::Mat> > &features, FeaturesFinder *finder) ;
void changeStructureORB( const cv::Mat &descriptor,vector<bool> &mask, vector<cv::Mat> &out);
void isInImage(vector<cv::KeyPoint> &keys, float &cx, float &cy, float &rMin, float &rMax, vector<bool> &mask);
void createVocabularyFile(ORBVocabulary &voc, std::string &fileName, const vector<vector<cv::Mat> > &features);
void test(vector<vector<cv::Mat> > &features);
// ----------------------------------------------------------------------------
const int N_IMAGES = 31; // 图的数量
int main()
{
vector<std::string> filenames;
for(int i = 0; i < N_IMAGES; ++i)
{
stringstream ss;
ss << "AAA/ccc" << i << ".bmp"; // 根据文件所在位置和文件名设置
filenames.push_back(ss.str());
}
// initialze ORBextractor
int nLevels = 5;//6;
// chenhui
cv::Ptr<cv::detail::FeaturesFinder> finder;
finder = new OrbFeaturesFinder(cv::Size(5,5), 5000, 1.05f, 3);
int nImages = filenames.size();
vector<vector<cv::Mat > > features;
features.clear();
features.reserve(nImages);
cv::Mat image;
cout << "> Extracting Features from " << nImages << " images..." << endl;
for(int i = 0; i < nImages; ++i)
{
std::cout << "Processing the " << i <<" image " << std::endl;
cv::Mat src = cv::imread(filenames[i], CV_LOAD_IMAGE_UNCHANGED);
imshow("View", src);
cv::waitKey(1);
if (!src.empty())
{
//cv_ptr = cv_bridge::toCvShare(i);
//cv::cvtColor(src, image, CV_RGB2GRAY); // 单通道图像就不需要再转
image = src;
extractORBFeatures(image, features, finder);
}
}
//bag.close();
cout << "... Extraction done!" << endl;
// Creating the Vocabulary
// define vocabulary
const int k = 10; // branching factor
const WeightingType weight = IDF;
const ScoringType score = L1_NORM;
ORBVocabulary voc(k, nLevels, weight, score);
std::string vociName = "vociOmni.txt";
createVocabularyFile(voc, vociName, features);
cout << "\n--- START TEST ---\n" << endl;
test(features);
cout << "--- THE END ---" << endl;
return 0;
}
// ----------------------------------------------------------------------------
void extractORBFeatures(cv::Mat &image, vector<vector<cv::Mat> > &features, FeaturesFinder *finder)
{
vector<cv::KeyPoint> keypoints;
cv::Mat descriptorORB;
// extract
ImageFeatures features300;
(*finder)(image, features300);
descriptorORB = features300.descriptors.getMat(cv::ACCESS_RW);
keypoints = features300.keypoints;
// reject features outside region of interest
vector<bool> mask;
float cx = 0; float cy = 0;
float rMin = 0; float rMax = 0;
isInImage(keypoints, cx, cy, rMin, rMax, mask);
// create descriptor vector for the vocabulary
features.push_back(vector<cv::Mat>());
changeStructureORB(descriptorORB, mask, features.back());
imshow("ORBFeature", features.back().back());
}
// ----------------------------------------------------------------------------
void changeStructureORB( const cv::Mat &descriptor,vector<bool> &mask, vector<cv::Mat> &out) {
for (int i = 0; i < descriptor.rows; i++) {
if(mask[i]) {
out.push_back(descriptor.row(i));
}
}
}
// ----------------------------------------------------------------------------
void isInImage(vector<cv::KeyPoint> &keys, float &cx, float &cy, float &xMax, float &yMax, vector<bool> &mask) {
int N = keys.size();
mask = vector<bool>(N, false);
mask = vector<bool>(N, true);
int num = 0;
// for(int i=0; i<N; i++) {
// cv::KeyPoint kp = keys[i];
// float u = kp.pt.x;
// float v = kp.pt.y;
// //if(u>20 && u<320-20 && v>20 && v<240-20)
//if(u>cx && u<xMax && v>cy && v<yMax)
// {
// mask[i] = true;
// num ++;
// }
// }
std::cout << "In image number " << num << std::endl;
}
// ----------------------------------------------------------------------------
void createVocabularyFile(ORBVocabulary &voc, std::string &fileName, const vector<vector<cv::Mat> > &features)
{
cout << "> Creating vocabulary. May take some time ..." << endl;
voc.create(features);
cout << "... done!" << endl;
cout << "> Vocabulary information: " << endl
<< voc << endl << endl;
// save the vocabulary to disk
cout << endl << "> Saving vocabulary..." << endl;
voc.saveToTextFile(fileName); // orb_slam2支持的save
voc.save(fileName); // 最基本的save
cout << "... saved to file: " << fileName << endl;
}
void test(vector<vector<cv::Mat> > &features)
{
// branching factor and depth levels
const int k = 9;
const int L = 3;
const WeightingType weight = IDF;
const ScoringType score = L1_NORM;
ORBVocabulary voc(k, L, weight, score); // 读取当前图像
cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl;
voc.create(features);
cout << "... done!" << endl;
cout << "Vocabulary information: " << endl
<< voc << endl << endl;
// lets do something with this vocabulary
cout << "Matching images against themselves (0 low, 1 high): " << endl;
BowVector v1, v2;
for(int i = 0; i < N_IMAGES; i++)
{
voc.transform(features[i], v1);
for(int j = 0; j < N_IMAGES; j++)
{
voc.transform(features[j], v2);
double score = voc.score(v1, v2);
cout << "Image " << i << " vs Image " << j << ": " << score << endl;
}
}
// save the vocabulary to disk
cout << endl << "Saving vocabulary..." << endl;
voc.save("small_voc.yml.gz");
cout << "Done" << endl;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)