00001 #ifndef TAGFAMILY_H 00002 #define TAGFAMILY_H 00003 00004 #include <climits> 00005 #include <cmath> 00006 #include <stdio.h> 00007 #include <vector> 00008 #include <map> 00009 00010 #include "AprilTags/TagDetection.h" 00011 00012 namespace AprilTags { 00013 00014 class TagCodes { 00015 public: 00016 int bits; 00017 int minHammingDistance; 00018 std::vector<unsigned long long> codes; 00019 public: 00020 TagCodes(int bits, int minHammingDistance, 00021 const unsigned long long* codesA, int num) 00022 : bits(bits), minHammingDistance(minHammingDistance), 00023 codes(codesA, codesA+num) // created vector for all entries of codesA 00024 {} 00025 }; 00026 00028 class TagFamily { 00029 public: 00031 TagFamily(const TagCodes& tagCodes); 00032 00033 void setErrorRecoveryBits(int b); 00034 00035 void setErrorRecoveryFraction(float v); 00036 00037 /* if the bits in w were arranged in a d*d grid and that grid was 00038 * rotated, what would the new bits in w be? 00039 * The bits are organized like this (for d = 3): 00040 * 00041 * 8 7 6 2 5 8 0 1 2 00042 * 5 4 3 ==> 1 4 7 ==> 3 4 5 (rotate90 applied twice) 00043 * 2 1 0 0 3 6 6 7 8 00044 */ 00045 static unsigned long long rotate90(unsigned long long w, int d); 00046 00048 static int hammingDistance(unsigned long long a, unsigned long long b); 00049 00051 static unsigned char popCountReal(unsigned long long w); 00052 00053 static int popCount(unsigned long long w); 00054 00056 /* The corresponding fields of TagDetection will be filled in. */ 00057 void decode(TagDetection& det, unsigned long long rCode) const; 00058 00060 void printHammingDistances() const; 00061 00063 int blackBorder; 00064 00066 int bits; 00067 00069 int dimension; 00070 00072 /* Accounting for rotational ambiguity? The code can recover 00073 * (minHammingDistance-1)/2 bit errors. 00074 */ 00075 int minimumHammingDistance; 00076 00077 /* The error recovery value determines our position on the ROC 00078 * curve. We will report codes that are within errorRecoveryBits 00079 * of a valid code. Small values mean greater rejection of bogus 00080 * tags (but false negatives). Large values mean aggressive 00081 * reporting of bad tags (but with a corresponding increase in 00082 * false positives). 00083 */ 00084 int errorRecoveryBits; 00085 00087 std::vector<unsigned long long> codes; 00088 00089 static const int popCountTableShift = 12; 00090 static const unsigned int popCountTableSize = 1 << popCountTableShift; 00091 static unsigned char popCountTable[popCountTableSize]; 00092 00094 static class TableInitializer { 00095 public: 00096 TableInitializer() { 00097 for (unsigned int i = 0; i < TagFamily::popCountTableSize; i++) 00098 TagFamily::popCountTable[i] = TagFamily::popCountReal(i); 00099 } 00100 } initializer; 00101 }; 00102 00103 } // namespace 00104 00105 #endif