OpenCV  3.1.0-dev
Open Source Computer Vision
Line Features Tutorial

In this tutorial it will be shown how to:

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 
43 
44 #include "opencv2/core/utility.hpp"
45 #include <opencv2/imgproc.hpp>
46 #include <opencv2/features2d.hpp>
47 #include <opencv2/highgui.hpp>
48 
49 #include <iostream>
50 
51 using namespace cv;
52 using namespace cv::line_descriptor;
53 using namespace std;
54 
55 static const char* keys =
56 { "{@image_path | | Image path }" };
57 
58 static void help()
59 {
60  cout << "\nThis example shows the functionalities of lines extraction " << "furnished by BinaryDescriptor class\n"
61  << "Please, run this sample using a command in the form\n" << "./example_line_descriptor_lines_extraction <path_to_input_image>" << endl;
62 }
63 
64 int main( int argc, char** argv )
65 {
66  /* get parameters from comand line */
67  CommandLineParser parser( argc, argv, keys );
68  String image_path = parser.get<String>( 0 );
69 
70  if( image_path.empty() )
71  {
72  help();
73  return -1;
74  }
75 
76  /* load image */
77  cv::Mat imageMat = imread( image_path, 1 );
78  if( imageMat.data == NULL )
79  {
80  std::cout << "Error, image could not be loaded. Please, check its path" << std::endl;
81  return -1;
82  }
83 
84  /* create a random binary mask */
85  cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
86 
87  /* create a pointer to a BinaryDescriptor object with deafult parameters */
89 
90  /* create a structure to store extracted lines */
91  vector<KeyLine> lines;
92 
93  /* extract lines */
94  cv::Mat output = imageMat.clone();
95  bd->detect( imageMat, lines, 2, 1, mask );
96 
97  /* draw lines extracted from octave 0 */
98  if( output.channels() == 1 )
99  cvtColor( output, output, COLOR_GRAY2BGR );
100  for ( size_t i = 0; i < lines.size(); i++ )
101  {
102  KeyLine kl = lines[i];
103  if( kl.octave == 0)
104  {
105  /* get a random color */
106  int R = ( rand() % (int) ( 255 + 1 ) );
107  int G = ( rand() % (int) ( 255 + 1 ) );
108  int B = ( rand() % (int) ( 255 + 1 ) );
109 
110  /* get extremes of line */
111  Point pt1 = Point2f( kl.startPointX, kl.startPointY );
112  Point pt2 = Point2f( kl.endPointX, kl.endPointY );
113 
114  /* draw line */
115  line( output, pt1, pt2, Scalar( B, G, R ), 3 );
116  }
117 
118  }
119 
120  /* show lines on image */
121  imshow( "LSD lines", output );
122  waitKey();
123 }
float startPointX
Definition: descriptor.hpp:129
Scalar_< double > Scalar
Definition: types.hpp:602
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
Converts an image from one color space to another.
static Ptr< LSDDetector > createLSDDetector()
Creates ad LSDDetector object, using smart pointers.
int channels() const
Returns the number of matrix channels.
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
static MatExpr ones(int rows, int cols, int type)
Returns an array of all 1&#39;s of the specified size and type.
uchar * data
pointer to the data
Definition: mat.hpp:1909
STL namespace.
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
float startPointY
Definition: descriptor.hpp:130
Definition: affine.hpp:51
Designed for command line parsing.
Definition: utility.hpp:734
Definition: imgproc.hpp:540
Template class for 2D points specified by its coordinates x and y.
Definition: types.hpp:148
int octave
Definition: descriptor.hpp:115
float endPointX
Definition: descriptor.hpp:131
bool empty() const
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.
Mat clone() const
Creates a full copy of the array and the underlying data.
Point_< float > Point2f
Definition: types.hpp:180
MatSize size
Definition: mat.hpp:1926
Definition: descriptor.hpp:77
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:280
for i
Definition: modelConvert.m:63
A class to represent a line.
Definition: descriptor.hpp:105
#define CV_8UC1
Definition: interface.h:82
Definition: cvstd.hpp:477
n-dimensional dense array class
Definition: mat.hpp:740
float endPointY
Definition: descriptor.hpp:132
int waitKey(int delay=0)
Waits for a pressed key.

This is the result obtained for famous cameraman image:

lines_cameraman_edl.png
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:

