fractallabeler.cpp
Go to the documentation of this file.
2 
3 #include "aruco_cvversioning.h"
4 namespace aruco
5 {
6 
8 {
9  _fractalMarkerSet = fractMarkerSet;
10 }
11 
12 bool FractalMarkerLabeler::detect(const cv::Mat& in, int& marker_id, int& nRotations,
13  std::string& additionalInfo)
14 {
15  assert(in.rows == in.cols);
16  cv::Mat grey;
17  if (in.type() == CV_8UC1)
18  grey = in;
19  else
20  cv::cvtColor(in, grey, CV_BGR2GRAY);
21  // threshold image
22  cv::threshold(grey, grey, 125, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
23 
24  std::map<uint32_t, std::vector<cv::Mat> > nbits_innerCodes;
25 
26  for (auto bitsids : _fractalMarkerSet.nbits_fractalMarkerIDs)
27  {
28  int nbits = bitsids.first;
29  std::vector<cv::Mat> innerCodes;
30  getInnerCode(grey, nbits, innerCodes);
31 
32  if (innerCodes.size() > 0)
33  {
34  if (sum(innerCodes[0])[0] != 0)
35  {
36  nbits_innerCodes[nbits] = innerCodes;
37  }
38  }
39  }
40 
41  if (nbits_innerCodes.size() == 0)
42  return false;
43 
44  // check if any dictionary recognizes it
45  for (auto bit_innerCodes : nbits_innerCodes)
46  {
47  uint32_t nb = bit_innerCodes.first;
48  auto innerCodes = bit_innerCodes.second;
49 
50  for (int i = 0; i < 4; i++)
51  {
52  if (_fractalMarkerSet.isFractalMarker(innerCodes[i], nb, marker_id))
53  {
54  // is in the set?
55  nRotations = i; // how many rotations are and its id
56  return true; // bye bye
57  }
58  }
59  }
60  return false;
61 }
62 
63 
64 std::string FractalMarkerLabeler::getName() const
65 {
66  return "fractal";
67  ;
68 }
69 
70 bool FractalMarkerLabeler::getInnerCode(const cv::Mat& thres_img, int total_nbits,
71  std::vector<cv::Mat>& innerCodes)
72 {
73  int bits_noborder = static_cast<int>(std::sqrt(total_nbits));
74  int bits_withborder = bits_noborder + 2;
75  // Markers are divided in (bits_a+2)x(bits_a+2) regions, of which the inner
76  // bits_axbits_a belongs to marker info the external border shoould be entirely black
77  cv::Mat nonZeros(bits_withborder, bits_withborder, CV_32SC1);
78  cv::Mat nValues(bits_withborder, bits_withborder, CV_32SC1);
79  nonZeros.setTo(cv::Scalar::all(0));
80  nValues.setTo(cv::Scalar::all(0));
81  for (int y = 0; y < thres_img.rows; y++)
82  {
83  const uchar* ptr = thres_img.ptr<uchar>(y);
84  int my = float(bits_withborder) * float(y) / float(thres_img.rows);
85  for (int x = 0; x < thres_img.cols; x++)
86  {
87  int mx = float(bits_withborder) * float(x) / float(thres_img.cols);
88  if (ptr[x] > 125)
89  nonZeros.at<int>(my, mx)++;
90  nValues.at<int>(my, mx)++;
91  }
92  }
93  cv::Mat binaryCode(bits_withborder, bits_withborder, CV_8UC1);
94  // now, make the theshold
95  for (int y = 0; y < bits_withborder; y++)
96  for (int x = 0; x < bits_withborder; x++)
97  {
98  if (nonZeros.at<int>(y, x) > nValues.at<int>(y, x) / 2)
99  binaryCode.at<uchar>(y, x) = 1;
100  else
101  binaryCode.at<uchar>(y, x) = 0;
102  }
103 
104  // check if border is completely black
105  for (int y = 0; y < bits_withborder; y++)
106  {
107  int inc = bits_withborder - 1;
108  if (y == 0 || y == bits_withborder - 1)
109  inc = 1; // for first and last row, check the whole border
110  for (int x = 0; x < bits_withborder; x += inc)
111  if (binaryCode.at<uchar>(y, x) != 0)
112  return false;
113  }
114 
115  // take the inner code
116  cv::Mat _bits(bits_noborder, bits_noborder, CV_8UC1);
117  for (int y = 0; y < bits_noborder; y++)
118  for (int x = 0; x < bits_noborder; x++)
119  _bits.at<uchar>(y, x) = binaryCode.at<uchar>(y + 1, x + 1);
120 
121  // now, get the 64bits ids
122  int nr = 0;
123  do
124  {
125  innerCodes.push_back(_bits);
126  _bits = rotate(_bits);
127  nr++;
128  } while (nr < 4);
129  return true;
130 }
131 
132 cv::Mat FractalMarkerLabeler::rotate(const cv::Mat& in)
133 {
134  cv::Mat out;
135  in.copyTo(out);
136  for (int i = 0; i < in.rows; i++)
137  {
138  for (int j = 0; j < in.cols; j++)
139  {
140  out.at<uchar>(i, j) = in.at<uchar>(in.cols - j - 1, i);
141  }
142  }
143  return out;
144 }
145 } // namespace aruco
aruco::FractalMarkerLabeler::detect
bool detect(const cv::Mat &in, int &marker_id, int &nRotations, std::string &additionalInfo)
Definition: fractallabeler.cpp:12
aruco::FractalMarkerLabeler::setConfiguration
void setConfiguration(const FractalMarkerSet &fractMarkerSet)
Definition: fractallabeler.cpp:7
aruco::FractalMarkerLabeler::getInnerCode
bool getInnerCode(const cv::Mat &thres_img, int total_nbits, std::vector< cv::Mat > &ids)
Definition: fractallabeler.cpp:70
aruco::FractalMarkerLabeler::rotate
cv::Mat rotate(const cv::Mat &in)
Definition: fractallabeler.cpp:132
fractallabeler.h
aruco::FractalMarkerLabeler::_fractalMarkerSet
FractalMarkerSet _fractalMarkerSet
Definition: fractallabeler.h:46
aruco::FractalMarkerSet::nbits_fractalMarkerIDs
std::map< int, std::vector< int > > nbits_fractalMarkerIDs
Definition: fractalmarkerset.h:72
aruco::FractalMarkerSet::isFractalMarker
bool isFractalMarker(cv::Mat &m, int nbits, int &id)
Definition: fractalmarkerset.cpp:696
aruco
Definition: cameraparameters.h:24
aruco_cvversioning.h
aruco::FractalMarkerSet
Definition: fractalmarkerset.h:10
aruco::FractalMarkerLabeler::getName
std::string getName() const
Definition: fractallabeler.cpp:64


aruco
Author(s): Rafael Muñoz Salinas , Bence Magyar
autogenerated on Sat Sep 23 2023 02:26:45