00001 #ifndef MMVL_HOUGH_TRACKING_HH_INCLUDED
00002 #define MMVL_HOUGH_TRACKING_HH_INCLUDED
00003
00004 #include <iostream>
00005 #include <fstream>
00006 #include <iomanip>
00007 #include <vector>
00008 #include <set>
00009 #include <algorithm>
00010 #include <boost/multi_array.hpp>
00011 #include <boost/numeric/ublas/vector.hpp>
00012 #include <mimas/mm_linalg.h>
00013
00014 #include <mimas/mm_image_fileinput.h>
00015 #include <mimas/mm_image_fileoutput.h>
00016 #include <mimas/mm_image_qtoutput.h>
00017 #include "tools.hh"
00018 #include <mimas/mm_image.h>
00019
00020 #include <mimas/mm_xml_node_reference_list.h>
00021 #include <mimas/mm_xml_document.h>
00022
00023 #include <util/PlatformUtils.hpp>
00024 #include <XPath/XPathInit.hpp>
00025 #ifndef NDEBUG
00026 #include <mimas/mm_image_qtoutput.h>
00027 #include <qdatetime.h>
00028 #endif
00029
00030 #include <qthread.h>
00031 #include <qthreadstorage.h>
00032 #include <qmutex.h>
00033
00034
00071
00072
00073 class Interval{
00074 public:
00075 enum interval_type {Continuous = 0, Discrete};
00076 enum interval_type type;
00077
00078
00079 float lower_bound;
00080 float upper_bound;
00081
00082
00083 int value;
00084
00085 Interval(float lowerBound, float uperBound)
00086 :type(Continuous), lower_bound(lowerBound), upper_bound(uperBound)
00087 {};
00088
00089 Interval(int value)
00090 :type(Discrete),value(value)
00091 {};
00092 };
00093
00094
00107 class Transformation{
00108 public:
00109 std::vector<Interval> intervals;
00110 int votes;
00111
00112 Transformation():
00113 votes(0){}
00114
00115 void debug(void)
00116 {
00117 std::cerr<<"transformation is:"<<std::endl
00118 <<"x: "<< (intervals[0].lower_bound + intervals[0].upper_bound)/2 <<std::endl
00119 <<"y: "<< (intervals[1].lower_bound + intervals[1].upper_bound)/2 <<std::endl
00120 <<"theta: "<< (intervals[2].lower_bound + intervals[2].upper_bound)/2 <<std::endl
00121 <<"z: "<< intervals[3].value <<std::endl
00122 <<"number of hit: "<< votes<<std::endl;
00123 }
00124 };
00125
00126 struct lttransf : public std::binary_function<Transformation, Transformation, bool> {
00127 bool operator()(Transformation x, Transformation y) { return x.votes < y.votes;}
00128 };
00129
00139 typedef boost::numeric::ublas::vector<int> Feature;
00140
00141 struct ltfeature
00142 {
00143 bool operator()(const Feature &f1, const Feature &f2) const
00144 {
00145 if (f1(0) == f2(0))
00146 {
00147 return f1(1) < f2(1);
00148 }
00149 return f1(0) < f2(0);
00150 }
00151 };
00152
00153
00154
00155
00156
00157 class hough_tracking {
00158 public:
00159
00160
00161
00162
00163
00164
00165
00166
00167 hough_tracking( const std::vector< std::vector<Feature> > &feature_images,
00168 int model_width, int model_height, int K ,
00169 int x_min, int x_max, int x_sub,
00170 int y_min, int y_max, int y_sub,
00171 float theta_min, float theta_max, int theta_sub,
00172 int nb_thread);
00173
00174
00175
00176
00177 std::vector<int> number_of_features;
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 void fill_image_space(void);
00196
00197
00198
00199 Transformation track(std::vector<Feature> &features);
00200
00201 int get_model_width(void) const { return model_width; }
00202 int get_model_height(void) const { return model_height; }
00203
00204 ~hough_tracking()
00205 {
00206
00207
00208
00209
00210
00211
00212
00213
00214 }
00215
00216 private:
00217 int model_width;
00218 int model_height;
00219 int x_sub;
00220 int y_sub;
00221 int theta_sub;
00222 int z_max;
00223
00224 class track_t:public QThread
00225 {
00226 public:
00227 boost::multi_array<std::vector<Transformation *>,2>& image_space;
00228 std::vector<Feature> &features;
00229 std::vector<Transformation *>::iterator transf_it;
00230 QMutex &mutex;
00231 QMutex &mutex_b;
00232
00233 track_t(boost::multi_array<std::vector<Transformation *>,2>& image_space, QMutex &mutex, QMutex &mutex_b)
00234 :image_space(image_space),features(*(new std::vector<Feature>) ), mutex(mutex), mutex_b(mutex_b)
00235 {
00236 this->mutex.lock();
00237 this->mutex_b.lock();
00238 }
00239
00240
00241 void set_features(std::vector<Feature> &features_l)
00242 {
00243 features = features_l;
00244 }
00245
00246
00247 void run(void)
00248 {
00249 while(true)
00250 {
00251 mutex_b.lock();
00252 for( std::vector<Feature>::const_iterator feature_it = features.begin(); feature_it != features.end(); feature_it++)
00253 {
00254 Feature temp(2);
00255 temp(0) = (*feature_it)(0) + image_space.shape()[0]/2;
00256 temp(1) = image_space.shape()[1]/2 - (*feature_it)(1);
00257
00258 for(transf_it = image_space[temp(0)][temp(1)].begin();
00259 transf_it != image_space[temp(0)][temp(1)].end();
00260 transf_it++)
00261 (*transf_it)->votes++;
00262 }
00263 mutex.unlock();
00264 }
00265 }
00266
00267 };
00268
00269
00270 std::vector< std::vector<Feature> > feature_images;
00271
00272 boost::multi_array<Transformation,4> transformation_space;
00273 typedef boost::multi_array<Transformation,4>::index idx_ts;
00274
00275
00276
00277 int nb_thread;
00278 std::vector<boost::multi_array<std::vector<Transformation *>,2> *> image_space_vec;
00279 std::vector<QMutex *> mutexes;
00280 std::vector<QMutex *> mutexes_b;
00281 std::vector<track_t *> threads;
00282
00283
00284 typedef boost::multi_array<std::vector<Transformation *>,2>::index idx_is;
00285
00286 #ifndef NDEBUG
00287
00288 mutable mimas::mm_image_qtoutput< mimas::mm_rgba< unsigned char > > display;
00289 #endif
00290
00291 };
00292
00293 typedef boost::shared_ptr< hough_tracking > hough_tracking_ptr;
00294
00295 #endif