00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _ARUCO_MarkerDetector_H
00029 #define _ARUCO_MarkerDetector_H
00030 #include <opencv2/core/core.hpp>
00031 #include <cstdio>
00032 #include <iostream>
00033 #include "cameraparameters.h"
00034 #include "exports.h"
00035 #include "marker.h"
00036 using namespace std;
00037
00038 namespace aruco {
00039
00043 class ARUCO_EXPORTS MarkerDetector {
00044
00045 class MarkerCandidate : public Marker {
00046 public:
00047 MarkerCandidate() {}
00048 MarkerCandidate(const Marker &M) : Marker(M) {}
00049 MarkerCandidate(const MarkerCandidate &M) : Marker(M) {
00050 contour = M.contour;
00051 idx = M.idx;
00052 }
00053 MarkerCandidate &operator=(const MarkerCandidate &M) {
00054 (*(Marker *)this) = (*(Marker *)&M);
00055 contour = M.contour;
00056 idx = M.idx;
00057 return *this;
00058 }
00059
00060 vector< cv::Point > contour;
00061 int idx;
00062 };
00063
00064 public:
00068 MarkerDetector();
00069
00072 ~MarkerDetector();
00073
00085 void detect(const cv::Mat &input, std::vector< Marker > &detectedMarkers, cv::Mat camMatrix = cv::Mat(), cv::Mat distCoeff = cv::Mat(),
00086 float markerSizeMeters = -1, bool setYPerperdicular = false) throw(cv::Exception);
00097 void detect(const cv::Mat &input, std::vector< Marker > &detectedMarkers, CameraParameters camParams, float markerSizeMeters = -1,
00098 bool setYPerperdicular = false) throw(cv::Exception);
00099
00103 enum ThresholdMethods { FIXED_THRES, ADPT_THRES, CANNY };
00104
00105
00106
00109 void setThresholdMethod(ThresholdMethods m) { _thresMethod = m; }
00112 ThresholdMethods getThresholdMethod() const { return _thresMethod; }
00119 void setThresholdParams(double param1, double param2) {
00120 _thresParam1 = param1;
00121 _thresParam2 = param2;
00122 }
00123
00130 void setThresholdParamRange(size_t r1 = 0, size_t r2 = 0) { _thresParam1_range = r1; }
00142 void enableLockedCornersMethod(bool enable);
00143
00150 void getThresholdParams(double ¶m1, double ¶m2) const {
00151 param1 = _thresParam1;
00152 param2 = _thresParam2;
00153 }
00154
00155
00159 const cv::Mat &getThresholdedImage() { return thres; }
00162 enum CornerRefinementMethod { NONE, HARRIS, SUBPIX, LINES };
00165 void setCornerRefinementMethod(CornerRefinementMethod method) { _cornerMethod = method; }
00168 CornerRefinementMethod getCornerRefinementMethod() const { return _cornerMethod; }
00175 void setMinMaxSize(float min = 0.03, float max = 0.5) throw(cv::Exception);
00176
00182 void getMinMaxSize(float &min, float &max) {
00183 min = _minSize;
00184 max = _maxSize;
00185 }
00186
00192 void enableErosion(bool enable) {}
00193
00201 void setDesiredSpeed(int val);
00204 int getDesiredSpeed() const { return _speed; }
00205
00210 void setWarpSize(int val) throw(cv::Exception);
00211 ;
00214 int getWarpSize() const { return _markerWarpSize; }
00215
00232 void setMakerDetectorFunction(int (*markerdetector_func)(const cv::Mat &in, int &nRotations)) { markerIdDetector_ptrfunc = markerdetector_func; }
00233
00242 void pyrDown(unsigned int level) {}
00243
00248
00252 void thresHold(int method, const cv::Mat &grey, cv::Mat &thresImg, double param1 = -1, double param2 = -1) throw(cv::Exception);
00257 void detectRectangles(const cv::Mat &thresImg, vector< std::vector< cv::Point2f > > &candidates);
00258
00261 const vector< std::vector< cv::Point2f > > &getCandidates() { return _candidates; }
00262
00270 bool warp(cv::Mat &in, cv::Mat &out, cv::Size size, std::vector< cv::Point2f > points) throw(cv::Exception);
00271
00272
00273
00277 void refineCandidateLines(MarkerCandidate &candidate, const cv::Mat &camMatrix, const cv::Mat &distCoeff);
00278
00279
00294 static void glGetProjectionMatrix(CameraParameters &CamMatrix, cv::Size orgImgSize, cv::Size size, double proj_matrix[16], double gnear, double gfar,
00295 bool invert = false) throw(cv::Exception);
00296
00297 private:
00298 bool warp_cylinder(cv::Mat &in, cv::Mat &out, cv::Size size, MarkerCandidate &mc) throw(cv::Exception);
00303 void detectRectangles(vector< cv::Mat > &vimages, vector< MarkerCandidate > &candidates);
00304
00305 ThresholdMethods _thresMethod;
00306
00307 double _thresParam1, _thresParam2, _thresParam1_range;
00308
00309 CornerRefinementMethod _cornerMethod;
00310
00311 float _minSize, _maxSize;
00312
00313
00314 bool _useLockedCorners;
00315
00316
00317 int _speed;
00318 int _markerWarpSize;
00319 float _borderDistThres;
00320
00321 vector< std::vector< cv::Point2f > > _candidates;
00322
00323 cv::Mat grey, thres;
00324
00325 int (*markerIdDetector_ptrfunc)(const cv::Mat &in, int &nRotations);
00326
00329 bool isInto(cv::Mat &contour, std::vector< cv::Point2f > &b);
00332 int perimeter(std::vector< cv::Point2f > &a);
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 void findBestCornerInRegion_harris(const cv::Mat &grey, vector< cv::Point2f > &Corners, int blockSize);
00346
00347
00348
00349 void interpolate2Dline(const vector< cv::Point2f > &inPoints, cv::Point3f &outLine);
00350 cv::Point2f getCrossPoint(const cv::Point3f &line1, const cv::Point3f &line2);
00351 void distortPoints(vector< cv::Point2f > in, vector< cv::Point2f > &out, const cv::Mat &camMatrix, const cv::Mat &distCoeff);
00352
00353
00359 template < typename T > void removeElements(vector< T > &vinout, const vector< bool > &toRemove) {
00360
00361 size_t indexValid = 0;
00362 for (size_t i = 0; i < toRemove.size(); i++) {
00363 if (!toRemove[i]) {
00364 if (indexValid != i)
00365 vinout[indexValid] = vinout[i];
00366 indexValid++;
00367 }
00368 }
00369 vinout.resize(indexValid);
00370 }
00371
00372
00373 void drawApproxCurve(cv::Mat &in, std::vector< cv::Point > &approxCurve, cv::Scalar color);
00374 void drawContour(cv::Mat &in, std::vector< cv::Point > &contour, cv::Scalar);
00375 void drawAllContours(cv::Mat input, std::vector< std::vector< cv::Point > > &contours);
00376 void draw(cv::Mat out, const std::vector< Marker > &markers);
00377
00378
00379 void findCornerMaxima(vector< cv::Point2f > &Corners, const cv::Mat &grey, int wsize);
00380
00381
00382
00383 template < typename T > void joinVectors(vector< vector< T > > &vv, vector< T > &v, bool clearv = false) {
00384 if (clearv)
00385 v.clear();
00386 for (size_t i = 0; i < vv.size(); i++)
00387 for (size_t j = 0; j < vv[i].size(); j++)
00388 v.push_back(vv[i][j]);
00389 }
00390 };
00391 };
00392 #endif