markerdetector.h
Go to the documentation of this file.
1 /*****************************
2 Copyright 2011 Rafael Muñoz Salinas. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without modification, are
5 permitted provided that the following conditions are met:
6 
7  1. Redistributions of source code must retain the above copyright notice, this list of
8  conditions and the following disclaimer.
9 
10  2. Redistributions in binary form must reproduce the above copyright notice, this list
11  of conditions and the following disclaimer in the documentation and/or other materials
12  provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY Rafael Muñoz Salinas ''AS IS'' AND ANY EXPRESS OR IMPLIED
15 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Rafael Muñoz Salinas OR
17 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 
24 The views and conclusions contained in the software and documentation are those of the
25 authors and should not be interpreted as representing official policies, either expressed
26 or implied, of Rafael Muñoz Salinas.
27 ********************************/
28 #ifndef _ARUCO_MarkerDetector_H
29 #define _ARUCO_MarkerDetector_H
30 #include <opencv2/core/core.hpp>
31 #include <cstdio>
32 #include <iostream>
33 #include "exports.h"
34 #include "cameraparameters.h"
35 #include "dictionary.h"
36 #include "marker.h"
37 #include "markerlabeler.h"
38 using namespace std;
39 
40 namespace aruco {
45 
46 public:
47 
51 
55  enum ThresholdMethods { FIXED_THRES, ADPT_THRES, CANNY };
56 
59  struct Params{
60  //method emplpoyed for image threshold
62  // Threshold parameters
63  double _thresParam1, _thresParam2, _thresParam1_range;
64 
65  // Current corner method
67  //when using subpix, this indicates the search range for optimization (in pixels)
69  //size of the image passed to the MarkerLabeler
71  // border around image limits in which corners are not allowed to be detected. (0,1)
73 
74  // minimum and maximum size of a contour lenght. We use the following formula
75  // minLenght= min ( _minSize_pix , _minSize* Is)*4
76  // maxLenght= _maxSize* Is*4
77  // being Is=max(imageWidth,imageHeight)
78  //the values _minSize and _maxSize are normalized, thus, depends on camera image size
79  //However, _minSize_pix is expressed in pixels and prevents a marker large enough, but relatively small to the image dimensions
80  //to be discarded. For instance, imagine a image of 6000x6000 and a marker of 100x100 in it.
81  // The marker is visible, but relatively small, so, we set a minimum size expressed in pixels to avoid discarding it
82  float _minSize, _maxSize;
84  Params(){
85  _thresMethod = ADPT_THRES;
86  _thresParam1 = _thresParam2 = 7;
87  _cornerMethod = LINES;
88 
89  _thresParam1_range = 0;
90  _markerWarpSize = 56;
91 
92  _minSize = 0.04;_maxSize = 0.5;_minSize_pix=25;
93  _borderDistThres = 0.005; // corners at a distance from image boundary nearer than 2.5% of image are ignored
94  _subpix_wsize=5;//window size employed for subpixel search (in vase you use _cornerMethod=SUBPIX
95  }
96 
97  };
98 
102  MarkerDetector();
103 
106  ~MarkerDetector();
118  std::vector<aruco::Marker> detect(const cv::Mat &input) throw(cv::Exception);
119  std::vector<aruco::Marker> detect(const cv::Mat &input,const CameraParameters &camParams, float markerSizeMeters , bool setYPerperdicular = false) throw(cv::Exception);
120 
131  void detect(const cv::Mat &input, std::vector< Marker > &detectedMarkers, CameraParameters camParams, float markerSizeMeters = -1,
132  bool setYPerperdicular = false) throw(cv::Exception);
133 
134 
147  void detect(const cv::Mat &input, std::vector< Marker > &detectedMarkers, cv::Mat camMatrix = cv::Mat(), cv::Mat distCoeff = cv::Mat(),
148  float markerSizeMeters = -1, bool setYPerperdicular = false) throw(cv::Exception);
149 
152  void setParams(Params p){_params =p;}
155  Params getParams()const {return _params;}
166  void setDictionary(std::string dict_type,float error_correction_rate=0)throw(cv::Exception);
167 
175  void setDictionary(Dictionary::DICT_TYPES dict_type,float error_correction_rate=0)throw(cv::Exception);
176 
177 
182  const cv::Mat &getThresholdedImage() { return thres; }
183 
184 
185  //Below this point, you are most probably not interested
186  //--- deprecated accesor modifiers ue the new setParams() and getParams() methods instead
190  void setThresholdMethod(ThresholdMethods m) { _params._thresMethod = m; }
193  ThresholdMethods getThresholdMethod() const { return _params._thresMethod; }
200  void setThresholdParams(double param1, double param2) {
201  _params._thresParam1 = param1;
202  _params._thresParam2 = param2;
203  }
204 
212  void setThresholdParamRange(size_t r1 = 0, size_t r2 = 0) {_params. _thresParam1_range = r1; (void)(r2); }
213 
220  void getThresholdParams(double &param1, double &param2) const {
221  param1 = _params._thresParam1;
222  param2 = _params._thresParam2;
223  }
224 
225 
226 
231  void setCornerRefinementMethod(CornerRefinementMethod method,int val=-1) { _params._cornerMethod = method; if (val!=-1)_params._subpix_wsize=val;}
234  CornerRefinementMethod getCornerRefinementMethod() const { return _params._cornerMethod; }
243  void setMinMaxSize(float min = 0.03, float max = 0.5) throw(cv::Exception){
244  if (min <= 0 || min > 1) throw cv::Exception(1, " min parameter out of range", "MarkerDetector::setMinMaxSize", __FILE__, __LINE__);
245  if (max <= 0 || max > 1) throw cv::Exception(1, " max parameter out of range", "MarkerDetector::setMinMaxSize", __FILE__, __LINE__);
246  if (min > max) throw cv::Exception(1, " min>max", "MarkerDetector::setMinMaxSize", __FILE__, __LINE__);
247  _params._minSize = min;
248  _params._maxSize = max;
249  }
250 
251 
258  void getMinMaxSize(float &min, float &max) {
259  min = _params._minSize;
260  max = _params._maxSize;
261  }
262 
263 
267  void setDesiredSpeed(int val){(void)(val);}
270  int getDesiredSpeed() const { return 0; }
271 
276  void setWarpSize(int val) throw(cv::Exception){
277  if (val < 10)
278  throw cv::Exception(1, " invalid canonical image size", "MarkerDetector::setWarpSize", __FILE__, __LINE__);
279  _params._markerWarpSize = val;
280  };
283  int getWarpSize() const { return _params._markerWarpSize; }
284 
285 
286 
287 
288 
289 
294 
295 
300  void setMarkerLabeler(cv::Ptr<MarkerLabeler> detector)throw(cv::Exception);
301  cv::Ptr<MarkerLabeler> getMarkerLabeler()throw(cv::Exception){ return markerIdDetector;}
302  // Represent a candidate to be a maker
303  class MarkerCandidate : public Marker {
304  public:
306  MarkerCandidate(const Marker &M) : Marker(M) {}
308  contour = M.contour;
309  idx = M.idx;
310  }
312  (*(Marker *)this) = (*(Marker *)&M);
313  contour = M.contour;
314  idx = M.idx;
315  return *this;
316  }
317 
318  vector< cv::Point > contour; // all the points of its contour
319  int idx; // index position in the global contour list
320  };
321 
325  void thresHold(int method, const cv::Mat &grey, cv::Mat &thresImg, double param1 = -1, double param2 = -1) throw(cv::Exception);
328  void adpt_threshold_multi(const cv::Mat &grey, std::vector<cv::Mat> &out, double param1 , double param1_range , double param2,double param2_range=0 );
333  void detectRectangles(const cv::Mat &thresImg, vector< std::vector< cv::Point2f > > &candidates);
334 
337  const vector< std::vector< cv::Point2f > > &getCandidates() { return _candidates; }
338 
347  bool warp(cv::Mat &in, cv::Mat &out, cv::Size size, std::vector< cv::Point2f > points) throw(cv::Exception);
348 
349 
350 
354  void refineCandidateLines(MarkerCandidate &candidate, const cv::Mat &camMatrix, const cv::Mat &distCoeff);
355 
356 
357 
358 
359  private:
360  bool warp_cylinder(cv::Mat &in, cv::Mat &out, cv::Size size, MarkerCandidate &mc) throw(cv::Exception);
365  void detectRectangles(vector< cv::Mat > &vimages, vector< MarkerCandidate > &candidates);
366  //operating params
368  // vectr of candidates to be markers. This is a vector with a set of rectangles that have no valid id
369  vector< std::vector< cv::Point2f > > _candidates;
370  // Images
371  cv::Mat grey, thres;
372  // pointer to the function that analizes a rectangular region so as to detect its internal marker
373  cv::Ptr<MarkerLabeler> markerIdDetector;
374 
377  bool isInto(cv::Mat &contour, std::vector< cv::Point2f > &b);
380  int perimeter(std::vector< cv::Point2f > &a);
381 
382  // auxiliar functions to perform LINES refinement
383  void interpolate2Dline(const vector< cv::Point2f > &inPoints, cv::Point3f &outLine);
384  cv::Point2f getCrossPoint(const cv::Point3f &line1, const cv::Point3f &line2);
385  void distortPoints(vector< cv::Point2f > in, vector< cv::Point2f > &out, const cv::Mat &camMatrix, const cv::Mat &distCoeff);
386 
387 
393  template < typename T > void removeElements(vector< T > &vinout, const vector< bool > &toRemove) {
394  // remove the invalid ones by setting the valid in the positions left by the invalids
395  size_t indexValid = 0;
396  for (size_t i = 0; i < toRemove.size(); i++) {
397  if (!toRemove[i]) {
398  if (indexValid != i)
399  vinout[indexValid] = vinout[i];
400  indexValid++;
401  }
402  }
403  vinout.resize(indexValid);
404  }
405 
406  // graphical debug
407  void drawApproxCurve(cv::Mat &in, std::vector< cv::Point > &approxCurve, cv::Scalar color);
408  void drawContour(cv::Mat &in, std::vector< cv::Point > &contour, cv::Scalar);
409  void drawAllContours(cv::Mat input, std::vector< std::vector< cv::Point > > &contours);
410  void draw(cv::Mat out, const std::vector< Marker > &markers);
411  // method to refine corner detection in case the internal border after threshold is found
412  // This was tested in the context of chessboard methods
413  void findCornerMaxima(vector< cv::Point2f > &Corners, const cv::Mat &grey, int wsize);
414 
415 
416 
417  template < typename T > void joinVectors(vector< vector< T > > &vv, vector< T > &v, bool clearv = false) {
418  if (clearv)
419  v.clear();
420  for (size_t i = 0; i < vv.size(); i++)
421  for (size_t j = 0; j < vv[i].size(); j++)
422  v.push_back(vv[i][j]);
423  }
424 
425  vector<cv::Mat > imagePyramid;
426 };
427 };
428 #endif
void setThresholdParams(double param1, double param2)
void getMinMaxSize(float &min, float &max)
#define ARUCO_EXPORTS
Definition: exports.h:42
NONE
void setCornerRefinementMethod(CornerRefinementMethod method, int val=-1)
void removeElements(vector< T > &vinout, const vector< bool > &toRemove)
cv::Ptr< MarkerLabeler > getMarkerLabeler()
CornerRefinementMethod getCornerRefinementMethod() const
MarkerCandidate & operator=(const MarkerCandidate &M)
void setThresholdParamRange(size_t r1=0, size_t r2=0)
void setParams(Params p)
vector< cv::Mat > imagePyramid
MarkerCandidate(const MarkerCandidate &M)
void setMinMaxSize(float min=0.03, float max=0.5)
void setWarpSize(int val)
This class represents a marker. It is a vector of the fours corners ot the marker.
Definition: marker.h:42
Main class for marker detection.
const cv::Mat & getThresholdedImage()
Parameters of the camera.
void getThresholdParams(double &param1, double &param2) const
ThresholdMethods getThresholdMethod() const
int min(int a, int b)
Params getParams() const
void joinVectors(vector< vector< T > > &vv, vector< T > &v, bool clearv=false)
cv::Ptr< MarkerLabeler > markerIdDetector
CornerRefinementMethod _cornerMethod
void setThresholdMethod(ThresholdMethods m)
void setDesiredSpeed(int val)
int getDesiredSpeed() const
vector< std::vector< cv::Point2f > > _candidates


tuw_aruco
Author(s): Lukas Pfeifhofer
autogenerated on Mon Feb 28 2022 23:57:56