OpenCV 4.13.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 4.13.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
直線特徴チュートリアル

このチュートリアルでは、以下の方法を示す:

  • BinaryDescriptor インターフェイスを使って線分を抽出し、それらを KeyLine オブジェクトに格納する
  • 同じインターフェイスを使って、抽出した各線分の記述子を計算する
  • BynaryDescriptorMatcher を使って、異なる画像から得られた記述子間のマッチを求める

線分の抽出と記述子の計算

次のコード片では、画像から線分を検出する方法を示す。LSD 抽出器は LSD_REFINE_ADV オプションで初期化され、残りの引数はデフォルト値のままにしている。すべての抽出された線分を受け入れるために、1で埋めたマスクを使用する。最後に、それらをオクターブ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
49#include <opencv2/imgproc.hpp>
51#include <opencv2/highgui.hpp>
52
53using namespace cv;
54using namespace cv::line_descriptor;
55using namespace std;
56
57static const char* keys =
58{ "{@image_path | | Image path }" };
59
60static 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
66int 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
129int main()
130{
131 std::cerr << "OpenCV was built without features2d module" << std::endl;
132 return 0;
133}
134
135#endif // HAVE_OPENCV_FEATURES2D
Designed for command line parsing.
Definition utility.hpp:890
n-dimensional dense array class
Definition mat.hpp:840
CV_NODISCARD_STD Mat clone() const
Creates a full copy of the array and the underlying data.
MatSize size
Definition mat.hpp:2226
uchar * data
pointer to the data
Definition mat.hpp:2206
int channels() const
Returns the number of matrix channels.
std::string String
Definition cvstd.hpp:151
std::shared_ptr< _Tp > Ptr
Definition cvstd_wrapper.hpp:23
#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.
Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0, AlgorithmHint hint=cv::ALGO_HINT_DEFAULT)
Converts an image from one color space to another.
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.
int main(int argc, char *argv[])
Definition highgui_qt.cpp:3
Definition descriptor.hpp:77
Definition core.hpp:107
STL namespace.
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

これは有名な cameraman 画像から得られた結果である:

alternate text

線分を抽出するもう一つの方法は LSDDetector クラスを使うことである。このクラスは LSD 抽出器を用いて線分を計算する。この結果を得るには、上で示したコード片を使い、該当する行を変更するだけで十分である

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

これは再び cameraman 画像に対して LSD 検出器が返した結果である:

alternate text

キーラインが検出されたら、次に示すようにそれらの記述子を計算できる:

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
49#include <opencv2/imgproc.hpp>
51#include <opencv2/highgui.hpp>
52
53using namespace cv;
54using namespace cv::line_descriptor;
55
56
57static const char* keys =
58{ "{@image_path | | Image path }" };
59
60static 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
67int 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
105int main()
106{
107 std::cerr << "OpenCV was built without features2d module" << std::endl;
108 return 0;
109}
110
111#endif // HAVE_OPENCV_FEATURES2D

記述子間のマッチング

2つの異なる画像から記述子を抽出した場合、それらの間でマッチを探すことができる。その一つの方法は、各入力クエリ記述子に対して記述子を厳密にマッチさせ、距離が最も近いものを選ぶことである:

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
49#include <opencv2/imgproc.hpp>
51#include <opencv2/highgui.hpp>
52
53#define MATCHES_DIST_THRESHOLD 25
54
55using namespace cv;
56using namespace cv::line_descriptor;
57
58static const char* keys =
59{ "{@image_path1 | | Image path 1 }"
60 "{@image_path2 | | Image path 2 }" };
61
62static 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
70int 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
214int main()
215{
216 std::cerr << "OpenCV was built without features2d module" << std::endl;
217 return 0;
218}
219
220#endif // HAVE_OPENCV_FEATURES2D
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.
Template class for specifying the size of an image or rectangle.
Definition types.hpp:335
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR)
Resizes an image.
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.

場合によっては、ある入力に対して最も近い k 個の記述子を探したいことがある。これには、前のコードを少し変更する必要がある:

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

上の例では、各クエリに対して最も近い6個の記述子が返される。ある場合には、探索半径を設けて、入力クエリから高々 r の距離にあるすべての記述子を探したいことがある。前のコードは次のように変更する必要がある:

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

これは、元の cameraman 画像と、それをダウンサンプリングした(さらにぼかした)版から抽出した記述子間のマッチングの例である:

alternate text

内部データベースへの問い合わせ

BynaryDescriptorMatcher クラスは、異なる画像から抽出した記述子を格納でき、前節で説明したいずれかの方式で問い合わせられる内部データベースを持つ。内部データセットへの登録は add 関数で行える。この関数は新しいデータを直接データベースに追加するのではなく、ローカルに保持するだけである。実際の更新は train 関数が呼び出されたとき、または任意の問い合わせ関数が実行されたときに起こる。なぜなら、それぞれが問い合わせの前に train を呼び出すからである。問い合わせを受けると、内部データベースは必要な記述子を返すだけでなく、返された各マッチについて、そのマッチした記述子がどの画像から抽出されたかを示すことができる。内部データセットの使用例を次のコードで説明する。ローカルに新しい記述子を追加した後、半径探索を実行する。これによりローカルのデータがデータセットに転送され、そのデータセットが続いて問い合わせられる。

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
49#include <opencv2/imgproc.hpp>
51#include <opencv2/highgui.hpp>
52
53#include <vector>
54
55using namespace cv;
56using namespace cv::line_descriptor;
57
58static const std::string images[] =
59{ "cameraman.jpg", "church.jpg", "church2.png", "einstein.jpg", "stuff.jpg" };
60
61static const char* keys =
62{ "{@image_path | | Image path }" };
63
64static 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
70int 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
149int main()
150{
151 std::cerr << "OpenCV was built without features2d module" << std::endl;
152 return 0;
153}
154
155#endif // HAVE_OPENCV_FEATURES2D
int rows
the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
Definition mat.hpp:2204