| OpenCV 3.4.7 Open Source Computer Vision

Line Features Tutorial

In this tutorial it will be shown how to:

- use the BinaryDescriptor interface to extract lines and store them in KeyLine objects
- use the same interface to compute descriptors for every extracted line
- use the BynaryDescriptorMatcher to determine matches among descriptors obtained from different images

## Lines extraction and descriptors computation

In the following snippet of code, it is shown how to detect lines from an image. The LSD extractor is initialized with LSD_REFINE_ADV option; remaining parameters are left to their default values. A mask of ones is used in order to accept all extracted lines, which, at the end, are displayed using random colors for octave 0.

1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2014, Biagio Montesano, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include <iostream>
43 #include <opencv2/opencv_modules.hpp>
44
45 #ifdef HAVE_OPENCV_FEATURES2D
46
47 #include <opencv2/line_descriptor.hpp>
48 #include <opencv2/core/utility.hpp>
49 #include <opencv2/imgproc.hpp>
50 #include <opencv2/features2d.hpp>
51 #include <opencv2/highgui.hpp>
52
53 using namespace cv;
54 using namespace cv::line_descriptor;
55 using namespace std;
56
57 static const char* keys =
58 { "{@image_path | | Image path }" };
59
60 static void help()
61 {
62 cout << "\nThis example shows the functionalities of lines extraction " << "furnished by BinaryDescriptor class\n"
63 << "Please, run this sample using a command in the form\n" << "./example_line_descriptor_lines_extraction <path_to_input_image>" << endl;
64 }
65
66 int main( int argc, char** argv )
67 {
68 /* get parameters from comand line */
69 CommandLineParser parser( argc, argv, keys );
70 String image_path = parser.get<String>( 0 );
71
72 if( image_path.empty() )
73 {
74 help();
75 return -1;
76 }
77
78 /* load image */
79 cv::Mat imageMat = imread( image_path, 1 );
80 if( imageMat.data == NULL )
81 {
82 std::cout << "Error, image could not be loaded. Please, check its path" << std::endl;
83 return -1;
84 }
85
86 /* create a random binary mask */
87 cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
88
89 /* create a pointer to a BinaryDescriptor object with deafult parameters */
90 Ptr<LSDDetector> bd = LSDDetector::createLSDDetector();
91
92 /* create a structure to store extracted lines */
93 vector<KeyLine> lines;
94
95 /* extract lines */
96 cv::Mat output = imageMat.clone();
97 bd->detect( imageMat, lines, 2, 1, mask );
98
99 /* draw lines extracted from octave 0 */
100 if( output.channels() == 1 )
101 cvtColor( output, output, COLOR_GRAY2BGR );
102 for ( size_t i = 0; i < lines.size(); i++ )
103 {
104 KeyLine kl = lines[i];
105 if( kl.octave == 0)
106 {
107 /* get a random color */
108 int R = ( rand() % (int) ( 255 + 1 ) );
109 int G = ( rand() % (int) ( 255 + 1 ) );
110 int B = ( rand() % (int) ( 255 + 1 ) );
111
112 /* get extremes of line */
113 Point pt1 = Point2f( kl.startPointX, kl.startPointY );
114 Point pt2 = Point2f( kl.endPointX, kl.endPointY );
115
116 /* draw line */
117 line( output, pt1, pt2, Scalar( B, G, R ), 3 );
118 }
119
120 }
121
122 /* show lines on image */
123 imshow( "LSD lines", output );
124 waitKey();
125 }
126
127 #else
128
129 int main()
130 {
131 std::cerr << "OpenCV was built without features2d module" << std::endl;
132 return 0;
133 }
134
135 #endif // HAVE_OPENCV_FEATURES2D
cv::line_descriptor::KeyLine::startPointX
float startPointX
Definition: descriptor.hpp:126
cv::Scalar
Scalar_< double > Scalar
Definition: types.hpp:657
cv::line_descriptor::LSDDetector::createLSDDetector
static Ptr< LSDDetector > createLSDDetector()
Creates ad LSDDetector object, using smart pointers.
cv::imread
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
cv::Mat::ones
static MatExpr ones(int rows, int cols, int type)
Returns an array of all 1&#39;s of the specified size and type.
features2d.hpp
cv::COLOR_GRAY2BGR
Definition: imgproc.hpp:544
cv::Mat::data
uchar * data
pointer to the data
Definition: mat.hpp:2116
std
STL namespace.
cv::String::empty
bool empty() const
highgui.hpp
line_descriptor.hpp
cv::imshow
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
cv::line_descriptor::KeyLine::startPointY
float startPointY
Definition: descriptor.hpp:127
cv
Definition: affine.hpp:51
cv::CommandLineParser
Designed for command line parsing.
Definition: utility.hpp:862
cv::cvtColor
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
Converts an image from one color space to another.
cv::Point_< int >
cv::line_descriptor::KeyLine::octave
int octave
Definition: descriptor.hpp:112
cv::line_descriptor::KeyLine::endPointX
float endPointX
Definition: descriptor.hpp:128
cv::line
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)
Draws a line segment connecting two points.
cv::Point2f
Point_< float > Point2f
Definition: types.hpp:190
imgproc.hpp
cv::Mat::size
MatSize size
Definition: mat.hpp:2136
utility.hpp
cv::line_descriptor
Definition: descriptor.hpp:74
cv::Ptr
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:261
cv::line_descriptor::KeyLine
A class to represent a line.
Definition: descriptor.hpp:102
cvflann::rand
int rand()
Definition: random.h:43
cv::Mat::clone
Mat clone() const CV_NODISCARD
Creates a full copy of the array and the underlying data.
CV_8UC1
#define CV_8UC1
Definition: interface.h:86
cv::String
Definition: cvstd.hpp:458
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:804
cv::Mat::channels
int channels() const
Returns the number of matrix channels.
cv::line_descriptor::KeyLine::endPointY
float endPointY
Definition: descriptor.hpp:129
cv::waitKey
int waitKey(int delay=0)
Waits for a pressed key.

