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 #include <time.h>
55
56 using namespace cv;
57 using namespace cv::line_descriptor;
58
59 static const char* keys =
60 { "{@image_path1 | | Image path 1 }"
61 "{@image_path2 | | Image path 2 }" };
62
help()63 static void help()
64 {
65 std::cout << "\nThis example shows the functionalities of descriptors matching\n" << "Please, run this sample using a command in the form\n"
66 << "./example_line_descriptor_matching <path_to_input_image 1>" << "<path_to_input_image 2>" << std::endl;
67
68 }
69
70 uchar invertSingleBits( uchar dividend_char, int numBits );
71
72 /* invert numBits bits in input char */
invertSingleBits(uchar dividend_char,int numBits)73 uchar invertSingleBits( uchar dividend_char, int numBits )
74 {
75 std::vector<int> bin_vector;
76 long dividend;
77 long bin_num;
78
79 /* convert input char to a long */
80 dividend = (long) dividend_char;
81
82 /*if a 0 has been obtained, just generate a 8-bit long vector of zeros */
83 if( dividend == 0 )
84 bin_vector = std::vector<int>( 8, 0 );
85
86 /* else, apply classic decimal to binary conversion */
87 else
88 {
89 while ( dividend >= 1 )
90 {
91 bin_num = dividend % 2;
92 dividend /= 2;
93 bin_vector.push_back( bin_num );
94 }
95 }
96
97 /* ensure that binary vector always has length 8 */
98 if( bin_vector.size() < 8 )
99 {
100 std::vector<int> zeros( 8 - bin_vector.size(), 0 );
101 bin_vector.insert( bin_vector.end(), zeros.begin(), zeros.end() );
102 }
103
104 /* invert numBits bits */
105 for ( int index = 0; index < numBits; index++ )
106 {
107 if( bin_vector[index] == 0 )
108 bin_vector[index] = 1;
109
110 else
111 bin_vector[index] = 0;
112 }
113
114 /* reconvert to decimal */
115 uchar result = 0;
116 for ( int i = (int) bin_vector.size() - 1; i >= 0; i-- )
117 result += (uchar) ( bin_vector[i] * (1 << i) );
118
119 return result;
120 }
121
main(int argc,char ** argv)122 int main( int argc, char** argv )
123 {
124 /* get parameters from comand line */
125 CommandLineParser parser( argc, argv, keys );
126 String image_path1 = parser.get<String>( 0 );
127 String image_path2 = parser.get<String>( 1 );
128
129 if( image_path1.empty() || image_path2.empty() )
130 {
131 help();
132 return -1;
133 }
134
135 /* load image */
136 cv::Mat imageMat1 = imread( image_path1, 1 );
137 cv::Mat imageMat2 = imread( image_path2, 1 );
138
139 if( imageMat1.data == NULL || imageMat2.data == NULL )
140 {
141 std::cout << "Error, images could not be loaded. Please, check their paths" << std::endl;
142 }
143
144 /* create binary masks */
145 cv::Mat mask1 = Mat::ones( imageMat1.size(), CV_8UC1 );
146 cv::Mat mask2 = Mat::ones( imageMat2.size(), CV_8UC1 );
147
148 /* create a pointer to a BinaryDescriptor object with default parameters */
149 Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
150
151 /* compute lines */
152 std::vector<KeyLine> keylines1, keylines2;
153 bd->detect( imageMat1, keylines1, mask1 );
154 bd->detect( imageMat2, keylines2, mask2 );
155
156 /* compute descriptors */
157 cv::Mat descr1, descr2;
158 bd->compute( imageMat1, keylines1, descr1 );
159 bd->compute( imageMat2, keylines2, descr2 );
160
161 /* create a BinaryDescriptorMatcher object */
162 Ptr<BinaryDescriptorMatcher> bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
163
164 /* make a copy of descr2 mat */
165 Mat descr2Copy = descr1.clone();
166
167 /* randomly change some bits in original descriptors */
168 srand( (unsigned int) time( NULL ) );
169
170 for ( int j = 0; j < descr1.rows; j++ )
171 {
172 /* select a random column */
173 int randCol = rand() % 32;
174
175 /* get correspondent data */
176 uchar u = descr1.at<uchar>( j, randCol );
177
178 /* change bits */
179 for ( int k = 1; k <= 5; k++ )
180 {
181 /* copy current row to train matrix */
182 descr2Copy.push_back( descr1.row( j ) );
183
184 /* invert k bits */
185 uchar uc = invertSingleBits( u, k );
186
187 /* update current row in train matrix */
188 descr2Copy.at<uchar>( descr2Copy.rows - 1, randCol ) = uc;
189 }
190 }
191
192 /* prepare a structure to host matches */
193 std::vector<std::vector<DMatch> > matches;
194
195 /* require knn match */
196 bdm->knnMatch( descr1, descr2, matches, 6 );
197
198 }
199
200 #else
201
main()202 int main()
203 {
204 std::cerr << "OpenCV was built without features2d module" << std::endl;
205 return 0;
206 }
207
208 #endif // HAVE_OPENCV_FEATURES2D
209