目标
- 提取特征和描述子
- 匹配特征
- 展示匹配结果
SIFT
#include "openMVG/features/feature.hpp"
#include "openMVG/features/sift/SIFT_Anatomy_Image_Describer.hpp"
#include "openMVG/features/svg_features.hpp"
#include "openMVG/image/image_io.hpp"
#include "openMVG/image/image_concat.hpp"
#include "openMVG/matching/regions_matcher.hpp"
#include "openMVG/matching/svg_matches.hpp"
//
#include "third_party/stlplus3/filesystemSimplified/file_system.hpp"
#include <cstdlib>
#include <string>
#include <iostream>
using namespace openMVG;
using namespace openMVG::image;
using namespace openMVG::matching;
using namespace std;
int main() {
Image<RGBColor> image;
string jpg_filenameL = stlplus::folder_up(string("/home/lsy/openMVG/src/openMVG_Samples/features_siftPutativeMatches"))
+ "/imageData/StanfordMobileVisualSearch/Ace_0.png";
string jpg_filenameR = stlplus::folder_up(string("/home/lsy/openMVG/src/openMVG_Samples/features_siftPutativeMatches"))
+ "/imageData/StanfordMobileVisualSearch/Ace_1.png";
Image<unsigned char> imageL, imageR;
ReadImage(jpg_filenameL.c_str(), &imageL);
ReadImage(jpg_filenameR.c_str(), &imageR);
//--
// Detect regions thanks to an image_describer
//--
using namespace openMVG::features;
std::unique_ptr<Image_describer> image_describer(new SIFT_Anatomy_Image_describer);
std::map<IndexT, std::unique_ptr<features::Regions>> regions_perImage;
image_describer->Describe(imageL, regions_perImage[0]);
image_describer->Describe(imageR, regions_perImage[1]);
const PointFeatures
featsL = regions_perImage.at(0)->GetRegionsPositions(),
featsR = regions_perImage.at(1)->GetRegionsPositions();
//virtual PointFeatures GetRegionsPositions() const = 0;不好,返回不是引用
// Show both images side by side
{
Image<unsigned char> concat;
ConcatV(imageL, imageR, concat);
string out_filename = "00_images.jpg";
WriteImage(out_filename.c_str(), concat);
}
//std::unique_ptr<features::Regions>
const SIFT_Regions* regionsL = dynamic_cast<SIFT_Regions*>(regions_perImage.at(0).get());
const SIFT_Regions* regionsR = dynamic_cast<SIFT_Regions*>(regions_perImage.at(1).get());
//- Draw features on the two image (side by side)
{
Features2SVG
(
jpg_filenameL,
{imageL.Width(), imageL.Height()},
regionsL->Features(),
jpg_filenameR,
{imageR.Width(), imageR.Height()},
regionsR->Features(),
"01_features.svg"
);
}
//-- Perform matching -> find Nearest neighbor, filtered with Distance ratio
std::vector<IndMatch> vec_PutativeMatches;
{
// Find corresponding points
matching::DistanceRatioMatch(
0.8, matching::BRUTE_FORCE_L2,
*regions_perImage.at(0).get(),
*regions_perImage.at(1).get(),
vec_PutativeMatches);
// Draw correspondences after Nearest Neighbor ratio filter
const bool bVertical = true;
Matches2SVG
(
jpg_filenameL,
{imageL.Width(), imageL.Height()},
regionsL->GetRegionsPositions(),
jpg_filenameR,
{imageR.Width(), imageR.Height()},
regionsR->GetRegionsPositions(),
vec_PutativeMatches,
"02_Matches.svg",
bVertical
);
}
// Display some statistics
std::cout << featsL.size() << " Features on image A" << std::endl
<< featsR.size() << " Features on image B" << std::endl
<< vec_PutativeMatches.size() << " matches after matching with Distance Ratio filter" << std::endl;
return EXIT_SUCCESS;
}
特征点提取
可以选择三种方法:
std::unique_ptr<Image_describer> image_describer = AKAZE_Image_describer::create
(AKAZE_Image_describer::Params(AKAZE::Params(), AKAZE_MSURF));
std::unique_ptr<Image_describer> image_describer = AKAZE_Image_describer::create
(AKAZE_Image_describer::Params(AKAZE::Params(), AKAZE_MLDB));
std::unique_ptr<Image_describer> image_describer(new SIFT_Anatomy_Image_describer(SIFT_Anatomy_Image_describer::Params()));
//regions_fctory.hpp
/// Define the classic SIFT Keypoint
using SIFT_Regions = Scalar_Regions<SIOPointFeature, unsigned char, 128>;
/// Define the AKAZE Keypoint (with a float descriptor)
using AKAZE_Float_Regions = Scalar_Regions<SIOPointFeature, float, 64>;
/// Define the AKAZE Keypoint (with a LIOP descriptor)
using AKAZE_Liop_Regions = Scalar_Regions<SIOPointFeature, unsigned char, 144>;
/// Define the AKAZE Keypoint (with a binary descriptor saved in an uchar array)
using AKAZE_Binary_Regions = Binary_Regions<SIOPointFeature, 64>;
//matcher_type.hpp
enum EMatcherType : unsigned char
{
BRUTE_FORCE_L2,
ANN_L2,
CASCADE_HASHING_L2,
BRUTE_FORCE_HAMMING
};
匹配结果保存成图像
//features_image_matching
// Draw correspondences after Nearest Neighbor ratio filter
{
const bool bVertical = true;
Matches2SVG
(
jpg_filenameL,
{imageL.Width(), imageL.Height()},
regions_perImage.at(0)->GetRegionsPositions(),
jpg_filenameR,
{imageR.Width(), imageR.Height()},
regions_perImage.at(1)->GetRegionsPositions(),
vec_PutativeMatches,
"02_Matches.svg",
bVertical
);
}
c++技巧
string jpg_filenameL = stlplus::folder_up(string("/home/lsy/openMVG/src/openMVG_Samples/features_siftPutativeMatches"))
+ "/imageData/StanfordMobileVisualSearch/Ace_0.png";
//folder_up : 输入"1/2/3", 输出"1/2"