This is the result obtained for famous cameraman image:

alternate text

Another way to extract lines is using LSDDetector class; such class uses the LSD extractor to compute lines. To obtain this result, it is sufficient to use the snippet code seen above, just modifying it by the rows

// create a pointer to an LSDDetector object
Ptr<LSDDetector> lsd = LSDDetector::createLSDDetector();
// compute lines
std::vector<KeyLine> keylines;
lsd->detect( imageMat, keylines, mask );

Here's the result returned by LSD detector again on cameraman picture:

alternate text

Once keylines have been detected, it is possible to compute their descriptors as shown in the following:

1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2014, Biagio Montesano, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include <iostream>
43 #include <opencv2/opencv_modules.hpp>
44
45 #ifdef HAVE_OPENCV_FEATURES2D
46
47 #include <opencv2/line_descriptor.hpp>
48 #include <opencv2/core/utility.hpp>
49 #include <opencv2/imgproc.hpp>
50 #include <opencv2/features2d.hpp>
51 #include <opencv2/highgui.hpp>
52
53 using namespace cv;
54 using namespace cv::line_descriptor;
55
56
57 static const char* keys =
58 { "{@image_path | | Image path }" };
59
60 static void help()
61 {
62 std::cout << "\nThis example shows the functionalities of lines extraction " << "and descriptors computation furnished by BinaryDescriptor class\n"
63 << "Please, run this sample using a command in the form\n" << "./example_line_descriptor_compute_descriptors <path_to_input_image>"
64 << std::endl;
65 }
66
67 int main( int argc, char** argv )
68 {
69 /* get parameters from command line */
70 CommandLineParser parser( argc, argv, keys );
71 String image_path = parser.get<String>( 0 );
72
73 if( image_path.empty() )
74 {
75 help();
76 return -1;
77 }
78
79 /* load image */
80 cv::Mat imageMat = imread( image_path, 1 );
81 if( imageMat.data == NULL )
82 {
83 std::cout << "Error, image could not be loaded. Please, check its path" << std::endl;
84 }
85
86 /* create a binary mask */
87 cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
88
89 /* create a pointer to a BinaryDescriptor object with default parameters */
90 Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
91
92 /* compute lines */
93 std::vector<KeyLine> keylines;
94 bd->detect( imageMat, keylines, mask );
95
96 /* compute descriptors */
97 cv::Mat descriptors;
98
99 bd->compute( imageMat, keylines, descriptors);
100
101 }
102
103 #else
104
105 int main()
106 {
107 std::cerr << "OpenCV was built without features2d module" << std::endl;
108 return 0;
109 }
110
111 #endif // HAVE_OPENCV_FEATURES2D
cv::line_descriptor::BinaryDescriptor::createBinaryDescriptor
static Ptr< BinaryDescriptor > createBinaryDescriptor()
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a sma...
cv::imread
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
cv::Mat::ones
static MatExpr ones(int rows, int cols, int type)
Returns an array of all 1&#39;s of the specified size and type.
features2d.hpp
cv::Mat::data
uchar * data
pointer to the data
Definition: mat.hpp:2116
cv::String::empty
bool empty() const
highgui.hpp
line_descriptor.hpp
cv
Definition: affine.hpp:51
cv::CommandLineParser
Designed for command line parsing.
Definition: utility.hpp:862
imgproc.hpp
cv::Mat::size
MatSize size
Definition: mat.hpp:2136
utility.hpp
cv::line_descriptor
Definition: descriptor.hpp:74
cv::Ptr
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:261
CV_8UC1
#define CV_8UC1
Definition: interface.h:86
cv::String
Definition: cvstd.hpp:458
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:804

