使用opencv实现线特征lsd提取、lbd描述子匹配实现:
具体逻辑如下:
1.设置读图的路径
2. 加载图片
3. 创建mask掩代码
4.初始化参数
5.检测lsd线段
6. 计算尺度第一塔的描述
7. 使用尺度第一塔进行特征与描述提取
8.lbd描述子匹配
9.选择高精度匹配
10.画图显示
完整代码如下:
#include <iostream>
#include <opencv2/opencv_modules.hpp>
#include <opencv2/line_descriptor.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace cv::line_descriptor;
using namespace std;
#define matches_dist_threshold 25
//主函数
int main(int argc, char** argv)
{
//1.设置读图的路径
string image_path1 = "your path1";
string image_path2 = "your path2";
if (image_path1.empty() || image_path2.empty())
{
return -1;
}
//2. 加载图片
cv::mat imagemat1 = imread(image_path1, 1);
cv::mat imagemat2 = imread(image_path2, 1);
// 检测路径是否为空
if (imagemat1.data == null || imagemat2.data == null)
{
std::cout << "error, images could not be loaded. please, check their path" << std::endl;
}
//3. 创建mask掩代码
cv::mat mask1 = mat::ones(imagemat1.size(), cv_8uc1);
cv::mat mask2 = mat::ones(imagemat2.size(), cv_8uc1);
// 4.初始化参数
ptr<lsddetector> lsd = lsddetector::createlsddetector();
ptr<binarydescriptor> lbd = binarydescriptor::createbinarydescriptor();// binarydescriptor指针默认参数
ptr<binarydescriptormatcher> match1 = binarydescriptormatcher::createbinarydescriptormatcher(); //binarydescriptormatcher二值描述子匹配创建
//5.检测线段
std::vector<keyline> klsd1, klsd2;
mat lsd_descr1, lsd_descr2;
lsd->detect(imagemat1, klsd1, 2, 2, mask1);
lsd->detect(imagemat2, klsd2, 2, 2, mask2);
//6. 计算尺度第一塔的描述
lbd->compute(imagemat1, klsd1, lsd_descr1);
lbd->compute(imagemat2, klsd2, lsd_descr2);
//7. 尺度第一塔进行特征与描述提取
std::vector<keyline> octave0_1, octave0_2;
mat leftdescr, rightdescr;
for (int i = 0; i < (int)klsd1.size(); i++)
{
if (klsd1[i].octave == 1)
{
octave0_1.push_back(klsd1[i]);
leftdescr.push_back(lsd_descr1.row(i));
}
}
for (int j = 0; j < (int)klsd2.size(); j++)
{
if (klsd2[j].octave == 1)
{
octave0_2.push_back(klsd2[j]);
rightdescr.push_back(lsd_descr2.row(j));
}
}
//8.匹配
std::vector<dmatch> lsd_matches;
match1->match(leftdescr, rightdescr, lsd_matches);
//9.选择高精度匹配
std::vector<dmatch> good_matches;
for (int i = 0; i < (int)lsd_matches.size(); i++)
{
if (lsd_matches[i].distance < matches_dist_threshold)
good_matches.push_back(lsd_matches[i]);
}
// 10.画图显示
cv::mat lsd_outimg;
resize(imagemat1, imagemat1, size(imagemat1.cols/2, imagemat1.rows/2));
resize(imagemat2, imagemat2, size(imagemat2.cols/2, imagemat2.rows/2));
std::vector<char> lsd_mask(lsd_matches.size(), 1);
drawlinematches(imagemat1, octave0_1, imagemat2, octave0_2, good_matches, lsd_outimg,
scalar::all(-1), scalar::all(-1), lsd_mask, drawlinesmatchesflags::default);
imshow("lsd matches", lsd_outimg);
std::cout << "lsdescriptormatcher is : " << good_matches.size() << std::endl;
waitkey(0);
return 0;
}
发表评论