188         DoHandleTest(
int _type_id=-1, 
bool _needs_has_p2d=
false, 
bool _needs_has_p3d=
false) 
   189                 : type_id(_type_id), needs_has_p2d(_needs_has_p2d), needs_has_p3d(_needs_has_p3d) {}
   191                 if (needs_has_p2d && !f.has_p2d) 
return false;
   192                 if (needs_has_p3d && !f.has_p3d) 
return false;
   194                 if ((type_id != -1) && (type_id != f.type_id)) 
return false;
   213         DoEraseTest(
bool _erase_without_p2d, 
bool _erase_without_p3d, 
int _type_id=-1) 
   214                 : type_id(_type_id), erase_without_p2d(_erase_without_p2d), erase_without_p3d(_erase_without_p3d), 
   215                   test_reprojection(false), limit_sq(0.
f) {}
   216         DoEraseTest(
float _limit, 
bool _erase_without_p2d=
false, 
bool _erase_without_p3d=
false, 
int _type_id=-1) 
   217                 : type_id(_type_id), erase_without_p2d(_erase_without_p2d), erase_without_p3d(_erase_without_p3d),
   218                   test_reprojection(true), limit_sq(_limit*_limit) {}
   220                 if ((type_id != -1) && (type_id != f.type_id)) 
return false;
   221                 if (erase_without_p2d && !f.has_p2d) 
return true;
   222                 if (erase_without_p3d && !f.has_p3d) 
