knn_matching.cpp 6.3 KB

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