LSD 线特征提取⽅法+Opencv 实现C++
边缘检测: 传统的直线检测⽅法⼀般采⽤边缘检测算法提取⼆值边缘图像,然后利⽤Hough变换将表⽰每条直线属性的参数投影到Hough 空间中。该线检测⽅法是⼀种全局拟合算法。缺点是依赖于边缘检测算法的准确性,在边缘密集的地⽅容易出现异常检测 LSD检测 LSD算法是⼀种基于梯度信息的直线检测⽅法,具有检测速度快、参数⾃适应、精度可达到亚像素级的特点。其主要思想是将局部区域内具有相同梯度⽅向的像素进⾏合并,以达到直线检测的⽬的#include <iostream>#include <chrono>#include <cv.h>#include <opencv2/core/core.hpp>#include <opencv2/core/utility.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/imgcodecs.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/line_descriptor/descriptor.hpp>#include <opencv2/features2d/features2d.hpp>#include <iostream>using namespace cv ;using namespace std ;using namespace cv ::line_descriptor ;struct sort_descriptor_by_queryIdx { inline bool operator ()(const vector <DMatch >& a , const vector <DMatch >& b ){ return ( a [0].queryIdx < b [0].queryIdx ); }};struct sort_lines_by_response { inline bool operator ()(const KeyLine & a , const KeyLine & b ){ return ( a .response > b .response ); }};void ExtractLineSegment (const Mat &img , const Mat &image2, vector <KeyLine > &keylines ,vector <KeyLine > &keylines2);int main (int argc , char **argv ){ if (argc != 3) { cerr << endl << "Usage: ./Line path_to_image1 pat h_to_image2" << endl ; return 1; } string imagePath1=string (argv [1]); string imagePath2=string (argv [2]); cout <<"import two images"<<endl ; Mat image1=imread (imagePath1); Mat image2=imread (imagePath2); imshow ("ima1",image1); imshow ("ima2",image2); waitKey (0); if (image1.data ==NULL ) { cout <<"the path is wrong"<<endl ; } vector <KeyLine > keylines ,keylines2; ExtractLineSegment (image1,image2,keylines ,keylines2); return 0;}
1
木结构设计规范2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
李兆宗21
22
23
24
25
26
27
28
29
大瀑布的葬礼教学设计30
31
32
33
34
35
36
37
38
wald39
40
41
42
43
44
45
46
47
48
49
50
51
电信网技术
52
53
54
55
56
57
针对⾃⼰的⽂件 的执⾏命令:./bin/HC++ /home/jyy/图⽚/test1.png /home/jyy/图⽚/test1.png }void ExtractLineSegment (const Mat &img , const Mat &image2, vector <KeyLine > &keylines ,vector <KeyLine > &keylines2){ Mat mLdesc ,mLdesc2; vector <vector <DMatch >> lmatches ; Ptr <BinaryDescriptor > lbd = BinaryDescriptor ::createBinaryDescriptor (); Ptr <line_descriptor ::LSDDetector > lsd = line_descriptor ::LSDDetector ::createLSDDetector (); cout <<"extract lsd line segments"<<endl ; lsd ->detect (img , keylines , 1.2,1); lsd ->detect (image2,keylines2,1.2,1); int lsdNFeatures = 50; cout <<"filter lines"<<endl ; if (keylines .size ()>lsdNFeatures ) { sort (keylines .begin (), keylines .end (), sort_lines_by_response ()); k
eylines .resize (lsdNFeatures ); for ( int i =0; i <lsdNFeatures ; i ++) keylines [i ].class_id = i ; } if (keylines2.size ()>lsdNFeatures ) { sort (keylines2.begin (), d (), sort_lines_by_response ()); size (lsdNFeatures ); for (int i =0; i <lsdNFeatures ; i ++) keylines2[i ].class_id = i ; } cout <<"lbd describle"<<endl ; lbd ->compute (img , keylines , mLdesc ); lbd ->compute (image2,keylines2,mLdesc2);//计算特征线段的描述⼦ BFMatcher * bfm = new BFMatcher (NORM_HAMMING , false ); bfm ->knnMatch (mLdesc , mLdesc2, lmatches , 2); vector <DMatch > matches ; for (size_t i =0;i <lmatches .size ();i ++) { const DMatch & bestMatch = lmatches [i ][0]; const DMatch & betterMatch = lmatches [i ][1]; float distanceRatio = bestMatch .distance / betterMatch .distance ; if (distanceRatio < 0.75) matches .push_back (bestMatch ); } cv ::Mat outImg ; std ::vector <char > mask ( lmatches .size (), 1 ); drawLineMatches ( img , keylines , image2, keylines2, matches , outImg , Scalar ::all ( -1 ), Scalar ::all ( -1 ), mask , DrawLinesMatchesFlags ::DEFAULT ); imshow ( "Matches", outImg ); waitKey ();}
四川商情网57585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
PROJECT (HC ++)cmake_minimum_required (VERSION 3.5)set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${HC ++_SOURCE_DIR }/bin ) #可执⾏⽂件的输出位
置# find required opencv find_package (OpenCV REQUIRED )# directory of opencv headers link_directories (${OpenCV_LIBRARY_DIRS }) # opencv libr include_directories (${OpenCV_INCLUDE_DIRS })add_executable (${PROJECT_NAME } "./baselineExperiment.cpp" ) # directory of opencv libraryaries target_link_libraries (HC ++ ${OpenCV_LIBS } -lpthread -lm ) 123456789101112131415