Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef MOCAP_DATA_H
00017 #define MOCAP_DATA_H
00018
00019 #include "cloud.h"
00020 #include "options.h"
00021 #include <list>
00022 #include <vector>
00023 #include <limits>
00024
00025 typedef std::vector<vector3> point_vector;
00026
00030 template <class observation_type>
00031 class mocap_data : public cloud<point_vector>
00032 {
00033 public:
00034 mocap_data (const options &opts, const calibration &_calib)
00035 : cloud<point_vector> (opts, _calib)
00036 {
00037 try
00038 {
00039 const std::string mocap_filename = opts.mocap_filename ();
00040 read_data (mocap_filename);
00041 curr_frame_iter = all_points.begin ();
00042
00043
00044 for (int f = 0; f < frame; f++)
00045 curr_frame_iter ++;
00046 }
00047 catch (missing_option)
00048 {
00049 curr_frame_iter = all_points.end ();
00050 }
00051 };
00052
00053 ~mocap_data ()
00054 {
00055 for (std::list<point_vector*>::iterator iter = all_points.begin ();
00056 iter != all_points.end (); iter ++)
00057 {
00058 if (*iter != NULL)
00059 {
00060 delete *iter;
00061 *iter = NULL;
00062 }
00063 }
00064 };
00065
00066 bool refresh (bool goto_next = true)
00067 {
00068 bool retval = true;
00069 if (goto_next && curr_frame_iter != all_points.end ())
00070 {
00071 frame ++;
00072 curr_frame_iter ++;
00073 if (curr_frame_iter == all_points.end ())
00074 retval = false;
00075 }
00076
00077 return retval;
00078 };
00079
00080 size_t size () const
00081 {
00082 return all_points.size ();
00083 };
00084
00085 void show () const
00086 {
00087 if (curr_frame_iter != all_points.end ())
00088 {
00089 const point_vector *points = *curr_frame_iter;
00090 if (points != NULL)
00091 {
00092 OpenTissue::gl::ColorPicker (1.0, 0.3, 0.0);
00093 for (size_t k = 0; k < points->size (); k++)
00094 OpenTissue::gl::DrawPoint ((*points) [k], 0.15);
00095 }
00096 }
00097 };
00098
00099 double average_pose_dist (const skeleton_state<observation_type> &pose)
00100 {
00101 double dist = 0;
00102 if (curr_frame_iter != all_points.end ())
00103 {
00104 const skeleton_type& skeleton = pose.get_skeleton ();
00105 const point_vector *points = *curr_frame_iter;
00106 if (points != NULL)
00107 {
00108 for (size_t k = 0; k < points->size (); k++)
00109 dist += point_skin_dist (skeleton, (*points) [k]);
00110 dist /= (double)points->size ();
00111 }
00112 }
00113
00114 return dist;
00115 };
00116
00117 protected:
00118
00119 std::list< point_vector* > all_points;
00120 std::list< point_vector* >::iterator curr_frame_iter;
00121
00122
00123 void read_data (const std::string filename)
00124 {
00125 FILE *mocap_fid = fopen (filename.c_str (), "r");
00126 if (mocap_fid != NULL)
00127 {
00128
00129 char line [1000];
00130 char *status = fgets (line, sizeof (line), mocap_fid);
00131 while (status == line)
00132 {
00133
00134 int num_words = 1;
00135 char *lp = line;
00136 while (*lp != '\n')
00137 {
00138 if (*lp == ' ' && *(lp-1) != ' ')
00139 num_words ++;
00140 lp++;
00141 }
00142
00143 point_vector *points = NULL;
00144 if ((num_words/3)*3 != num_words)
00145 {
00146 std::cerr << "warning: number of word (" << num_words
00147 << ") in mocap validation file is not divisble by 3"
00148 << std::endl;
00149 }
00150 else
00151 {
00152 lp = line;
00153 const int num_points = num_words / 3;
00154 points = new point_vector (num_points);
00155 int idx = 0;
00156 for (int v = 0; v < num_points; v++)
00157 {
00158 double x, y, z;
00159 const int num_read = sscanf (lp, "%lf %lf %lf", &x, &y, &z);
00160 if (num_read == 3)
00161 {
00162 #define IS_MINUS_ONE(X) (fabs (x + 1.0) < 0.00001)
00163 if (!(IS_MINUS_ONE (x) && IS_MINUS_ONE (y) && IS_MINUS_ONE (z)))
00164 (*points) [idx++] = calib.camera_to_world (vector3 (x, y, z));
00165 #undef IS_MINUS_ONE
00166
00167 for (int w = 0; w < 3; w++)
00168 {
00169 while (*lp != ' ' && *lp != '\n')
00170 lp++;
00171 while (*lp == ' ' || *lp == '\n')
00172 lp++;
00173 }
00174 }
00175 else
00176 {
00177 std::cerr << "warning: did not read a 3D point from mocap validation file"
00178 << std::endl;
00179 delete points;
00180 points = NULL;
00181 break;
00182 }
00183 }
00184 points->resize (idx);
00185 }
00186 all_points.push_back (points);
00187
00188 status = fgets (line, sizeof (line), mocap_fid);
00189 }
00190 fclose (mocap_fid);
00191 }
00192 };
00193
00194 double point_skin_dist (const skeleton_type &skeleton, const vector3 &x0)
00195 {
00196 double min_dist = std::numeric_limits<double>::infinity();
00197
00198 for (const_bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter++)
00199 {
00200 if (!iter->is_root ())
00201 {
00202 const vector3 x1 = iter->absolute ().T ();
00203 const vector3 x2 = iter->parent ()->absolute ().T ();
00204 if (x1 != x2)
00205 {
00206 const vector3 d01 = x0 - x1;
00207 const vector3 d21 = x2 - x1;
00208 const double alpha = force_in_range ((d01 * d21) / (d21 * d21), 0.0, 1.0);
00209
00210 const vector3 on_stick = alpha * x2 + (1.0 - alpha) * x1;
00211 const vector3 d = on_stick - x0;
00212 const double dist_to_bone = sqrt (d * d);
00213
00214 const double r = iter->get_width ();
00215 const double dist_to_skin = fabs (dist_to_bone - r);
00216
00217 if (dist_to_skin < min_dist)
00218 min_dist = dist_to_skin;
00219 }
00220 }
00221 }
00222 return min_dist;
00223 };
00224
00225 };
00226
00227 #endif // MOCAP_DATA_H