使用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;
}