## Matching among descriptors

If we have extracted descriptors from two different images, it is possible to search for matches among them. One way of doing it is matching exactly a descriptor to each input query descriptor, choosing the one at closest distance:

1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2014, Biagio Montesano, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include <iostream>
43 #include <opencv2/opencv_modules.hpp>
44
45 #ifdef HAVE_OPENCV_FEATURES2D
46
47 #include <opencv2/line_descriptor.hpp>
48 #include <opencv2/core/utility.hpp>
49 #include <opencv2/imgproc.hpp>
50 #include <opencv2/features2d.hpp>
51 #include <opencv2/highgui.hpp>
52
53 #define MATCHES_DIST_THRESHOLD 25
54
55 using namespace cv;
56 using namespace cv::line_descriptor;
57
58 static const char* keys =
59 { "{@image_path1 | | Image path 1 }"
60 "{@image_path2 | | Image path 2 }" };
61
62 static void help()
63 {
64 std::cout << "\nThis example shows the functionalities of lines extraction " << "and descriptors computation furnished by BinaryDescriptor class\n"
65 << "Please, run this sample using a command in the form\n" << "./example_line_descriptor_compute_descriptors <path_to_input_image 1>"
66 << "<path_to_input_image 2>" << std::endl;
67
68 }
69
70 int main( int argc, char** argv )
71 {
72 /* get parameters from command line */
73 CommandLineParser parser( argc, argv, keys );
74 String image_path1 = parser.get<String>( 0 );
75 String image_path2 = parser.get<String>( 1 );
76
77 if( image_path1.empty() || image_path2.empty() )
78 {
79 help();
80 return -1;
81 }
82
83 /* load image */
84 cv::Mat imageMat1 = imread( image_path1, 1 );
85 cv::Mat imageMat2 = imread( image_path2, 1 );
86
87 if( imageMat1.data == NULL || imageMat2.data == NULL )
88 {
89 std::cout << "Error, images could not be loaded. Please, check their path" << std::endl;
90 }
91
92 /* create binary masks */
93 cv::Mat mask1 = Mat::ones( imageMat1.size(), CV_8UC1 );
94 cv::Mat mask2 = Mat::ones( imageMat2.size(), CV_8UC1 );
95
96 /* create a pointer to a BinaryDescriptor object with default parameters */
97 Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor( );
98
99 /* compute lines and descriptors */
100 std::vector<KeyLine> keylines1, keylines2;
101 cv::Mat descr1, descr2;
102
103 ( *bd )( imageMat1, mask1, keylines1, descr1, false, false );
104 ( *bd )( imageMat2, mask2, keylines2, descr2, false, false );
105
106 /* select keylines from first octave and their descriptors */
107 std::vector<KeyLine> lbd_octave1, lbd_octave2;
108 Mat left_lbd, right_lbd;
109 for ( int i = 0; i < (int) keylines1.size(); i++ )
110 {
111 if( keylines1[i].octave == 0 )
112 {
113 lbd_octave1.push_back( keylines1[i] );
114 left_lbd.push_back( descr1.row( i ) );
115 }
116 }
117
118 for ( int j = 0; j < (int) keylines2.size(); j++ )
119 {
120 if( keylines2[j].octave == 0 )
121 {
122 lbd_octave2.push_back( keylines2[j] );
123 right_lbd.push_back( descr2.row( j ) );
124 }
125 }
126
127 /* create a BinaryDescriptorMatcher object */
128 Ptr<BinaryDescriptorMatcher> bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
129
130 /* require match */
131 std::vector<DMatch> matches;
132 bdm->match( left_lbd, right_lbd, matches );
133
134 /* select best matches */
135 std::vector<DMatch> good_matches;
136 for ( int i = 0; i < (int) matches.size(); i++ )
137 {
138 if( matches[i].distance < MATCHES_DIST_THRESHOLD )
139 good_matches.push_back( matches[i] );
140 }
141
142 /* plot matches */
143 cv::Mat outImg;
144 cv::Mat scaled1, scaled2;
145 std::vector<char> mask( matches.size(), 1 );
146 drawLineMatches( imageMat1, lbd_octave1, imageMat2, lbd_octave2, good_matches, outImg, Scalar::all( -1 ), Scalar::all( -1 ), mask,
147 DrawLinesMatchesFlags::DEFAULT );
148
149 imshow( "Matches", outImg );
150 waitKey();
151 imwrite("/home/ubisum/Desktop/images/env_match/matches.jpg", outImg);
152 /* create an LSD detector */
153 Ptr<LSDDetector> lsd = LSDDetector::createLSDDetector();
154
155 /* detect lines */
156 std::vector<KeyLine> klsd1, klsd2;
157 Mat lsd_descr1, lsd_descr2;
158 lsd->detect( imageMat1, klsd1, 2, 2, mask1 );
159 lsd->detect( imageMat2, klsd2, 2, 2, mask2 );
160
161 /* compute descriptors for lines from first octave */
162 bd->compute( imageMat1, klsd1, lsd_descr1 );
163 bd->compute( imageMat2, klsd2, lsd_descr2 );
164
165 /* select lines and descriptors from first octave */
166 std::vector<KeyLine> octave0_1, octave0_2;
167 Mat leftDEscr, rightDescr;
168 for ( int i = 0; i < (int) klsd1.size(); i++ )
169 {
170 if( klsd1[i].octave == 1 )
171 {
172 octave0_1.push_back( klsd1[i] );
173 leftDEscr.push_back( lsd_descr1.row( i ) );
174 }
175 }
176
177 for ( int j = 0; j < (int) klsd2.size(); j++ )
178 {
179 if( klsd2[j].octave == 1 )
180 {
181 octave0_2.push_back( klsd2[j] );
182 rightDescr.push_back( lsd_descr2.row( j ) );
183 }
184 }
185
186 /* compute matches */
187 std::vector<DMatch> lsd_matches;
188 bdm->match( leftDEscr, rightDescr, lsd_matches );
189
190 /* select best matches */
191 good_matches.clear();
192 for ( int i = 0; i < (int) lsd_matches.size(); i++ )
193 {
194 if( lsd_matches[i].distance < MATCHES_DIST_THRESHOLD )
195 good_matches.push_back( lsd_matches[i] );
196 }
197
198 /* plot matches */
199 cv::Mat lsd_outImg;
200 resize( imageMat1, imageMat1, Size( imageMat1.cols / 2, imageMat1.rows / 2 ), 0, 0, INTER_LINEAR_EXACT );
201 resize( imageMat2, imageMat2, Size( imageMat2.cols / 2, imageMat2.rows / 2 ), 0, 0, INTER_LINEAR_EXACT );
202 std::vector<char> lsd_mask( matches.size(), 1 );
203 drawLineMatches( imageMat1, octave0_1, imageMat2, octave0_2, good_matches, lsd_outImg, Scalar::all( -1 ), Scalar::all( -1 ), lsd_mask,
204 DrawLinesMatchesFlags::DEFAULT );
205
206 imshow( "LSD matches", lsd_outImg );
207 waitKey();
208
209
210 }
211
212 #else
213
214 int main()
215 {
216 std::cerr << "OpenCV was built without features2d module" << std::endl;
217 return 0;
218 }
219
220 #endif // HAVE_OPENCV_FEATURES2D
cv::line_descriptor::LSDDetector::detect
void detect(const Mat &image, std::vector< KeyLine > &keypoints, int scale, int numOctaves, const Mat &mask=Mat())
Detect lines inside an image.
cv::imwrite
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
cv::line_descriptor::LSDDetector::createLSDDetector
static Ptr< LSDDetector > createLSDDetector()
Creates ad LSDDetector object, using smart pointers.
cv::line_descriptor::BinaryDescriptor::createBinaryDescriptor
static Ptr< BinaryDescriptor > createBinaryDescriptor()
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a sma...
cv::Mat::push_back
void push_back(const _Tp &elem)
Adds elements to the bottom of the matrix.
cv::imread
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
cv::Mat::ones
static MatExpr ones(int rows, int cols, int type)
Returns an array of all 1&#39;s of the specified size and type.
features2d.hpp
cv::Mat::data
uchar * data
pointer to the data
Definition: mat.hpp:2116
cv::String::empty
bool empty() const
highgui.hpp
line_descriptor.hpp
cv::imshow
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
cv
Definition: affine.hpp:51
cv::resize
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
Resizes an image.
cv::CommandLineParser
Designed for command line parsing.
Definition: utility.hpp:862
imgproc.hpp
cv::Mat::size
MatSize size
Definition: mat.hpp:2136
utility.hpp
cv::line_descriptor::drawLineMatches
void drawLineMatches(const Mat &img1, const std::vector< KeyLine > &keylines1, const Mat &img2, const std::vector< KeyLine > &keylines2, const std::vector< DMatch > &matches1to2, Mat &outImg, const Scalar &matchColor=Scalar::all(-1), const Scalar &singleLineColor=Scalar::all(-1), const std::vector< char > &matchesMask=std::vector< char >(), int flags=DrawLinesMatchesFlags::DEFAULT)
Draws the found matches of keylines from two images.
cv::line_descriptor
Definition: descriptor.hpp:74
cv::Ptr
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:261
cv::Size
Size2i Size
Definition: types.hpp:343
cv::Mat::row
Mat row(int y) const
Creates a matrix header for the specified matrix row.
cv::line_descriptor::BinaryDescriptorMatcher::match
void match(const Mat &queryDescriptors, const Mat &trainDescriptors, std::vector< DMatch > &matches, const Mat &mask=Mat()) const
For every input query descriptor, retrieve the best matching one from a dataset provided from user or...
cv::line_descriptor::DrawLinesMatchesFlags::DEFAULT
Definition: descriptor.hpp:1157
CV_8UC1
#define CV_8UC1
Definition: interface.h:86
cv::Scalar_< double >::all
static Scalar_< double > all(double v0)
returns a scalar with all elements set to v0
cv::String
Definition: cvstd.hpp:458
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:804
cv::line_descriptor::BinaryDescriptorMatcher::createBinaryDescriptorMatcher
static Ptr< BinaryDescriptorMatcher > createBinaryDescriptorMatcher()
Create a BinaryDescriptorMatcher object and return a smart pointer to it.
cv::waitKey
int waitKey(int delay=0)
Waits for a pressed key.
cv::INTER_LINEAR_EXACT
Definition: imgproc.hpp:254

