00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef MARKER_H
00025 #define MARKER_H
00026
00034 #include "Alvar.h"
00035 #include <iostream>
00036 #include <algorithm>
00037 #include "Util.h"
00038 #include "Camera.h"
00039 #include "Pose.h"
00040 #include "Bitset.h"
00041 #include <vector>
00042 #include "ar_track_alvar/kinect_filtering.h"
00043
00044 namespace alvar {
00045
00051 class ALVAR_EXPORT Marker
00052 {
00053 protected:
00054 void VisualizeMarkerPose(IplImage *image, Camera *cam, double visualize2d_points[12][2], CvScalar color=CV_RGB(255,0,0)) const;
00055 virtual void VisualizeMarkerContent(IplImage *image, Camera *cam, double datatext_point[2], double content_point[2]) const;
00056 virtual void VisualizeMarkerError(IplImage *image, Camera *cam, double errortext_point[2]) const;
00057 bool UpdateContentBasic(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, IplImage *gray, Camera *cam, int frame_no = 0);
00058
00059 public:
00060 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00061 bool valid;
00062
00069 void CompareCorners(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, int *orientation, double *error);
00072 void CompareContent(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, IplImage *gray, Camera *cam, int *orientation) const;
00075 virtual bool UpdateContent(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, IplImage *gray, Camera *cam, int frame_no = 0);
00078 void UpdatePose(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, Camera *cam, int orientation, int frame_no = 0, bool update_pose = true);
00082 virtual bool DecodeContent(int *orientation);
00083
00086 CvMat *GetContent() const {
00087 return marker_content;
00088 }
00091 void SaveMarkerImage(const char *filename, int save_res = 0) const;
00094 void ScaleMarkerToImage(IplImage *image) const;
00097 void Visualize(IplImage *image, Camera *cam, CvScalar color=CV_RGB(255,0,0)) const;
00099 void SetMarkerSize(double _edge_length = 0, int _res = 0, double _margin = 0);
00101 double GetMarkerEdgeLength() const { return edge_length; }
00103 ~Marker();
00109 Marker(double _edge_length = 0, int _res = 0, double _margin = 0);
00111 Marker(const Marker& m);
00117 virtual unsigned long GetId() const { return 0; }
00118 virtual void SetId(unsigned long _id) {};
00119
00125 int GetRes() const { return res; }
00126
00131 double GetMargin() const { return margin; }
00132
00135 Pose pose;
00143 double GetError(int errors = (MARGIN_ERROR | DECODE_ERROR)) const {
00144 int count = 0;
00145 double error = 0;
00146 if (errors & MARGIN_ERROR) {error+=margin_error; count++;}
00147 if (errors & DECODE_ERROR) {error+=decode_error; count++;}
00148 if (errors & TRACK_ERROR) {error+=track_error; count++;}
00149 return error/count;
00150 }
00152 void SetError(int error_type, double value) {
00153 if (error_type == MARGIN_ERROR) margin_error = value;
00154 else if (error_type == DECODE_ERROR) decode_error = value;
00155 else if (error_type == TRACK_ERROR) track_error = value;
00156 }
00157 static const int MARGIN_ERROR=1;
00158 static const int DECODE_ERROR=2;
00159 static const int TRACK_ERROR=4;
00160 protected:
00161 double margin_error;
00162 double decode_error;
00163 double track_error;
00164 double edge_length;
00165 int res;
00166 double margin;
00167 CvMat *marker_content;
00168
00169 public:
00170
00172 std::vector<PointDouble> marker_points;
00174 std::vector<PointDouble> marker_corners;
00176 std::vector<PointDouble> marker_corners_img;
00178 std::vector<PointDouble> ros_marker_points_img;
00179 ar_track_alvar::ARCloud ros_corners_3D;
00180 int ros_orientation;
00182 std::vector<PointDouble> marker_margin_w;
00184 std::vector<PointDouble> marker_margin_b;
00185 #ifdef VISUALIZE_MARKER_POINTS
00186 std::vector<PointDouble> marker_allpoints_img;
00187 #endif
00188 };
00189
00193 class ALVAR_EXPORT MarkerArtoolkit : public Marker
00194 {
00195 protected:
00196 int default_res() { std::cout<<"MarkerArtoolkit::default_res"<<std::endl; return 3; }
00197 double default_margin() { return 1.5; }
00198
00199 public:
00200 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00202 unsigned long id;
00204 MarkerArtoolkit(double _edge_length = 0, int _res = 0, double _margin = 0) :
00205 Marker(_edge_length, (_res?_res:3), (_margin?_margin:1.5))
00206 {
00207 }
00209 unsigned long GetId() const { return id; }
00210 void SetId(unsigned long _id) { id = _id; }
00212 bool DecodeContent(int *orientation);
00214 void SetContent(unsigned long _id);
00215 };
00216
00220 class ALVAR_EXPORT MarkerData : public Marker
00221 {
00222 protected:
00223 virtual void VisualizeMarkerContent(IplImage *image, Camera *cam, double datatext_point[2], double content_point[2]) const;
00224 void DecodeOrientation(int *error, int *total, int *orientation);
00225 int DecodeCode(int orientation, BitsetExt *bs, int *erroneous, int *total, unsigned char* content_type);
00226 void Read6bitStr(BitsetExt *bs, char *s, size_t s_max_len);
00227 void Add6bitStr(BitsetExt *bs, char *s);
00228 int UsableDataBits(int marker_res, int hamming);
00229 bool DetectResolution(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, IplImage *gray, Camera *cam);
00230
00231 public:
00232 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00233 static const int MAX_MARKER_STRING_LEN=2048;
00234 enum MarkerContentType {
00235 MARKER_CONTENT_TYPE_NUMBER,
00236 MARKER_CONTENT_TYPE_STRING,
00237 MARKER_CONTENT_TYPE_FILE,
00238 MARKER_CONTENT_TYPE_HTTP
00239 };
00240 unsigned char content_type;
00241
00243 union {
00244 unsigned long id;
00245 char str[MAX_MARKER_STRING_LEN];
00246 } data;
00247
00253 MarkerData(double _edge_length = 0, int _res = 0, double _margin = 0) :
00254 Marker(_edge_length, _res, (_margin?_margin:2))
00255 {
00256 }
00258 unsigned long GetId() const { return data.id; }
00260 void SetId(unsigned long _id) { data.id = _id; }
00265 virtual bool UpdateContent(std::vector<Point<CvPoint2D64f> > &_marker_corners_img, IplImage *gray, Camera *cam, int frame_no = 0);
00268 bool DecodeContent(int *orientation);
00271 void SetContent(MarkerContentType content_type, unsigned long id, const char *str, bool force_strong_hamming=false, bool verbose=false);
00272 };
00273
00276 class ALVAR_EXPORT MarkerIterator : public std::iterator<std::forward_iterator_tag, Marker*> {
00277 public:
00278 virtual bool operator==(const MarkerIterator& other) = 0;
00279 virtual bool operator!=(const MarkerIterator& other) = 0;
00280 virtual MarkerIterator& operator++() = 0;
00281 virtual const Marker* operator*() = 0;
00282 virtual const Marker* operator->() = 0;
00283 virtual MarkerIterator& reset() = 0;
00284
00285 void *_data;
00286 };
00287
00292 template<typename T>
00293 class ALVAR_EXPORT MarkerIteratorImpl : public MarkerIterator {
00294 public:
00295 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00296 MarkerIteratorImpl(typename std::vector<T>::const_iterator i) : _begin(i), _i(i) {
00297 _data = this;
00298 }
00299
00300 ~MarkerIteratorImpl() {}
00301
00302
00303 MarkerIteratorImpl& operator=(const MarkerIteratorImpl& other) {
00304 _i = other._i;
00305 return(*this);
00306 }
00307
00308 bool operator==(const MarkerIterator& other) {
00309 MarkerIteratorImpl* pother = (MarkerIteratorImpl*)other._data;
00310 return (_i == pother->_i);
00311 }
00312
00313 bool operator!=(const MarkerIterator& other) {
00314 MarkerIteratorImpl* pother = (MarkerIteratorImpl*)other._data;
00315 return (_i != pother->_i);
00316 }
00317
00318 MarkerIterator& operator++() {
00319 _i++;
00320 return(*this);
00321 }
00322
00323 const Marker* operator*() {
00324 return &(*_i);
00325 }
00326
00327 const Marker* operator->() {
00328 return &(*_i);
00329 }
00330
00331 MarkerIterator& reset() {
00332 _i = _begin;
00333 return (*this);
00334 }
00335
00336 private:
00337 typename std::vector<T>::const_iterator _begin;
00338 typename std::vector<T>::const_iterator _i;
00339 };
00340
00341 }
00342
00343 #endif