cameraman_lines2.png
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 
43 
44 #include "opencv2/core/utility.hpp"
45 #include <opencv2/imgproc.hpp>
46 #include <opencv2/features2d.hpp>
47 #include <opencv2/highgui.hpp>
48 
49 #include <iostream>
50 
51 using namespace cv;
52 using namespace cv::line_descriptor;
53 
54 
55 static const char* keys =
56 { "{@image_path | | Image path }" };
57 
58 static void help()
59 {
60  std::cout << "\nThis example shows the functionalities of lines extraction " << "and descriptors computation furnished by BinaryDescriptor class\n"
61  << "Please, run this sample using a command in the form\n" << "./example_line_descriptor_compute_descriptors <path_to_input_image>"
62  << std::endl;
63 }
64 
65 int main( int argc, char** argv )
66 {
67  /* get parameters from command line */
68  CommandLineParser parser( argc, argv, keys );
69  String image_path = parser.get<String>( 0 );
70 
71  if( image_path.empty() )
72  {
73  help();
74  return -1;
75  }
76 
77  /* load image */
78  cv::Mat imageMat = imread( image_path, 1 );
79  if( imageMat.data == NULL )
80  {
81  std::cout << "Error, image could not be loaded. Please, check its path" << std::endl;
82  }
83 
84  /* create a binary mask */
85  cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
86 
87  /* create a pointer to a BinaryDescriptor object with default parameters */
89 
90  /* compute lines */
91  std::vector<KeyLine> keylines;
92  bd->detect( imageMat, keylines, mask );
93 
94  /* compute descriptors */
95  cv::Mat descriptors;
96 
97  bd->compute( imageMat, keylines, descriptors);
98 
99 }
100 
101 
static Ptr< BinaryDescriptor > createBinaryDescriptor()
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a sma...
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
static MatExpr ones(int rows, int cols, int type)
Returns an array of all 1&#39;s of the specified size and type.
uchar * data
pointer to the data
Definition: mat.hpp:1909
Definition: affine.hpp:51
Designed for command line parsing.
Definition: utility.hpp:734
bool empty() const
MatSize size
Definition: mat.hpp:1926
Definition: descriptor.hpp:77
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:280
#define CV_8UC1
Definition: interface.h:82
Definition: cvstd.hpp:477
n-dimensional dense array class
Definition: mat.hpp:740

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 
43 
44 #include "opencv2/core/utility.hpp"
45 #include <opencv2/imgproc.hpp>
46 #include <opencv2/features2d.hpp>
47 #include <opencv2/highgui.hpp>
48 
49 #include <iostream>
50 
51 #define MATCHES_DIST_THRESHOLD 25
52 
53 using namespace cv;
54 using namespace cv::line_descriptor;
55 
56 static const char* keys =
57 { "{@image_path1 | | Image path 1 }"
58  "{@image_path2 | | Image path 2 }" };
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 1>"
64  << "<path_to_input_image 2>" << std::endl;
65 
66 }
67 
68 int main( int argc, char** argv )
69 {
70  /* get parameters from command line */
71  CommandLineParser parser( argc, argv, keys );
72  String image_path1 = parser.get<String>( 0 );
73  String image_path2 = parser.get<String>( 1 );
74 
75  if( image_path1.empty() || image_path2.empty() )
76  {
77  help();
78  return -1;
79  }
80 
81  /* load image */
82  cv::Mat imageMat1 = imread( image_path1, 1 );
83  cv::Mat imageMat2 = imread( image_path2, 1 );
84 
85  if( imageMat1.data == NULL || imageMat2.data == NULL )
86  {
87  std::cout << "Error, images could not be loaded. Please, check their path" << std::endl;
88  }
89 
90  /* create binary masks */
91  cv::Mat mask1 = Mat::ones( imageMat1.size(), CV_8UC1 );
92  cv::Mat mask2 = Mat::ones( imageMat2.size(), CV_8UC1 );
93 
94  /* create a pointer to a BinaryDescriptor object with default parameters */
96 
97  /* compute lines and descriptors */
98  std::vector<KeyLine> keylines1, keylines2;
99  cv::Mat descr1, descr2;
100 
101  ( *bd )( imageMat1, mask1, keylines1, descr1, false, false );
102  ( *bd )( imageMat2, mask2, keylines2, descr2, false, false );
103 
104  /* select keylines from first octave and their descriptors */
105  std::vector<KeyLine> lbd_octave1, lbd_octave2;
106  Mat left_lbd, right_lbd;
107  for ( int i = 0; i < (int) keylines1.size(); i++ )
108  {
109  if( keylines1[i].octave == 0 )
110  {
111  lbd_octave1.push_back( keylines1[i] );
112  left_lbd.push_back( descr1.row( i ) );
113  }
114  }
115 
116  for ( int j = 0; j < (int) keylines2.size(); j++ )
117  {
118  if( keylines2[j].octave == 0 )
119  {
120  lbd_octave2.push_back( keylines2[j] );
121  right_lbd.push_back( descr2.row( j ) );
122  }
123  }
124 
125  /* create a BinaryDescriptorMatcher object */
127 
128  /* require match */
129  std::vector<DMatch> matches;
130  bdm->match( left_lbd, right_lbd, matches );
131 
132  /* select best matches */
133  std::vector<DMatch> good_matches;
134  for ( int i = 0; i < (int) matches.size(); i++ )
135  {
136  if( matches[i].distance < MATCHES_DIST_THRESHOLD )
137  good_matches.push_back( matches[i] );
138  }
139 
140  /* plot matches */
141  cv::Mat outImg;
142  cv::Mat scaled1, scaled2;
143  std::vector<char> mask( matches.size(), 1 );
144  drawLineMatches( imageMat1, lbd_octave1, imageMat2, lbd_octave2, good_matches, outImg, Scalar::all( -1 ), Scalar::all( -1 ), mask,
146 
147  imshow( "Matches", outImg );
148  waitKey();
149  imwrite("/home/ubisum/Desktop/images/env_match/matches.jpg", outImg);
150  /* create an LSD detector */
152 
153  /* detect lines */
154  std::vector<KeyLine> klsd1, klsd2;
155  Mat lsd_descr1, lsd_descr2;
156  lsd->detect( imageMat1, klsd1, 2, 2, mask1 );
157  lsd->detect( imageMat2, klsd2, 2, 2, mask2 );
158 
159  /* compute descriptors for lines from first octave */
160  bd->compute( imageMat1, klsd1, lsd_descr1 );
161  bd->compute( imageMat2, klsd2, lsd_descr2 );
162 
163  /* select lines and descriptors from first octave */
164  std::vector<KeyLine> octave0_1, octave0_2;
165  Mat leftDEscr, rightDescr;
166  for ( int i = 0; i < (int) klsd1.size(); i++ )
167  {
168  if( klsd1[i].octave == 1 )
169  {
170  octave0_1.push_back( klsd1[i] );
171  leftDEscr.push_back( lsd_descr1.row( i ) );
172  }
173  }
174 
175  for ( int j = 0; j < (int) klsd2.size(); j++ )
176  {
177  if( klsd2[j].octave == 1 )
178  {
179  octave0_2.push_back( klsd2[j] );
180  rightDescr.push_back( lsd_descr2.row( j ) );
181  }
182  }
183 
184  /* compute matches */
185  std::vector<DMatch> lsd_matches;
186  bdm->match( leftDEscr, rightDescr, lsd_matches );
187 
188  /* select best matches */
189  good_matches.clear();
190  for ( int i = 0; i < (int) lsd_matches.size(); i++ )
191  {
192  if( lsd_matches[i].distance < MATCHES_DIST_THRESHOLD )
193  good_matches.push_back( lsd_matches[i] );
194  }
195 
196  /* plot matches */
197  cv::Mat lsd_outImg;
198  resize( imageMat1, imageMat1, Size( imageMat1.cols / 2, imageMat1.rows / 2 ) );
199  resize( imageMat2, imageMat2, Size( imageMat2.cols / 2, imageMat2.rows / 2 ) );
200  std::vector<char> lsd_mask( matches.size(), 1 );
201  drawLineMatches( imageMat1, octave0_1, imageMat2, octave0_2, good_matches, lsd_outImg, Scalar::all( -1 ), Scalar::all( -1 ), lsd_mask,
203 
204  imshow( "LSD matches", lsd_outImg );
205  waitKey();
206 
207 
208 }
209 
void detect(const Mat &image, std::vector< KeyLine > &keypoints, int scale, int numOctaves, const Mat &mask=Mat())
Detect lines inside an image.
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
Mat row(int y) const
Creates a matrix header for the specified matrix row.
static Ptr< LSDDetector > createLSDDetector()
Creates ad LSDDetector object, using smart pointers.
static Ptr< BinaryDescriptor > createBinaryDescriptor()
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a sma...
void push_back(const _Tp &elem)
Adds elements to the bottom of the matrix.
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
static MatExpr ones(int rows, int cols, int type)
Returns an array of all 1&#39;s of the specified size and type.
uchar * data
pointer to the data
Definition: mat.hpp:1909
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
Definition: affine.hpp:51
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
Resizes an image.
Designed for command line parsing.
Definition: utility.hpp:734
bool empty() const
MatSize size
Definition: mat.hpp:1926
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.
Definition: descriptor.hpp:77
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:280
Size2i Size
Definition: types.hpp:313
#define CV_8UC1
Definition: interface.h:82
static Scalar_< double > all(double v0)
returns a scalar with all elements set to v0
Definition: cvstd.hpp:477
n-dimensional dense array class
Definition: mat.hpp:740
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...
static Ptr< BinaryDescriptorMatcher > createBinaryDescriptorMatcher()
Create a BinaryDescriptorMatcher object and return a smart pointer to it.
int waitKey(int delay=0)
Waits for a pressed key.

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:

matching2.png
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 
43 
44 #include "opencv2/core/utility.hpp"
45 #include <opencv2/imgproc.hpp>
46 #include <opencv2/features2d.hpp>
47 #include <opencv2/highgui.hpp>
48 
49 #include <iostream>
50 #include <vector>
51 
52 using namespace cv;
53 using namespace cv::line_descriptor;
54 
55 static const std::string images[] =
56 { "cameraman.jpg", "church.jpg", "church2.png", "einstein.jpg", "stuff.jpg" };
57 
58 static const char* keys =
59 { "{@image_path | | Image path }" };
60 
61 static void help()
62 {
63  std::cout << "\nThis example shows the functionalities of radius matching " << "Please, run this sample using a command in the form\n"
64  << "./example_line_descriptor_radius_matching <path_to_input_images>/" << std::endl;
65 }
66 
67 int main( int argc, char** argv )
68 {
69  /* get parameters from comand line */
70  CommandLineParser parser( argc, argv, keys );
71  String pathToImages = parser.get < String > ( 0 );
72 
73  /* create structures for hosting KeyLines and descriptors */
74  int num_elements = sizeof ( images ) / sizeof ( images[0] );
75  std::vector < Mat > descriptorsMat;
76  std::vector < std::vector<KeyLine> > linesMat;
77 
78  /*create a pointer to a BinaryDescriptor object */
80 
81  /* compute lines and descriptors */
82  for ( int i = 0; i < num_elements; i++ )
83  {
84  /* get path to image */
85  std::stringstream image_path;
86  image_path << pathToImages << images[i];
87  std::cout << image_path.str().c_str() << std::endl;
88 
89  /* load image */
90  Mat loadedImage = imread( image_path.str().c_str(), 1 );
91  if( loadedImage.data == NULL )
92  {
93  std::cout << "Could not load images." << std::endl;
94  help();
95  exit( -1 );
96  }
97 
98  /* compute lines and descriptors */
99  std::vector < KeyLine > lines;
100  Mat computedDescr;
101  bd->detect( loadedImage, lines );
102  bd->compute( loadedImage, lines, computedDescr );
103 
104  descriptorsMat.push_back( computedDescr );
105  linesMat.push_back( lines );
106 
107  }
108 
109  /* compose a queries matrix */
110  Mat queries;
111  for ( size_t j = 0; j < descriptorsMat.size(); j++ )
112  {
113  if( descriptorsMat[j].rows >= 5 )
114  queries.push_back( descriptorsMat[j].rowRange( 0, 5 ) );
115 
116  else if( descriptorsMat[j].rows > 0 && descriptorsMat[j].rows < 5 )
117  queries.push_back( descriptorsMat[j] );
118  }
119 
120  std::cout << "It has been generated a matrix of " << queries.rows << " descriptors" << std::endl;
121 
122  /* create a BinaryDescriptorMatcher object */
124 
125  /* populate matcher */
126  bdm->add( descriptorsMat );
127 
128  /* compute matches */
129  std::vector < std::vector<DMatch> > matches;
130  bdm->radiusMatch( queries, matches, 30 );
131  std::cout << "size matches sample " << matches.size() << std::endl;
132 
133  for ( int i = 0; i < (int) matches.size(); i++ )
134  {
135  for ( int j = 0; j < (int) matches[i].size(); j++ )
136  {
137  std::cout << "match: " << matches[i][j].queryIdx << " " << matches[i][j].trainIdx << " " << matches[i][j].distance << std::endl;
138  }
139 
140  }
141 
142 }
static Ptr< BinaryDescriptor > createBinaryDescriptor()
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a sma...
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions ...
Definition: mat.hpp:1907
void push_back(const _Tp &elem)
Adds elements to the bottom of the matrix.
Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
uchar * data
pointer to the data
Definition: mat.hpp:1909
Definition: affine.hpp:51
Designed for command line parsing.
Definition: utility.hpp:734
void add(const std::vector< Mat > &descriptors)
Store locally new descriptors to be inserted in dataset, without updating dataset.
const char * c_str() const
Definition: descriptor.hpp:77
Template class for smart pointers with shared ownership.
Definition: cvstd.hpp:280
void detect(const Mat &image, std::vector< KeyLine > &keypoints, const Mat &mask=Mat())
Requires line detection.
void compute(const Mat &image, std::vector< KeyLine > &keylines, Mat &descriptors, bool returnFloatDescr=false) const
Requires descriptors computation.
for i
Definition: modelConvert.m:63
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...
Definition: cvstd.hpp:477
static Ptr< BinaryDescriptorMatcher > createBinaryDescriptorMatcher()
Create a BinaryDescriptorMatcher object and return a smart pointer to it.