Sometimes, we could be interested in searching for the closest k descriptors, given an input one. This requires to modify slightly previous code:

// prepare a structure to host matches
std::vector<std::vector<DMatch> > matches;
// require knn match
bdm->knnMatch( descr1, descr2, matches, 6 );

In the above example, the closest 6 descriptors are returned for every query. In some cases, we could have a search radius and look for all descriptors distant at the most r from input query. Previous code must me modified:

// prepare a structure to host matches
std::vector<std::vector<DMatch> > matches;
// compute matches
bdm->radiusMatch( queries, matches, 30 );

Here's an example om matching among descriptors extratced from original cameraman image and its downsampled (and blurred) version:

alternate text

## Querying internal database

The BynaryDescriptorMatcher class, owns an internal database that can be populated with descriptors extracted from different images and queried using one of the modalities described in previous section. Population of internal dataset can be done using the add function; such function doesn't directly add new data to database, but it just stores it them locally. The real update happens when function train is invoked or when any querying function is executed, since each of them invokes train before querying. When queried, internal database not only returns required descriptors, but, for every returned match, it is able to tell which image matched descriptor was extracted from. An example of internal dataset usage is described in the following code; after adding locally new descriptors, a radius search is invoked. This provokes local data to be transferred to dataset, which, in turn, is then queried.

