TagFamily.cc
Go to the documentation of this file.
00001 #include <iostream>
00002 
00003 #include "TagFamily.h"
00004 
00026 namespace AprilTags {
00027 
00028 TagFamily::TagFamily(const TagCodes& tagCodes)
00029   : blackBorder(1), bits(tagCodes.bits), dimension((int)std::sqrt((float)bits)),
00030     minimumHammingDistance(tagCodes.minHammingDistance),
00031     errorRecoveryBits(1), codes() {
00032   if ( bits != dimension*dimension )
00033     cerr << "Error: TagFamily constructor called with bits=" << bits << "; must be a square number!" << endl;
00034   codes = tagCodes.codes;
00035 }
00036 
00037 void TagFamily::setErrorRecoveryBits(int b) {
00038   errorRecoveryBits = b;
00039 }
00040 
00041 void TagFamily::setErrorRecoveryFraction(float v) {
00042   errorRecoveryBits = (int) (((int) (minimumHammingDistance-1)/2)*v);
00043 }
00044 
00045 unsigned long long TagFamily::rotate90(unsigned long long w, int d) {
00046   unsigned long long wr = 0;
00047   const unsigned long long oneLongLong = 1;
00048 
00049   for (int r = d-1; r>=0; r--) {
00050     for (int c = 0; c<d; c++) {
00051       int b = r + d*c;
00052       wr = wr<<1;
00053       
00054       if ((w & (oneLongLong<<b)) != 0)
00055         wr |= 1;
00056     }
00057   }
00058   return wr;
00059 }
00060 
00061 int TagFamily::hammingDistance(unsigned long long a, unsigned long long b) {
00062   return popCount(a^b);
00063 }
00064 
00065 unsigned char TagFamily::popCountReal(unsigned long long w) {
00066   unsigned char cnt = 0;
00067   while (w != 0) {
00068     w &= (w-1);
00069     ++cnt;
00070   }
00071   return cnt;
00072 }
00073 
00074 int TagFamily::popCount(unsigned long long w) {
00075   int count = 0;
00076   while (w != 0) {
00077     count += popCountTable[(unsigned int) (w & (popCountTableSize-1))];
00078     w >>= popCountTableShift;
00079   }
00080   return count;
00081 }
00082 
00083 void TagFamily::decode(TagDetection& det, unsigned long long rCode) const {
00084   int  bestId = -1;
00085   int  bestHamming = INT_MAX;
00086   int  bestRotation = 0;
00087   unsigned long long bestCode = 0;
00088 
00089   unsigned long long rCodes[4];
00090   rCodes[0] = rCode;
00091   rCodes[1] = rotate90(rCodes[0], dimension);
00092   rCodes[2] = rotate90(rCodes[1], dimension);
00093   rCodes[3] = rotate90(rCodes[2], dimension);
00094 
00095   for (unsigned int id = 0; id < codes.size(); id++) {
00096     for (unsigned int rot = 0; rot < 4; rot++) {
00097       int thisHamming = hammingDistance(rCodes[rot], codes[id]);
00098       if (thisHamming < bestHamming) {
00099         bestHamming = thisHamming;
00100         bestRotation = rot;
00101         bestId = id;
00102         bestCode = codes[id];
00103       }
00104     }
00105   }
00106   det.id = bestId;
00107   det.hammingDistance = bestHamming;
00108   det.rotation = bestRotation;
00109   det.good = (det.hammingDistance <= errorRecoveryBits);
00110   det.obsCode = rCode;
00111   det.code = bestCode;
00112 }
00113 
00114 void TagFamily::printHammingDistances() const {
00115   vector<int> hammings(dimension*dimension+1);
00116   for (unsigned i = 0; i < codes.size(); i++) {
00117     unsigned long long r0 = codes[i];
00118     unsigned long long r1 = rotate90(r0, dimension);
00119     unsigned long long r2 = rotate90(r1, dimension);
00120     unsigned long long r3 = rotate90(r2, dimension);
00121     for (unsigned int j = i+1; j < codes.size(); j++) {
00122       int d = min(min(hammingDistance(r0, codes[j]),
00123                       hammingDistance(r1, codes[j])),
00124                   min(hammingDistance(r2, codes[j]),
00125                       hammingDistance(r3, codes[j])));
00126       hammings[d]++;
00127     }
00128   }
00129 
00130   for (unsigned int i = 0; i < hammings.size(); i++)
00131     printf("hammings: %u = %d\n", i, hammings[i]);
00132 }
00133 
00134 unsigned char TagFamily::popCountTable[TagFamily::popCountTableSize];
00135 
00136 TagFamily::TableInitializer TagFamily::initializer;
00137 
00138 } // namespace


apriltags
Author(s): Mitchell Wills
autogenerated on Thu Aug 27 2015 12:23:28