return true;
   223                 if (test_reprojection) {
   224                         if (!f.has_p2d) 
return false;
   225                         if (!f.has_p3d) 
return false;
   227                         double dist_sq = (f.p2d.x-f.projected_p2d.x)*(f.p2d.x-f.projected_p2d.x);
   228                         dist_sq       += (f.p2d.y-f.projected_p2d.y)*(f.p2d.y-f.projected_p2d.y);
   229                         if (dist_sq > limit_sq) 
   237 template<
typename T, 
typename F>
   240         typename std::map<int,T>::iterator iter = container.begin();
   241         while(iter != container.end()) {
   243                 if (do_erase_test(f)) {
   244                         container.erase(iter++);
   257         TrackerFeaturesEC(
int _max_features=100, 
int _min_features=90, 
double _quality_level=0.01, 
double _min_distance=10, 
int _pyr_levels=4, 
int win_size=6)
   258                 : 
TrackerFeatures(_max_features, _min_features, _quality_level, _min_distance, _pyr_levels, win_size), purge(false) {}
   262         bool Track(IplImage *img, IplImage *mask, std::map<int,T> &container, 
int type_id=-1, 
int first_id=-1, 
int last_id=-1)
   266                 return Track(img, mask, container, do_handle_test_default, 
type_id, first_id, last_id);
   310         template<
typename T, 
typename F>
   311         bool Track(IplImage *img, IplImage *mask, std::map<int,T> &container, F do_handle_test, 
int type_id=0, 
int first_id=-1, 
int last_id=-1)
   314                 if (first_id < 0) last_id = -1;
   316                 typename std::map<int,T>::iterator iter = container.begin();
   317                 typename std::map<int,T>::iterator iter_end = container.end();
   319                 for (;iter != iter_end; iter++) {
   321                         if (!do_handle_test(f)) 
continue;
   322                         if (f.has_p2d != 
true) 
continue;
   324                         features[feature_count] = f.p2d;
   325                         ids[feature_count] = iter->first;
   327                         if (feature_count == max_features) 
break;
   336                         TrackHid(img, mask, 
false);
   339                         if (next_id < first_id) next_id = first_id;
   340                         if (next_id > last_id) 
return false; 
   342                         TrackHid(img, mask, 
true);
   345                 for (
int i=0; i<feature_count; i++) {
   347                         if (last_id >= 0 && 
id >= last_id) 
break;
   348                         T &
f = container[id];
   362                 for (
int i=0; i<feature_count; i++) {
   364                         if (last_id >= 0 && 
id >= last_id) 
break;
   365                         T &
f = container[id];
   398                 return Undistort(container, do_handle_test_default);
   401         template<
typename T, 
typename F>
   402         void Undistort(std::map<int,T> &container, F &do_handle_test) {
   403                 typename std::map<int,T>::iterator iter = container.begin();
   404                 typename std::map<int,T>::iterator iter_end = container.end();
   405                 for (;iter != iter_end; iter++) {
   407                         if (!do_handle(f)) 
continue;
   408                         if (f.has_p2d) Undistort(f.p2d);
   415                 return Distort(container, do_handle_test_default);
   418         template<
typename T, 
typename F>
   419         void Distort(std::map<int,T> &container, F &do_handle_test) {
   420                 typename std::map<int,T>::iterator iter = container.begin();
   421                 typename std::map<int,T>::iterator iter_end = container.end();
   422                 for (;iter != iter_end; iter++) {
   424                         if (!do_handle(f)) 
continue;
   425                         if (f.has_p2d) Distort(f.p2d);
   432                 return CalcExteriorOrientation(container, pose, do_handle_test_default);
   435         template<
typename T, 
typename F>
   437                 int count_points = container.size();
   438                 if(count_points < 4) 
return false;
   439                 CvMat* world_points = cvCreateMat(count_points, 1, CV_32FC3);
   440                 CvMat* image_observations = cvCreateMat(count_points*2, 1, CV_32FC2);
   441                 typename std::map<int,T>::iterator iter = container.begin();
   442                 typename std::map<int,T>::iterator iter_end = container.end();
   444                 for (;iter != iter_end; iter++) {
   446                         if (!do_handle_test(f)) 
continue;
   447                         if (f.has_p2d && f.has_p3d) {
   448                                 world_points->data.fl[ind*3+0] = (float)f.p3d.x;
   449                                 world_points->data.fl[ind*3+1] = (
float)f.p3d.y;
   450                                 world_points->data.fl[ind*3+2] = (float)f.p3d.z;
   451                                 image_observations->data.fl[ind*2+0]  = (
float)f.p2d.x;
   452                                 image_observations->data.fl[ind*2+1]  = (float)f.p2d.y;
   456                 if (ind<4) 
return false;
   458                 CvRect 
r; r.x = 0; r.y = 0; r.height = ind; r.width = 1;
   459                 CvMat world_points_sub;
   460                 cvGetSubRect(world_points, &world_points_sub, r);
   461                 CvMat image_observations_sub;
   462                 cvGetSubRect(image_observations, &image_observations_sub, r);
   466                 cvReleaseMat(&image_observations);
   467                 cvReleaseMat(&world_points);
   475                 return UpdatePose(container, pose, do_handle_test_default, weights);
   481                 return UpdateRotation(container, pose, do_handle_test_default);
   484         template<
typename T, 
typename F>
   486                 int count_points = container.size();
   487                 if(count_points < 6) 
return false;
   489                 CvMat* world_points = cvCreateMat(count_points, 1, CV_64FC3);
   490                 CvMat* image_observations = cvCreateMat(count_points*2, 1, CV_64F); 
   493                 typename std::map<int,T>::iterator iter = container.begin();
   494                 typename std::map<int,T>::iterator iter_end = container.end();
   495                 for (;iter != iter_end; iter++) {
   497                         if (!do_handle_test(f)) 
continue;
   498                         if (f.has_p2d && f.has_p3d) {
   499                                 world_points->data.db[ind*3+0] = f.p3d.x;
   500                                 world_points->data.db[ind*3+1] = f.p3d.y;
   501                                 world_points->data.db[ind*3+2] = f.p3d.z;
   502                                 image_observations->data.db[ind*2+0] = f.p2d.x;
   503                                 image_observations->data.db[ind*2+1] = f.p2d.y;
   507                 if (ind < 6) 
return false;
   509                 CvRect 
r; r.x = 0; r.y = 0; r.height = ind; r.width = 1;
   510                 CvMat world_points_sub;
   511                 cvGetSubRect(world_points, &world_points_sub, r);
   514                 CvMat image_observations_sub;
   515                 cvGetSubRect(image_observations, &image_observations_sub, r);
   517                 bool ret = UpdateRotation(&world_points_sub, &image_observations_sub, pose);
   519                 cvReleaseMat(&image_observations);
   520                 cvReleaseMat(&world_points);
   525         template<
typename T, 
typename F>
   526         bool UpdatePose(std::map<int,T> &container, 
Pose *pose, F do_handle_test, std::map<int,double> *weights=0) {
   527                 int count_points = container.size();
   528                 if(count_points < 4) 
return false; 
   530                 CvMat* world_points = cvCreateMat(count_points, 1, CV_64FC3);
   531                 CvMat* image_observations = cvCreateMat(count_points*2, 1, CV_64F); 
   533                 if(weights) w = cvCreateMat(count_points*2, 1, CV_64F);
   536                 typename std::map<int,T>::iterator iter = container.begin();
   537                 typename std::map<int,T>::iterator iter_end = container.end();
   538                 for (;iter != iter_end; iter++) {
   540                         if (!do_handle_test(f)) 
continue;
   541                         if (f.has_p2d && f.has_p3d) {
   542                                 world_points->data.db[ind*3+0] = f.p3d.x;
   543                                 world_points->data.db[ind*3+1] = f.p3d.y;
   544                                 world_points->data.db[ind*3+2] = f.p3d.z;
   545                                 image_observations->data.db[ind*2+0] = f.p2d.x;
   546                                 image_observations->data.db[ind*2+1] = f.p2d.y;
   549                                         w->data.db[ind*2+1] = w->data.db[ind*2+0] = (*weights)[iter->first];
   553                 if (ind < 4) 
return false; 
   555                 CvRect 
r; r.x = 0; r.y = 0; r.height = ind; r.width = 1;
   556                 CvMat world_points_sub;
   557                 cvGetSubRect(world_points, &world_points_sub, r);
   560                 CvMat image_observations_sub;
   561                 cvGetSubRect(image_observations, &image_observations_sub, r);
   566                         cvGetSubRect(w, &w_sub, r);
   567                         ret = UpdatePose(&world_points_sub, &image_observations_sub, pose, &w_sub);
   570                         ret = UpdatePose(&world_points_sub, &image_observations_sub, pose);
   572                 cvReleaseMat(&image_observations);
   573                 cvReleaseMat(&world_points);
   574                 if(w) cvReleaseMat(&w);
   581         float Reproject(std::map<int,T> &container, 
Pose *pose, 
int type_id=-1, 
bool needs_has_p2d=
false, 
bool needs_has_p3d=
false, 
float average_outlier_limit=0.f)
   584                 return Reproject(container, pose, do_handle_test, average_outlier_limit);
   587         template<
typename T, 
typename F>
   588         float Reproject(std::map<int,T> &container, 
Pose *pose, F do_handle_test, 
float average_outlier_limit=0.f)
   590                 float reprojection_sum=0.f;
   591                 int   reprojection_count=0;
   592                 float limit_sq = average_outlier_limit*average_outlier_limit;
   593                 typename std::map<int,T>::iterator iter = container.begin();
   594                 typename std::map<int,T>::iterator iter_end = container.end();
   595                 for(;iter != iter_end;iter++) {
   597                         if (!do_handle_test(f)) 
continue;
   602                         float dist_sq = (f.p2d.x-f.projected_p2d.x)*(f.p2d.x-f.projected_p2d.x);
   603                         dist_sq       += (f.p2d.y-f.projected_p2d.y)*(f.p2d.y-f.projected_p2d.y);
   604                         if ((limit_sq == 0) || (dist_sq < limit_sq)) {
   605                                 reprojection_sum += sqrt(dist_sq);
   606                                 reprojection_count++;
   609                 if (reprojection_count == 0) 
return 0.f;
   610                 return reprojection_sum/reprojection_count;
   620                 if (pose) Reproject(container, pose, 
type_id, 
false, 
false);
   626         bool UpdateRotation(
const CvMat* object_points, CvMat* image_points, 
Pose *pose);
   629         bool UpdateRotation(
const CvMat* object_points, CvMat* image_points, CvMat *rot, CvMat *tra);
   632         bool UpdatePose(
const CvMat* object_points, CvMat* image_points, 
Pose *pose, CvMat *weights=0);
   635         bool UpdatePose(
const CvMat* object_points, CvMat* image_points, CvMat *rodriques, CvMat *tra, CvMat *weights=0);
   638         bool ReconstructFeature(
const Pose *pose1, 
const Pose *pose2, 
const CvPoint2D32f *u1, 
const CvPoint2D32f *u2, CvPoint3D32f *
p3d, 
double limit);
   641         void Get3dOnPlane(
const Pose *pose, CvPoint2D32f 
p2d, CvPoint3D32f &p3d);
   644         void Get3dOnDepth(
const Pose *pose, CvPoint2D32f p2d, 
float depth, CvPoint3D32f &p3d);
   649         int id = first_id + marker_id*4 + corner_id;
   650         if (
id > last_id) 
return -1;
   660                 return PreDetect(p.second, type_id);
   664                 if (p.type_id != type_id) 
return false;
   669         int GetId(
int marker_id, 
int corner_id, 
int first_id=0, 
int last_id=65535) {
   677                            std::map<int,T> &container,
   685                            LabelingMethod labeling_method=CVSEQ)
   690                 typename std::map<int,T>::iterator iter = container.begin();
   691                 typename std::map<int,T>::iterator iter_end = container.end();
   692                 for (;iter != iter_end; iter++) {
   694                         if (f.type_id != 
type_id) 
continue;
   702                 for (
size_t i=0; i<MarkerDetector<M>::markers->size(); i++) {
   704                         for (
int corner=0; corner<4; corner++) {
   707                                         T &
f = container[id];
   710                                         f.p2d.x = float(m.marker_corners_img[corner].x);
   711                                         f.p2d.y = float(m.marker_corners_img[corner].y);
   720         void MarkerToEC(std::map<int,T> &container, 
int marker_id, 
double edge_length, 
Pose &pose, 
int type_id=0, 
int first_id=0,
int last_id=65535) {
   721                 CvMat *m3 = cvCreateMat(4,4,CV_64F); cvSetIdentity(m3);
   724                 for(
size_t corner = 0; corner < 4; ++corner)
   728                         double X_data[4] = {0, 0, 0, 1};
   730                                 X_data[0] = -0.5*edge_length;
   731                                 X_data[1] = -0.5*edge_length;
   732                         } 
else if (corner == 1) {
   733                                 X_data[0] = +0.5*edge_length;
   734                                 X_data[1] = -0.5*edge_length;
   735                         } 
else if (corner == 2) {
   736                                 X_data[0] = +0.5*edge_length;
   737                                 X_data[1] = +0.5*edge_length;
   738                         } 
else if (corner == 3) {
   739                                 X_data[0] = -0.5*edge_length;
   740                                 X_data[1] = +0.5*edge_length;
   743                         CvMat X  = cvMat(4, 1, CV_64F, X_data);
   744                         cvMatMul(m3, &X, &X);
   747                         T &
f = container[id];
   749                         f.p3d.x = float(X_data[0] / X_data[3]);
   750                         f.p3d.y = float(X_data[1] / X_data[3]);
   751                         f.p3d.z = float(X_data[2] / X_data[3]);
   765                 for (
size_t i = 0; i < marker_indices.size(); i++) {
   766                         if (marker_status[i] == 0) 
continue; 
   767                         int marker_id = marker_indices[i];
   768                         for (
int corner = 0; corner < 4; corner++) {
   771                                         int pc_index =  pointcloud_index(marker_id, corner);
   772                                         T &
f = container[id];
   774                                         f.p3d.x = float(pointcloud[pc_index].
x);
   775                                         f.p3d.y = float(pointcloud[pc_index].
y);
   776                                         f.p3d.z = float(pointcloud[pc_index].
z);
   793                 if (!MarkersFromEC(container, 
type_id, first_id, last_id)) 
return false;
   802                 return MarkersToEC(container, 
type_id, first_id, last_id);
 double max_new_marker_error
This file implements a camera used for projecting points and computing homographies. 
bool UpdatePose(std::map< int, T > &container, Pose *pose, int type_id=-1, std::map< int, double > *weights=0)
Update the pose using the items with matching type_id. 
bool DelFeatureId(int id)
void Undistort(std::map< int, T > &container, F &do_handle_test)
Undistort the items matching the given functor. 
bool MarkersFromEC(std::map< int, T > &container, int type_id=0, int first_id=0, int last_id=65535)
This is a default functor for testing which items in the container should be handled by each method...
bool AddFeatures(std::map< int, T > &container, int type_id=0, int first_id=0, int last_id=65535)
add features to the previously tracked frame if there are less than min_features 
Version of Camera using external container. 
This file implements a generic marker detector. 
bool Track(IplImage *img, IplImage *mask, std::map< int, T > &container, int type_id=-1, int first_id=-1, int last_id=-1)
Track features with matching type id. New features will have id's in the specified id range...
int EraseNonTracked(std::map< int, T > &container, int type_id=-1)
Erases the items matching with type_id having has_p2d == false . If type_id == -1 doesn't test the ty...
ExternalContainer(const ExternalContainer &c)
DoEraseTest(float _limit, bool _erase_without_p2d=false, bool _erase_without_p3d=false, int _type_id=-1)
Base class for using MultiMarker. 
TFSIMD_FORCE_INLINE const tfScalar & y() const 
float Reproject(std::map< int, T > &container, Pose *pose, int type_id=-1, bool needs_has_p2d=false, bool needs_has_p3d=false, float average_outlier_limit=0.f)
Projects p3d in the items matching with type_id into projected_p2d . If type_id == -1 doesn't test th...
Simple Camera class for calculating distortions, orientation or projections with pre-calibrated camer...
double Reset(IplImage *img, IplImage *mask)
int Purge()
Purge features that are considerably closer than the defined min_distance. 
TrackerFeaturesEC(int _max_features=100, int _min_features=90, double _quality_level=0.01, double _min_distance=10, int _pyr_levels=4, int win_size=6)
Constructor. 
void Distort(std::map< int, T > &container, int type_id=-1)
Distort the items with matching type_id. 
bool PreDetect(T &p, int type_id)
DoHandleTest(int _type_id=-1, bool _needs_has_p2d=false, bool _needs_has_p3d=false)
This is default functor for testing which items in the container should be erased. 
Version of MarkerDetector using external container. 
Version of MultiMarker using external container. 
void Purge()
Purge features that are considerably closer than the defined min_distance. 
int GetId(int marker_id, int corner_id, int first_id=0, int last_id=65535)
bool Track(IplImage *img, IplImage *mask, std::map< int, T > &container, F do_handle_test, int type_id=0, int first_id=-1, int last_id=-1)
Track features matching the given functor. New features will have id's in the specified id range...
int AddFeatures(IplImage *mask=NULL)
add features to the previously tracked frame if there are less than min_features 
MarkerDetector for detecting markers of type M 
void MarkerToEC(std::map< int, T > &container, int marker_id, double edge_length, Pose &pose, int type_id=0, int first_id=0, int last_id=65535)
Fill in 3D-coordinates for marker_id marker corners using edge_length and pose. 
DoEraseTest(bool _erase_without_p2d, bool _erase_without_p3d, int _type_id=-1)
void Undistort(std::map< int, T > &container, int type_id=-1)
Undistort the items with matching type_id. 
bool Save(std::map< int, T > &container, const char *fname, FILE_FORMAT format=FILE_FORMAT_DEFAULT, int type_id=0, int first_id=0, int last_id=65535)
int EraseItemsEC(std::map< int, T > &container, F do_erase_test)
Erasing items from container using DoEraseTest type functor. 
This file implements a feature tracker. 
int EraseUsingReprojectionError(std::map< int, T > &container, float reprojection_error_limit, int type_id=-1, Pose *pose=0)
Erases the items matching with type_id having large reprojection error. If type_id == -1 doesn't test...
void ProjectPoint(const CvPoint3D64f pw, const Pose *pose, CvPoint2D64f &pi) const 
Project one point. 
Pose representation derived from the Rotation class 
bool UpdateRotation(std::map< int, T > &container, Pose *pose, F do_handle_test)
Update the rotation in pose using the items matching the given functor. 
TFSIMD_FORCE_INLINE const tfScalar & x() const 
bool UpdatePose(std::map< int, T > &container, Pose *pose, F do_handle_test, std::map< int, double > *weights=0)
Update the pose using the items matching the given functor. 
TrackerFeatures tracks features using OpenCV's cvGoodFeaturesToTrack and cvCalcOpticalFlowPyrLK ...
TFSIMD_FORCE_INLINE const tfScalar & z() const 
bool DelFeature(int index)
int Detect(IplImage *image, Camera *cam, std::map< int, T > &container, int type_id=0, int first_id=0, int last_id=65535, bool track=false, bool visualize=false, double max_new_marker_error=0.08, double max_track_error=0.2, LabelingMethod labeling_method=CVSEQ)
Detect markers in the image and fill in their 2D-positions in the given external container. 
bool PreDetect(std::pair< const int, T > &p, int type_id)
TFSIMD_FORCE_INLINE const tfScalar & w() const 
This file implements a multi-marker. 
void GetMatrix(CvMat *mat) const 
bool Load(const char *fname, FILE_FORMAT format=FILE_FORMAT_DEFAULT)
Loads multi marker configuration from a text file. 
void CalcExteriorOrientation(std::vector< CvPoint3D64f > &pw, std::vector< CvPoint2D64f > &pi, Pose *pose)
Calculate exterior orientation. 
bool Load(std::map< int, T > &container, const char *fname, FILE_FORMAT format=FILE_FORMAT_DEFAULT, int type_id=0, int first_id=0, int last_id=65535)
Fill in 3D-coordinates for marker corners to the given container using save MultiMarker file...
int Detect(IplImage *image, Camera *cam, bool track=false, bool visualize=false, double max_new_marker_error=0.08, double max_track_error=0.2, LabelingMethod labeling_method=CVSEQ, bool update_pose=true)
Detect Marker 's from image 
void Distort(std::map< int, T > &container, F &do_handle_test)
Distort the items matching the given functor. 
bool CalcExteriorOrientation(std::map< int, T > &container, Pose *pose, int type_id=-1)
Calculate the pose using the items with matching type_id. 
bool MarkersToEC(std::map< int, T > &container, int type_id=0, int first_id=0, int last_id=65535)
Fill in 3D-coordinates for marker corners to the given container. 
CvPoint2D32f projected_p2d
Basic structure to be usable with EC methods. 
bool CalcExteriorOrientation(std::map< int, T > &container, Pose *pose, F do_handle_test)
Calculate the pose using the items matching the given functor. 
bool UpdateRotation(std::map< int, T > &container, Pose *pose, int type_id=-1)
Update the rotation in pose using the items with matching type_id. 
virtual bool operator()(const T &f) const 
int MarkerIdToContainerId(int marker_id, int corner_id, int first_id=0, int last_id=65535)
Calculate the index used in external container map for specified marker_id. 
bool Save(const char *fname, FILE_FORMAT format=FILE_FORMAT_DEFAULT)
Saves multi marker configuration to a text file. 
float Reproject(std::map< int, T > &container, Pose *pose, F do_handle_test, float average_outlier_limit=0.f)
Projects p3d in the items matching with the given functor. 
virtual bool operator()(const T &f) const 
Version of TrackerFeatures using external container.