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.
43 #include <opencv2/opencv_modules.hpp>
45 #ifdef HAVE_OPENCV_FEATURES2D
57 static const char* keys =
58 {
"{@image_path | | Image path }" };
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;
66 int main(
int argc,
char** argv )
72 if( image_path.empty() )
80 if( imageMat.
data == NULL )
82 std::cout <<
"Error, image could not be loaded. Please, check its path" << std::endl;
93 vector<KeyLine> lines;
97 bd->detect( imageMat, lines, 2, 1,
mask );
102 for (
size_t i = 0; i < lines.size(); i++ )
108 int R = ( rand() % (int) ( 255 + 1 ) );
109 int G = ( rand() % (int) ( 255 + 1 ) );
110 int B = ( rand() % (int) ( 255 + 1 ) );
117 line( output, pt1, pt2,
Scalar( B, G, R ), 3 );
123 imshow(
"LSD lines", output );
131 std::cerr <<
"OpenCV was built without features2d module" << std::endl;
Designed for command line parsing.
Definition: utility.hpp:818
n-dimensional dense array class
Definition: mat.hpp:811
CV_NODISCARD_STD Mat clone() const
Creates a full copy of the array and the underlying data.
MatSize size
Definition: mat.hpp:2138
uchar * data
pointer to the data
Definition: mat.hpp:2118
static CV_NODISCARD_STD MatExpr ones(int rows, int cols, int type)
Returns an array of all 1's of the specified size and type.
int channels() const
Returns the number of matrix channels.
static Ptr< LSDDetector > createLSDDetector()
Creates ad LSDDetector object, using smart pointers.
std::string String
Definition: cvstd.hpp:150
Scalar_< double > Scalar
Definition: types.hpp:691
std::shared_ptr< _Tp > Ptr
Definition: cvstd_wrapper.hpp:23
Point_< float > Point2f
Definition: types.hpp:202
#define CV_8UC1
Definition: interface.h:88
GMat mask(const GMat &src, const GMat &mask)
Applies a mask to a matrix.
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR)
Loads an image from a file.
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)
Converts an image from one color space to another.
@ COLOR_GRAY2BGR
Definition: imgproc.hpp:553
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.
Definition: descriptor.hpp:77
"black box" representation of the file storage associated with a file on disk.
Definition: affine.hpp:52
A class to represent a line.
Definition: descriptor.hpp:105
float endPointY
Definition: descriptor.hpp:131
float startPointX
Definition: descriptor.hpp:128
float endPointX
Definition: descriptor.hpp:130
float startPointY
Definition: descriptor.hpp:129
int octave
Definition: descriptor.hpp:114
Once keylines have been detected, it is possible to compute their descriptors as shown in the following:
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:
43 #include <opencv2/opencv_modules.hpp>
45 #ifdef HAVE_OPENCV_FEATURES2D
53 #define MATCHES_DIST_THRESHOLD 25
58 static const char* keys =
59 {
"{@image_path1 | | Image path 1 }"
60 "{@image_path2 | | Image path 2 }" };
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;
70 int main(
int argc,
char** argv )
77 if( image_path1.empty() || image_path2.empty() )
87 if( imageMat1.
data == NULL || imageMat2.
data == NULL )
89 std::cout <<
"Error, images could not be loaded. Please, check their path" << std::endl;
100 std::vector<KeyLine> keylines1, keylines2;
103 ( *bd )( imageMat1, mask1, keylines1, descr1,
false, false );
104 ( *bd )( imageMat2, mask2, keylines2, descr2,
false, false );
107 std::vector<KeyLine> lbd_octave1, lbd_octave2;
108 Mat left_lbd, right_lbd;
109 for (
int i = 0; i < (int) keylines1.size(); i++ )
111 if( keylines1[i].octave == 0 )
118 for (
int j = 0; j < (int) keylines2.size(); j++ )
120 if( keylines2[j].octave == 0 )
122 lbd_octave2.push_back( keylines2[j] );
131 std::vector<DMatch> matches;
132 bdm->match( left_lbd, right_lbd, matches );
135 std::vector<DMatch> good_matches;
136 for (
int i = 0; i < (int) matches.size(); i++ )
138 if( matches[i].distance < MATCHES_DIST_THRESHOLD )
139 good_matches.push_back( matches[i] );
145 std::vector<char>
mask( matches.size(), 1 );
149 imshow(
"Matches", outImg );
151 imwrite(
"/home/ubisum/Desktop/images/env_match/matches.jpg", outImg);
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 );
162 bd->compute( imageMat1, klsd1, lsd_descr1 );
163 bd->compute( imageMat2, klsd2, lsd_descr2 );
166 std::vector<KeyLine> octave0_1, octave0_2;
167 Mat leftDEscr, rightDescr;
168 for (
int i = 0; i < (int) klsd1.size(); i++ )
170 if( klsd1[i].octave == 1 )
177 for (
int j = 0; j < (int) klsd2.size(); j++ )
179 if( klsd2[j].octave == 1 )
181 octave0_2.push_back( klsd2[j] );
187 std::vector<DMatch> lsd_matches;
188 bdm->match( leftDEscr, rightDescr, lsd_matches );
191 good_matches.clear();
192 for (
int i = 0; i < (int) lsd_matches.size(); i++ )
194 if( lsd_matches[i].distance < MATCHES_DIST_THRESHOLD )
195 good_matches.push_back( lsd_matches[i] );
202 std::vector<char> lsd_mask( matches.size(), 1 );
206 imshow(
"LSD matches", lsd_outImg );
216 std::cerr <<
"OpenCV was built without features2d module" << std::endl;
Mat row(int y) const
Creates a matrix header for the specified matrix row.
void push_back(const _Tp &elem)
Adds elements to the bottom of the matrix.
static Scalar_< double > all(double v0)
returns a scalar with all elements set to v0
static Ptr< BinaryDescriptorMatcher > createBinaryDescriptorMatcher()
Create a BinaryDescriptorMatcher object and return a smart pointer to it.
Size2i Size
Definition: types.hpp:365
CV_EXPORTS_W bool imwrite(const String &filename, InputArray img, const std::vector< int > ¶ms=std::vector< int >())
Saves an image to a specified file.
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.
@ DEFAULT
Definition: descriptor.hpp:1361
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 be modified like:
Here's an example of matching among descriptors extracted from original cameraman image and its downsampled (and blurred) version:
43 #include <opencv2/opencv_modules.hpp>
45 #ifdef HAVE_OPENCV_FEATURES2D
58 static const std::string images[] =
59 {
"cameraman.jpg",
"church.jpg",
"church2.png",
"einstein.jpg",
"stuff.jpg" };
61 static const char* keys =
62 {
"{@image_path | | Image path }" };
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;
70 int main(
int argc,
char** argv )
77 int num_elements =
sizeof ( images ) /
sizeof ( images[0] );
78 std::vector < Mat > descriptorsMat;
79 std::vector < std::vector<KeyLine> > linesMat;
85 for (
int i = 0; i < num_elements; i++ )
88 std::stringstream image_path;
89 image_path << pathToImages << images[i];
90 std::cout << image_path.str().c_str() << std::endl;
93 Mat loadedImage =
imread( image_path.str().c_str(), 1 );
94 if( loadedImage.
data == NULL )
96 std::cout <<
"Could not load images." << std::endl;
102 std::vector < KeyLine > lines;
104 bd->detect( loadedImage, lines );
105 bd->compute( loadedImage, lines, computedDescr );
107 descriptorsMat.
push_back( computedDescr );
108 linesMat.push_back( lines );
114 for (
size_t j = 0; j < descriptorsMat.size(); j++ )
116 if( descriptorsMat[j].rows >= 5 )
117 queries.
push_back( descriptorsMat[j].rowRange( 0, 5 ) );
119 else if( descriptorsMat[j].rows > 0 && descriptorsMat[j].rows < 5 )
123 std::cout <<
"It has been generated a matrix of " << queries.
rows <<
" descriptors" << std::endl;
129 bdm->add( descriptorsMat );
132 std::vector < std::vector<DMatch> > matches;
133 bdm->radiusMatch( queries, matches, 30 );
134 std::cout <<
"size matches sample " << matches.size() << std::endl;
136 for (
int i = 0; i < (int) matches.size(); i++ )
138 for (
int j = 0; j < (int) matches[i].
size(); j++ )
140 std::cout <<
"match: " << matches[i][j].queryIdx <<
" " << matches[i][j].trainIdx <<
" " << matches[i][j].distance << std::endl;
151 std::cerr <<
"OpenCV was built without features2d module" << std::endl;
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
Definition: mat.hpp:2116
GOpaque< Size > size(const GMat &src)
Gets dimensions from Mat.