1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2014, Biagio Montesano, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include <iostream>
43 #include <opencv2/opencv_modules.hpp>
44
45 #ifdef HAVE_OPENCV_FEATURES2D
46
47 #include <opencv2/line_descriptor.hpp>
48 #include <opencv2/core/utility.hpp>
49 #include <opencv2/imgproc.hpp>
50 #include <opencv2/features2d.hpp>
51 #include <opencv2/highgui.hpp>
52
53 #include <vector>
54
55 using namespace cv;
56 using namespace cv::line_descriptor;
57
58 static const std::string images[] =
59 { "cameraman.jpg", "church.jpg", "church2.png", "einstein.jpg", "stuff.jpg" };
60
61 static const char* keys =
62 { "{@image_path | | Image path }" };
63
64 static void help()
65 {
66 std::cout << "\nThis example shows the functionalities of radius matching " << "Please, run this sample using a command in the form\n"
67 << "./example_line_descriptor_radius_matching <path_to_input_images>/" << std::endl;
68 }
69
70 int main( int argc, char** argv )
71 {
72 /* get parameters from comand line */
73 CommandLineParser parser( argc, argv, keys );
74 String pathToImages = parser.get < String > ( 0 );
75
76 /* create structures for hosting KeyLines and descriptors */
77 int num_elements = sizeof ( images ) / sizeof ( images[0] );
78 std::vector < Mat > descriptorsMat;
79 std::vector < std::vector<KeyLine> > linesMat;
80
81 /*create a pointer to a BinaryDescriptor object */
82 Ptr < BinaryDescriptor > bd = BinaryDescriptor::createBinaryDescriptor();
83
84 /* compute lines and descriptors */
85 for ( int i = 0; i < num_elements; i++ )
86 {
87 /* get path to image */
88 std::stringstream image_path;
89 image_path << pathToImages << images[i];
90 std::cout << image_path.str().c_str() << std::endl;
91
92 /* load image */
93 Mat loadedImage = imread( image_path.str().c_str(), 1 );
94 if( loadedImage.data == NULL )
95 {
96 std::cout << "Could not load images." << std::endl;
97 help();
98 exit( -1 );
99 }
100
101 /* compute lines and descriptors */
102 std::vector < KeyLine > lines;
103 Mat computedDescr;
104 bd->detect( loadedImage, lines );
105 bd->compute( loadedImage, lines, computedDescr );
106
107 descriptorsMat.push_back( computedDescr );
108 linesMat.push_back( lines );
109
110 }
111
112 /* compose a queries matrix */
113 Mat queries;
114 for ( size_t j = 0; j < descriptorsMat.size(); j++ )
115 {
116 if( descriptorsMat[j].rows >= 5 )
117 queries.push_back( descriptorsMat[j].rowRange( 0, 5 ) );
118
119 else if( descriptorsMat[j].rows > 0 && descriptorsMat[j].rows < 5 )
120 queries.push_back( descriptorsMat[j] );
121 }
122
123 std::cout << "It has been generated a matrix of " << queries.rows << " descriptors" << std::endl;
124
125 /* create a BinaryDescriptorMatcher object */
126 Ptr < BinaryDescriptorMatcher > bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
127
128 /* populate matcher */
129 bdm->add( descriptorsMat );
130
131 /* compute matches */
132 std::vector < std::vector<DMatch> > matches;
133 bdm->radiusMatch( queries, matches, 30 );
134 std::cout << "size matches sample " << matches.size() << std::endl;
135
136 for ( int i = 0; i < (int) matches.size(); i++ )
137 {
138 for ( int j = 0; j < (int) matches[i].size(); j++ )
139 {
140 std::cout << "match: " << matches[i][j].queryIdx << " " << matches[i][j].trainIdx << " " << matches[i][j].distance << std::endl;
141 }
142
143 }
144
145 }
146
147 #else
148
149 int main()
150 {
151 std::cerr << "OpenCV was built without features2d module" << std::endl;
152 return 0;
153 }
154
155 #endif // HAVE_OPENCV_FEATURES2D
cv::line_descriptor::BinaryDescriptor::createBinaryDescriptor
static Ptr< BinaryDescriptor > createBinaryDescriptor()
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a sma...
cv::Mat::rows
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions ...
Definition: mat.hpp:2114
cv::line_descriptor::BinaryDescriptor::compute
void compute(const Mat &image, std::vector< KeyLine > &keylines, Mat &descriptors, bool returnFloatDescr=false) const
Requires descriptors computation.
cv::Mat::push_back
void push_back(const _Tp &elem)
Adds elements to the bottom of the matrix.
cv::imread
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
features2d.hpp
cv::Mat::data
uchar * data
pointer to the data
Definition: mat.hpp:2116
highgui.hpp
line_descriptor.hpp
cv
Definition: affine.hpp:51
cv::CommandLineParser
Designed for command line parsing.
Definition: utility.hpp:862
cv::line_descriptor::BinaryDescriptorMatcher::add
void add(const std::vector< Mat > &descriptors)
Store locally new descriptors to be inserted in dataset, without updating dataset.
cv::String::c_str
const char * c_str() const
imgproc.hpp
utility.hpp
cv::line_descriptor::BinaryDescriptorMatcher::radiusMatch
void radiusMatch(const Mat &queryDescriptors, const Mat &trainDescriptors, std::vector< std::vector< DMatch > > &matches, float maxDistance, const Mat &mask=Mat(), bool compactResult=false) const
For every input query descriptor, retrieve, from a dataset provided from user or from the one interna...
cv::line_descriptor
Definition: descriptor.hpp:74
cv::Ptr
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:261
cv::line_descriptor::BinaryDescriptor::detect
void detect(const Mat &image, std::vector< KeyLine > &keypoints, const Mat &mask=Mat())
Requires line detection.
cv::String
Definition: cvstd.hpp:458
cv::Mat
n-dimensional dense array class
Definition: mat.hpp:804
cv::line_descriptor::BinaryDescriptorMatcher::createBinaryDescriptorMatcher
static Ptr< BinaryDescriptorMatcher > createBinaryDescriptorMatcher()
Create a BinaryDescriptorMatcher object and return a smart pointer to it.