FORB.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * File: FORB.cpp
  3. * Date: June 2012
  4. * Author: Dorian Galvez-Lopez
  5. * Description: functions for ORB descriptors
  6. * License: see the LICENSE.txt file
  7. *
  8. * Distance function has been modified
  9. *
  10. */
  11. #include <vector>
  12. #include <string>
  13. #include <sstream>
  14. #include <stdint-gcc.h>
  15. #include "FORB.h"
  16. using namespace std;
  17. namespace DBoW2 {
  18. // --------------------------------------------------------------------------
  19. const int FORB::L=32;
  20. void FORB::meanValue(const std::vector<FORB::pDescriptor> &descriptors,
  21. FORB::TDescriptor &mean)
  22. {
  23. if(descriptors.empty())
  24. {
  25. mean.release();
  26. return;
  27. }
  28. else if(descriptors.size() == 1)
  29. {
  30. mean = descriptors[0]->clone();
  31. }
  32. else
  33. {
  34. vector<int> sum(FORB::L * 8, 0);
  35. for(size_t i = 0; i < descriptors.size(); ++i)
  36. {
  37. const cv::Mat &d = *descriptors[i];
  38. const unsigned char *p = d.ptr<unsigned char>();
  39. for(int j = 0; j < d.cols; ++j, ++p)
  40. {
  41. if(*p & (1 << 7)) ++sum[ j*8 ];
  42. if(*p & (1 << 6)) ++sum[ j*8 + 1 ];
  43. if(*p & (1 << 5)) ++sum[ j*8 + 2 ];
  44. if(*p & (1 << 4)) ++sum[ j*8 + 3 ];
  45. if(*p & (1 << 3)) ++sum[ j*8 + 4 ];
  46. if(*p & (1 << 2)) ++sum[ j*8 + 5 ];
  47. if(*p & (1 << 1)) ++sum[ j*8 + 6 ];
  48. if(*p & (1)) ++sum[ j*8 + 7 ];
  49. }
  50. }
  51. mean = cv::Mat::zeros(1, FORB::L, CV_8U);
  52. unsigned char *p = mean.ptr<unsigned char>();
  53. const int N2 = (int)descriptors.size() / 2 + descriptors.size() % 2;
  54. for(size_t i = 0; i < sum.size(); ++i)
  55. {
  56. if(sum[i] >= N2)
  57. {
  58. // set bit
  59. *p |= 1 << (7 - (i % 8));
  60. }
  61. if(i % 8 == 7) ++p;
  62. }
  63. }
  64. }
  65. // --------------------------------------------------------------------------
  66. int FORB::distance(const FORB::TDescriptor &a,
  67. const FORB::TDescriptor &b)
  68. {
  69. // Bit set count operation from
  70. // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
  71. const int *pa = a.ptr<int32_t>();
  72. const int *pb = b.ptr<int32_t>();
  73. int dist=0;
  74. for(int i=0; i<8; i++, pa++, pb++)
  75. {
  76. unsigned int v = *pa ^ *pb;
  77. v = v - ((v >> 1) & 0x55555555);
  78. v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
  79. dist += (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
  80. }
  81. return dist;
  82. }
  83. // --------------------------------------------------------------------------
  84. std::string FORB::toString(const FORB::TDescriptor &a)
  85. {
  86. stringstream ss;
  87. const unsigned char *p = a.ptr<unsigned char>();
  88. for(int i = 0; i < a.cols; ++i, ++p)
  89. {
  90. ss << (int)*p << " ";
  91. }
  92. return ss.str();
  93. }
  94. // --------------------------------------------------------------------------
  95. void FORB::fromString(FORB::TDescriptor &a, const std::string &s)
  96. {
  97. a.create(1, FORB::L, CV_8U);
  98. unsigned char *p = a.ptr<unsigned char>();
  99. stringstream ss(s);
  100. for(int i = 0; i < FORB::L; ++i, ++p)
  101. {
  102. int n;
  103. ss >> n;
  104. if(!ss.fail())
  105. *p = (unsigned char)n;
  106. }
  107. }
  108. // --------------------------------------------------------------------------
  109. void FORB::toMat32F(const std::vector<TDescriptor> &descriptors,
  110. cv::Mat &mat)
  111. {
  112. if(descriptors.empty())
  113. {
  114. mat.release();
  115. return;
  116. }
  117. const size_t N = descriptors.size();
  118. mat.create(N, FORB::L*8, CV_32F);
  119. float *p = mat.ptr<float>();
  120. for(size_t i = 0; i < N; ++i)
  121. {
  122. const int C = descriptors[i].cols;
  123. const unsigned char *desc = descriptors[i].ptr<unsigned char>();
  124. for(int j = 0; j < C; ++j, p += 8)
  125. {
  126. p[0] = (desc[j] & (1 << 7) ? 1 : 0);
  127. p[1] = (desc[j] & (1 << 6) ? 1 : 0);
  128. p[2] = (desc[j] & (1 << 5) ? 1 : 0);
  129. p[3] = (desc[j] & (1 << 4) ? 1 : 0);
  130. p[4] = (desc[j] & (1 << 3) ? 1 : 0);
  131. p[5] = (desc[j] & (1 << 2) ? 1 : 0);
  132. p[6] = (desc[j] & (1 << 1) ? 1 : 0);
  133. p[7] = desc[j] & (1);
  134. }
  135. }
  136. }
  137. // --------------------------------------------------------------------------
  138. void FORB::toMat8U(const std::vector<TDescriptor> &descriptors,
  139. cv::Mat &mat)
  140. {
  141. mat.create(descriptors.size(), 32, CV_8U);
  142. unsigned char *p = mat.ptr<unsigned char>();
  143. for(size_t i = 0; i < descriptors.size(); ++i, p += 32)
  144. {
  145. const unsigned char *d = descriptors[i].ptr<unsigned char>();
  146. std::copy(d, d+32, p);
  147. }
  148. }
  149. // --------------------------------------------------------------------------
  150. } // namespace DBoW2