Fixed bug #1654
authorMarina Kolpakova <no@email>
Sun, 18 Mar 2012 17:17:44 +0000 (17:17 +0000)
committerMarina Kolpakova <no@email>
Sun, 18 Mar 2012 17:17:44 +0000 (17:17 +0000)
modules/contrib/src/chamfermatching.cpp

index c9e38d4..fa2c599 100644 (file)
 // The original code was written by
 //          Marius Muja
 // and later modified and prepared
-//  for integration into OpenCV by 
+//  for integration into OpenCV by
 //        Antonella Cascitelli,
 //        Marco Di Stefano and
 //          Stefano Fabri
-//        from Univ. of Rome 
+//        from Univ. of Rome
 //
 
 #include "precomp.hpp"
@@ -52,7 +52,7 @@ namespace cv
 {
 
 using std::queue;
-    
+
 typedef std::pair<int,int> coordinate_t;
 typedef float orientation_t;
 typedef std::vector<coordinate_t> template_coords_t;
@@ -61,14 +61,14 @@ typedef std::pair<Point, float> location_scale_t;
 
 class ChamferMatcher
 {
-    
+
 private:
     class Matching;
     int max_matches_;
     float min_match_distance_;
-    
+
     ///////////////////////// Image iterators ////////////////////////////
-    
+
     class ImageIterator
     {
     public:
@@ -76,15 +76,15 @@ private:
         virtual bool hasNext() const = 0;
         virtual location_scale_t next() = 0;
     };
-    
+
     class ImageRange
     {
     public:
         virtual ImageIterator* iterator() const = 0;
     };
-    
+
     // Sliding window
-    
+
     class SlidingWindowImageRange : public ImageRange
     {
         int width_;
@@ -94,64 +94,64 @@ private:
         int scales_;
         float min_scale_;
         float max_scale_;
-        
+
     public:
         SlidingWindowImageRange(int width, int height, int x_step = 3, int y_step = 3, int scales = 5, float min_scale = 0.6, float max_scale = 1.6) :
         width_(width), height_(height), x_step_(x_step),y_step_(y_step), scales_(scales), min_scale_(min_scale), max_scale_(max_scale)
         {
         }
-        
-        
+
+
         ImageIterator* iterator() const;
     };
-    
+
     class LocationImageRange : public ImageRange
     {
         const std::vector<Point>& locations_;
-        
+
         int scales_;
         float min_scale_;
         float max_scale_;
 
-               LocationImageRange(const LocationImageRange&);
-               LocationImageRange& operator=(const LocationImageRange&);
-        
+        LocationImageRange(const LocationImageRange&);
+        LocationImageRange& operator=(const LocationImageRange&);
+
     public:
         LocationImageRange(const std::vector<Point>& locations, int scales = 5, float min_scale = 0.6, float max_scale = 1.6) :
         locations_(locations), scales_(scales), min_scale_(min_scale), max_scale_(max_scale)
         {
         }
-        
+
         ImageIterator* iterator() const
         {
             return new LocationImageIterator(locations_, scales_, min_scale_, max_scale_);
         }
     };
-    
-    
+
+
     class LocationScaleImageRange : public ImageRange
     {
         const std::vector<Point>& locations_;
         const std::vector<float>& scales_;
-        
-               LocationScaleImageRange(const LocationScaleImageRange&);
-               LocationScaleImageRange& operator=(const LocationScaleImageRange&);
+
+        LocationScaleImageRange(const LocationScaleImageRange&);
+        LocationScaleImageRange& operator=(const LocationScaleImageRange&);
     public:
         LocationScaleImageRange(const std::vector<Point>& locations, const std::vector<float>& scales) :
         locations_(locations), scales_(scales)
         {
             assert(locations.size()==scales.size());
         }
-        
+
         ImageIterator* iterator() const
         {
             return new LocationScaleImageIterator(locations_, scales_);
         }
     };
-    
-    
-    
-    
+
+
+
+
 public:
     /**
      * Class that represents a template for chamfer matching.
@@ -160,26 +160,26 @@ public:
     {
         friend class ChamferMatcher::Matching;
         friend class ChamferMatcher;
-        
-        
+
+
     public:
         std::vector<Template*> scaled_templates;
         std::vector<int> addr;
         int addr_width;
         float scale;
         template_coords_t coords;
-        
+
         template_orientations_t orientations;
         Size size;
         Point center;
-        
+
     public:
         Template() : addr_width(-1)
         {
         }
-        
+
         Template(Mat& edge_image, float scale_ = 1);
-        
+
         ~Template()
         {
             for (size_t i=0;i<scaled_templates.size();++i) {
@@ -190,9 +190,9 @@ public:
             orientations.clear();
         }
         void show() const;
-        
-        
-        
+
+
+
     private:
         /**
          * Resizes a template
@@ -200,16 +200,16 @@ public:
          * @param scale Scale to be resized to
          */
         Template* rescale(float scale);
-        
+
         std::vector<int>& getTemplateAddresses(int width);
     };
-    
-    
-    
+
+
+
     /**
      * Used to represent a matching result.
      */
-    
+
     class Match
     {
     public:
@@ -217,9 +217,9 @@ public:
         Point offset;
         const Template* tpl;
     };
-    
+
     typedef std::vector<Match> Matches;
-    
+
 private:
     /**
      * Implements the chamfer matching algorithm on images taking into account both distance from
@@ -230,42 +230,42 @@ private:
     {
         float truncate_;
         bool use_orientation_;
-        
+
         std::vector<Template*> templates;
     public:
         Matching(bool use_orientation = true, float truncate = 10) : truncate_(truncate), use_orientation_(use_orientation)
         {
         }
-        
+
         ~Matching()
         {
             for (size_t i = 0; i<templates.size(); i++) {
                 delete templates[i];
             }
         }
-        
+
         /**
          * Add a template to the detector from an edge image.
          * @param templ An edge image
          */
         void addTemplateFromImage(Mat& templ, float scale = 1.0);
-        
+
         /**
          * Run matching using an edge image.
          * @param edge_img Edge image
          * @return a match object
          */
         ChamferMatcher::Matches* matchEdgeImage(Mat& edge_img, const ImageRange& range, float orientation_weight = 0.5, int max_matches = 20, float min_match_distance = 10.0);
-        
+
         void addTemplate(Template& template_);
-        
+
     private:
-        
+
         float orientation_diff(float o1, float o2)
         {
             return fabs(o1-o2);
         }
-        
+
         /**
          * Computes the chamfer matching cost for one position in the target image.
          * @param offset Offset where to compute cost
@@ -276,7 +276,7 @@ private:
          * @return matching result
          */
         ChamferMatcher::Match* localChamferDistance(Point offset, Mat& dist_img, Mat& orientation_img, Template* tpl,  float orientation_weight);
-        
+
     private:
         /**
          * Matches all templates.
@@ -284,12 +284,12 @@ private:
          * @param orientation_img Orientation image.
          */
         ChamferMatcher::Matches* matchTemplates(Mat& dist_img, Mat& orientation_img, const ImageRange& range, float orientation_weight);
-        
+
         void computeDistanceTransform(Mat& edges_img, Mat& dist_img, Mat& annotate_img, float truncate_dt, float a, float b);
         void computeEdgeOrientations(Mat& edge_img, Mat& orientation_img);
         void fillNonContourOrientations(Mat& annotated_img, Mat& orientation_img);
-        
-        
+
+
     public:
         /**
          * Finds a contour in an edge image. The original image is altered by removing the found contour.
@@ -298,7 +298,7 @@ private:
          * @return True while a contour is still found in the image.
          */
         static bool findContour(Mat& templ_img, template_coords_t& coords);
-        
+
         /**
          * Computes contour points orientations using the approach from:
          *
@@ -309,8 +309,8 @@ private:
          * @param orientations Contour points orientations
          */
         static void findContourOrientations(const template_coords_t& coords, template_orientations_t& orientations);
-        
-        
+
+
         /**
          * Computes the angle of a line segment.
          *
@@ -321,14 +321,14 @@ private:
          * @return Angle in radians.
          */
         static float getAngle(coordinate_t a, coordinate_t b, int& dx, int& dy);
-        
+
         /**
          * Finds a point in the image from which to start contour following.
          * @param templ_img
          * @param p
          * @return
          */
-        
+
         static bool findFirstContourPoint(Mat& templ_img, coordinate_t& p);
         /**
          * Method that extracts a single continuous contour from an image given a starting point.
@@ -339,54 +339,54 @@ private:
          * @param direction
          */
         static void followContour(Mat& templ_img, template_coords_t& coords, int direction);
-        
-        
+
+
     };
-    
-    
-    
-    
+
+
+
+
     class LocationImageIterator : public ImageIterator
     {
         const std::vector<Point>& locations_;
-        
+
         size_t iter_;
-        
+
         int scales_;
         float min_scale_;
         float max_scale_;
-        
+
         float scale_;
         float scale_step_;
         int scale_cnt_;
-        
+
         bool has_next_;
 
-               LocationImageIterator(const LocationImageIterator&);
-               LocationImageIterator& operator=(const LocationImageIterator&);
-        
+        LocationImageIterator(const LocationImageIterator&);
+        LocationImageIterator& operator=(const LocationImageIterator&);
+
     public:
         LocationImageIterator(const std::vector<Point>& locations, int scales, float min_scale, float max_scale);
-        
+
         bool hasNext() const {
             return has_next_;
         }
-        
+
         location_scale_t next();
     };
-    
+
     class LocationScaleImageIterator : public ImageIterator
     {
         const std::vector<Point>& locations_;
         const std::vector<float>& scales_;
-        
+
         size_t iter_;
-        
+
         bool has_next_;
 
-               LocationScaleImageIterator(const LocationScaleImageIterator&);
-               LocationScaleImageIterator& operator=(const LocationScaleImageIterator&);
-        
+        LocationScaleImageIterator(const LocationScaleImageIterator&);
+        LocationScaleImageIterator& operator=(const LocationScaleImageIterator&);
+
     public:
         LocationScaleImageIterator(const std::vector<Point>& locations, const std::vector<float>& scales) :
         locations_(locations), scales_(scales)
@@ -394,20 +394,20 @@ private:
             assert(locations.size()==scales.size());
             reset();
         }
-        
+
         void reset()
         {
             iter_ = 0;
             has_next_ = (locations_.size()==0 ? false : true);
         }
-        
+
         bool hasNext() const {
             return has_next_;
         }
-        
+
         location_scale_t next();
     };
-    
+
     class SlidingWindowImageIterator : public ImageIterator
     {
         int x_;
@@ -415,9 +415,9 @@ private:
         float scale_;
         float scale_step_;
         int scale_cnt_;
-        
+
         bool has_next_;
-        
+
         int width_;
         int height_;
         int x_step_;
@@ -425,22 +425,22 @@ private:
         int scales_;
         float min_scale_;
         float max_scale_;
-        
-        
+
+
     public:
-        
+
         SlidingWindowImageIterator(int width, int height, int x_step, int y_step, int scales, float min_scale, float max_scale);
-        
+
         bool hasNext() const {
             return has_next_;
         }
-        
+
         location_scale_t next();
     };
-    
-    
-    
-    
+
+
+
+
     int count;
     Matches matches;
     int pad_x;
@@ -451,7 +451,7 @@ private:
     float orientation_weight;
     float truncate;
     Matching * chamfer_;
-    
+
 public:
     ChamferMatcher(int _max_matches = 20, float _min_match_distance = 1.0, int _pad_x = 3,
                    int _pad_y = 3, int _scales = 5, float _minScale = 0.6, float _maxScale = 1.6,
@@ -467,371 +467,371 @@ public:
         orientation_weight = _orientation_weight;
         truncate = _truncate;
         count = 0;
-        
+
         matches.resize(max_matches_);
         chamfer_ = new Matching(true);
     }
-    
+
     void showMatch(Mat& img, int index = 0);
     void showMatch(Mat& img, Match match_);
-    
+
     const Matches& matching(Template&, Mat&);
-    
+
 private:
     void addMatch(float cost, Point offset, const Template* tpl);
-    
-    
+
+
 };
 
-    
+
 ///////////////////// implementation ///////////////////////////
 
-ChamferMatcher::SlidingWindowImageIterator::SlidingWindowImageIterator( int width, 
-                                                                                                                                               int height, 
-                                                                                                                                               int x_step = 3, 
-                                                                                                                                               int y_step = 3, 
-                                                                                                                                               int scales = 5, 
-                                                                                                                                               float min_scale = 0.6, 
-                                                                                                                                               float max_scale = 1.6) :
-                                                                                                                                                       
-                                                                                                                                                       width_(width), 
-                                                                                                                                                       height_(height), 
-                                                                                                                                                       x_step_(x_step),
-                                                                                                                                                       y_step_(y_step), 
-                                                                                                                                                       scales_(scales), 
-                                                                                                                                                       min_scale_(min_scale), 
-                                                                                                                                                       max_scale_(max_scale)
+ChamferMatcher::SlidingWindowImageIterator::SlidingWindowImageIterator( int width,
+                                                                        int height,
+                                                                        int x_step = 3,
+                                                                        int y_step = 3,
+                                                                        int scales = 5,
+                                                                        float min_scale = 0.6,
+                                                                        float max_scale = 1.6) :
+
+                                                                            width_(width),
+                                                                            height_(height),
+                                                                            x_step_(x_step),
+                                                                            y_step_(y_step),
+                                                                            scales_(scales),
+                                                                            min_scale_(min_scale),
+                                                                            max_scale_(max_scale)
 {
-       x_ = 0;
-       y_ = 0;
-       scale_cnt_ = 0;
-       scale_ = min_scale_;
-       has_next_ = true;
-       scale_step_ = (max_scale_-min_scale_)/scales_;
+    x_ = 0;
+    y_ = 0;
+    scale_cnt_ = 0;
+    scale_ = min_scale_;
+    has_next_ = true;
+    scale_step_ = (max_scale_-min_scale_)/scales_;
 }
 
 location_scale_t ChamferMatcher::SlidingWindowImageIterator::next()
 {
-       location_scale_t next_val = std::make_pair(Point(x_,y_),scale_);
+    location_scale_t next_val = std::make_pair(Point(x_,y_),scale_);
 
-       x_ += x_step_;
+    x_ += x_step_;
 
-       if (x_ >= width_) {
-               x_ = 0;
-               y_ += y_step_;
+    if (x_ >= width_) {
+        x_ = 0;
+        y_ += y_step_;
 
-               if (y_ >= height_) {
-                       y_ = 0;
-                       scale_ += scale_step_;
-                       scale_cnt_++;
+        if (y_ >= height_) {
+            y_ = 0;
+            scale_ += scale_step_;
+            scale_cnt_++;
 
-                       if (scale_cnt_ == scales_) {
-                               has_next_ = false;
-                               scale_cnt_ = 0;
-                               scale_ = min_scale_;
-                       }
-               }
-       }
+            if (scale_cnt_ == scales_) {
+                has_next_ = false;
+                scale_cnt_ = 0;
+                scale_ = min_scale_;
+            }
+        }
+    }
 
-       return next_val;
+    return next_val;
 }
 
 
 
 ChamferMatcher::ImageIterator* ChamferMatcher::SlidingWindowImageRange::iterator() const
 {
-       return new SlidingWindowImageIterator(width_, height_, x_step_, y_step_, scales_, min_scale_, max_scale_);
+    return new SlidingWindowImageIterator(width_, height_, x_step_, y_step_, scales_, min_scale_, max_scale_);
 }
 
 
 
-ChamferMatcher::LocationImageIterator::LocationImageIterator(const std::vector<Point>& locations, 
-                                                                                                                               int scales = 5, 
-                                                                                                                               float min_scale = 0.6, 
-                                                                                                                               float max_scale = 1.6) :
-                                                                                                                                       locations_(locations), 
-                                                                                                                                       scales_(scales), 
-                                                                                                                                       min_scale_(min_scale), 
-                                                                                                                                       max_scale_(max_scale)
-{ 
-       iter_ = 0;
-       scale_cnt_ = 0;
-       scale_ = min_scale_;
-       has_next_ = (locations_.size()==0 ? false : true);
-       scale_step_ = (max_scale_-min_scale_)/scales_;
+ChamferMatcher::LocationImageIterator::LocationImageIterator(const std::vector<Point>& locations,
+                                                                int scales = 5,
+                                                                float min_scale = 0.6,
+                                                                float max_scale = 1.6) :
+                                                                    locations_(locations),
+                                                                    scales_(scales),
+                                                                    min_scale_(min_scale),
+                                                                    max_scale_(max_scale)
+{
+    iter_ = 0;
+    scale_cnt_ = 0;
+    scale_ = min_scale_;
+    has_next_ = (locations_.size()==0 ? false : true);
+    scale_step_ = (max_scale_-min_scale_)/scales_;
 }
 
 location_scale_t ChamferMatcher::LocationImageIterator:: next()
 {
-       location_scale_t next_val = std::make_pair(locations_[iter_],scale_);
-
-       iter_ ++;
-       if (iter_==locations_.size()) {
-               iter_ = 0;
-               scale_ += scale_step_;
-               scale_cnt_++;
-
-               if (scale_cnt_ == scales_) {
-                       has_next_ = false;
-                       scale_cnt_ = 0;
-                       scale_ = min_scale_;
-               }
-       }
-
-       return next_val;
+    location_scale_t next_val = std::make_pair(locations_[iter_],scale_);
+
+    iter_ ++;
+    if (iter_==locations_.size()) {
+        iter_ = 0;
+        scale_ += scale_step_;
+        scale_cnt_++;
+
+        if (scale_cnt_ == scales_) {
+            has_next_ = false;
+            scale_cnt_ = 0;
+            scale_ = min_scale_;
+        }
+    }
+
+    return next_val;
 }
 
 
 location_scale_t ChamferMatcher::LocationScaleImageIterator::next()
 {
-       location_scale_t next_val = std::make_pair(locations_[iter_],scales_[iter_]);
+    location_scale_t next_val = std::make_pair(locations_[iter_],scales_[iter_]);
 
-       iter_ ++;
-       if (iter_==locations_.size()) {
-               iter_ = 0;
+    iter_ ++;
+    if (iter_==locations_.size()) {
+        iter_ = 0;
 
-               has_next_ = false;
-       }
+        has_next_ = false;
+    }
 
-       return next_val;
+    return next_val;
 }
 
 
 
 bool ChamferMatcher::Matching::findFirstContourPoint(Mat& templ_img, coordinate_t& p)
 {
-       for (int y=0;y<templ_img.rows;++y) {
-               for (int x=0;x<templ_img.cols;++x) {
-                       if (templ_img.at<uchar>(y,x)!=0) {
-                               p.first = x;
-                               p.second = y;
-                               return true;
-                       }
-               }
-       }
-       return false;
+    for (int y=0;y<templ_img.rows;++y) {
+        for (int x=0;x<templ_img.cols;++x) {
+            if (templ_img.at<uchar>(y,x)!=0) {
+                p.first = x;
+                p.second = y;
+                return true;
+            }
+        }
+    }
+    return false;
 }
 
 
 
 void ChamferMatcher::Matching::followContour(Mat& templ_img, template_coords_t& coords, int direction = -1)
 {
-       const int dir[][2] = { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
-       coordinate_t next;
-       coordinate_t next_temp;
-       unsigned char ptr;
-
-       assert (direction==-1 || !coords.empty());
-
-       coordinate_t crt = coords.back();
-
-       // mark the current pixel as visited
-       templ_img.at<uchar>(crt.second,crt.first) = 0;
-       if (direction==-1) {
-               for (int j = 0; j<7; ++j) {
-                       next.first = crt.first + dir[j][1];
-                       next.second = crt.second + dir[j][0];
-                       if (next.first >= 0 && next.first < templ_img.cols &&
-                               next.second >= 0 && next.second < templ_img.rows){
-                               ptr = templ_img.at<uchar>(next.second, next.first);
-                               if (ptr!=0) {
-                                       coords.push_back(next);
-                                       followContour(templ_img, coords,j);
-                                       // try to continue contour in the other direction
-                                       reverse(coords.begin(), coords.end());
-                                       followContour(templ_img, coords, (j+4)%8);
-                                       break;
-                               }
-                       }
-               }
-       }
-       else {
-               int k = direction;
-               int k_cost = 3;
-               next.first = crt.first + dir[k][1];
-               next.second = crt.second + dir[k][0];
-               if (next.first >= 0 && next.first < templ_img.cols &&
-                               next.second >= 0 && next.second < templ_img.rows){
-                       ptr = templ_img.at<uchar>(next.second, next.first);
-                       if (ptr!=0) {
-                               k_cost = std::abs(dir[k][1]) + std::abs(dir[k][0]);
-                       }
-                       int p = k;
-                       int n = k;
-
-                       for (int j = 0 ;j<3; ++j) {
-                               p = (p + 7) % 8;
-                               n = (n + 1) % 8;
-                               next.first = crt.first + dir[p][1];
-                               next.second = crt.second + dir[p][0];
-                               if (next.first >= 0 && next.first < templ_img.cols &&
-                                       next.second >= 0 && next.second < templ_img.rows){
-                                       ptr = templ_img.at<uchar>(next.second, next.first);
-                                       if (ptr!=0) {
-                                               int p_cost = std::abs(dir[p][1]) + std::abs(dir[p][0]);
-                                               if (p_cost<k_cost) {
-                                                       k_cost = p_cost;
-                                                       k = p;
-                                               }
-                                       }
-                                       next.first = crt.first + dir[n][1];
-                                       next.second = crt.second + dir[n][0];
-                                       if (next.first >= 0 && next.first < templ_img.cols &&
-                                       next.second >= 0 && next.second < templ_img.rows){
-                                               ptr = templ_img.at<uchar>(next.second, next.first);
-                                               if (ptr!=0) {
-                                                       int n_cost = std::abs(dir[n][1]) + std::abs(dir[n][0]);
-                                                       if (n_cost<k_cost) {
-                                                               k_cost = n_cost;
-                                                               k = n;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-
-                       if (k_cost!=3) {
-                               next.first = crt.first + dir[k][1];
-                               next.second = crt.second + dir[k][0];
-                               if (next.first >= 0 && next.first < templ_img.cols &&
-                                       next.second >= 0 && next.second < templ_img.rows) {
-                                       coords.push_back(next);
-                                       followContour(templ_img, coords, k);
-                               }
-                       }
-               }
-       }
+    const int dir[][2] = { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
+    coordinate_t next;
+    coordinate_t next_temp;
+    unsigned char ptr;
+
+    assert (direction==-1 || !coords.empty());
+
+    coordinate_t crt = coords.back();
+
+    // mark the current pixel as visited
+    templ_img.at<uchar>(crt.second,crt.first) = 0;
+    if (direction==-1) {
+        for (int j = 0; j<7; ++j) {
+            next.first = crt.first + dir[j][1];
+            next.second = crt.second + dir[j][0];
+            if (next.first >= 0 && next.first < templ_img.cols &&
+                next.second >= 0 && next.second < templ_img.rows){
+                ptr = templ_img.at<uchar>(next.second, next.first);
+                if (ptr!=0) {
+                    coords.push_back(next);
+                    followContour(templ_img, coords,j);
+                    // try to continue contour in the other direction
+                    reverse(coords.begin(), coords.end());
+                    followContour(templ_img, coords, (j+4)%8);
+                    break;
+                }
+            }
+        }
+    }
+    else {
+        int k = direction;
+        int k_cost = 3;
+        next.first = crt.first + dir[k][1];
+        next.second = crt.second + dir[k][0];
+        if (next.first >= 0 && next.first < templ_img.cols &&
+                next.second >= 0 && next.second < templ_img.rows){
+            ptr = templ_img.at<uchar>(next.second, next.first);
+            if (ptr!=0) {
+                k_cost = std::abs(dir[k][1]) + std::abs(dir[k][0]);
+            }
+            int p = k;
+            int n = k;
+
+            for (int j = 0 ;j<3; ++j) {
+                p = (p + 7) % 8;
+                n = (n + 1) % 8;
+                next.first = crt.first + dir[p][1];
+                next.second = crt.second + dir[p][0];
+                if (next.first >= 0 && next.first < templ_img.cols &&
+                    next.second >= 0 && next.second < templ_img.rows){
+                    ptr = templ_img.at<uchar>(next.second, next.first);
+                    if (ptr!=0) {
+                        int p_cost = std::abs(dir[p][1]) + std::abs(dir[p][0]);
+                        if (p_cost<k_cost) {
+                            k_cost = p_cost;
+                            k = p;
+                        }
+                    }
+                    next.first = crt.first + dir[n][1];
+                    next.second = crt.second + dir[n][0];
+                    if (next.first >= 0 && next.first < templ_img.cols &&
+                    next.second >= 0 && next.second < templ_img.rows){
+                        ptr = templ_img.at<uchar>(next.second, next.first);
+                        if (ptr!=0) {
+                            int n_cost = std::abs(dir[n][1]) + std::abs(dir[n][0]);
+                            if (n_cost<k_cost) {
+                                k_cost = n_cost;
+                                k = n;
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (k_cost!=3) {
+                next.first = crt.first + dir[k][1];
+                next.second = crt.second + dir[k][0];
+                if (next.first >= 0 && next.first < templ_img.cols &&
+                    next.second >= 0 && next.second < templ_img.rows) {
+                    coords.push_back(next);
+                    followContour(templ_img, coords, k);
+                }
+            }
+        }
+    }
 }
 
 
 bool ChamferMatcher::Matching::findContour(Mat& templ_img, template_coords_t& coords)
 {
-       coordinate_t start_point;
+    coordinate_t start_point;
 
-       bool found = findFirstContourPoint(templ_img,start_point);
-       if (found) {
-               coords.push_back(start_point);
-               followContour(templ_img, coords);
-               return true;
-       }
+    bool found = findFirstContourPoint(templ_img,start_point);
+    if (found) {
+        coords.push_back(start_point);
+        followContour(templ_img, coords);
+        return true;
+    }
 
-       return false;
+    return false;
 }
 
 
 float ChamferMatcher::Matching::getAngle(coordinate_t a, coordinate_t b, int& dx, int& dy)
 {
-       dx = b.first-a.first;
-       dy = -(b.second-a.second);  // in image coordinated Y axis points downward
+    dx = b.first-a.first;
+    dy = -(b.second-a.second);  // in image coordinated Y axis points downward
         float angle = atan2((float)dy,(float)dx);
-       
-       if (angle<0) {
+
+    if (angle<0) {
                 angle+=(float)CV_PI;
-       }
-       
-       return angle;
+    }
+
+    return angle;
 }
 
 
 
 void ChamferMatcher::Matching::findContourOrientations(const template_coords_t& coords, template_orientations_t& orientations)
 {
-       const int M = 5;
-       int coords_size = (int)coords.size();
+    const int M = 5;
+    int coords_size = (int)coords.size();
 
     std::vector<float> angles(2*M);
         orientations.insert(orientations.begin(), coords_size, float(-3*CV_PI)); // mark as invalid in the beginning
 
-       if (coords_size<2*M+1) {  // if contour not long enough to estimate orientations, abort
-               return;
-       }
-
-       for (int i=M;i<coords_size-M;++i) {
-               coordinate_t crt = coords[i];
-               coordinate_t other;
-               int k = 0;
-               int dx, dy;
-               // compute previous M angles
-               for (int j=M;j>0;--j) {
-                       other = coords[i-j];
-                       angles[k++] = getAngle(other,crt, dx, dy);
-               }
-               // compute next M angles
-               for (int j=1;j<=M;++j) {
-                       other = coords[i+j];
-                       angles[k++] = getAngle(crt, other, dx, dy);
-               }
-
-               // get the middle two angles
-               nth_element(angles.begin(), angles.begin()+M-1,  angles.end());
-               nth_element(angles.begin()+M-1, angles.begin()+M,  angles.end());
-               //              sort(angles.begin(), angles.end());
-
-               // average them to compute tangent
-               orientations[i] = (angles[M-1]+angles[M])/2;
-       }
+    if (coords_size<2*M+1) {  // if contour not long enough to estimate orientations, abort
+        return;
+    }
+
+    for (int i=M;i<coords_size-M;++i) {
+        coordinate_t crt = coords[i];
+        coordinate_t other;
+        int k = 0;
+        int dx, dy;
+        // compute previous M angles
+        for (int j=M;j>0;--j) {
+            other = coords[i-j];
+            angles[k++] = getAngle(other,crt, dx, dy);
+        }
+        // compute next M angles
+        for (int j=1;j<=M;++j) {
+            other = coords[i+j];
+            angles[k++] = getAngle(crt, other, dx, dy);
+        }
+
+        // get the middle two angles
+        nth_element(angles.begin(), angles.begin()+M-1,  angles.end());
+        nth_element(angles.begin()+M-1, angles.begin()+M,  angles.end());
+        //        sort(angles.begin(), angles.end());
+
+        // average them to compute tangent
+        orientations[i] = (angles[M-1]+angles[M])/2;
+    }
 }
 
 //////////////////////// Template /////////////////////////////////////
 
 ChamferMatcher::Template::Template(Mat& edge_image, float scale_) : addr_width(-1), scale(scale_)
 {
-       template_coords_t local_coords;
-       template_orientations_t local_orientations;
-
-       while (ChamferMatcher::Matching::findContour(edge_image, local_coords)) {
-               ChamferMatcher::Matching::findContourOrientations(local_coords, local_orientations);
-
-               coords.insert(coords.end(), local_coords.begin(), local_coords.end());
-               orientations.insert(orientations.end(), local_orientations.begin(), local_orientations.end());
-               local_coords.clear();
-               local_orientations.clear();
-       }
-
-
-       size = edge_image.size();
-       Point min, max;
-       min.x = size.width;
-       min.y = size.height;
-       max.x = 0;
-       max.y = 0;
-
-       center = Point(0,0);
-       for (size_t i=0;i<coords.size();++i) {
-               center.x += coords[i].first;
-               center.y += coords[i].second;
-
-               if (min.x>coords[i].first) min.x = coords[i].first;
-               if (min.y>coords[i].second) min.y = coords[i].second;
-               if (max.x<coords[i].first) max.x = coords[i].first;
-               if (max.y<coords[i].second) max.y = coords[i].second;
-       }
-
-       size.width = max.x - min.x;
-       size.height = max.y - min.y;
-       int coords_size = (int)coords.size();
-
-       center.x /= MAX(coords_size, 1);
-       center.y /= MAX(coords_size, 1);
-
-       for (int i=0;i<coords_size;++i) {
-               coords[i].first -= center.x;
-               coords[i].second -= center.y;
-       }
+    template_coords_t local_coords;
+    template_orientations_t local_orientations;
+
+    while (ChamferMatcher::Matching::findContour(edge_image, local_coords)) {
+        ChamferMatcher::Matching::findContourOrientations(local_coords, local_orientations);
+
+        coords.insert(coords.end(), local_coords.begin(), local_coords.end());
+        orientations.insert(orientations.end(), local_orientations.begin(), local_orientations.end());
+        local_coords.clear();
+        local_orientations.clear();
+    }
+
+
+    size = edge_image.size();
+    Point min, max;
+    min.x = size.width;
+    min.y = size.height;
+    max.x = 0;
+    max.y = 0;
+
+    center = Point(0,0);
+    for (size_t i=0;i<coords.size();++i) {
+        center.x += coords[i].first;
+        center.y += coords[i].second;
+
+        if (min.x>coords[i].first) min.x = coords[i].first;
+        if (min.y>coords[i].second) min.y = coords[i].second;
+        if (max.x<coords[i].first) max.x = coords[i].first;
+        if (max.y<coords[i].second) max.y = coords[i].second;
+    }
+
+    size.width = max.x - min.x;
+    size.height = max.y - min.y;
+    int coords_size = (int)coords.size();
+
+    center.x /= MAX(coords_size, 1);
+    center.y /= MAX(coords_size, 1);
+
+    for (int i=0;i<coords_size;++i) {
+        coords[i].first -= center.x;
+        coords[i].second -= center.y;
+    }
 }
 
 
 vector<int>& ChamferMatcher::Template::getTemplateAddresses(int width)
 {
-       if (addr_width!=width) {
-               addr.resize(coords.size());
-               addr_width = width;
-
-               for (size_t i=0; i<coords.size();++i) {
-                       addr[i] = coords[i].second*width+coords[i].first;
-               }
-       }
-       return addr;
+    if (addr_width!=width) {
+        addr.resize(coords.size());
+        addr_width = width;
+
+        for (size_t i=0; i<coords.size();++i) {
+            addr[i] = coords[i].second*width+coords[i].first;
+        }
+    }
+    return addr;
 }
 
 
@@ -843,35 +843,35 @@ vector<int>& ChamferMatcher::Template::getTemplateAddresses(int width)
 ChamferMatcher::Template* ChamferMatcher::Template::rescale(float new_scale)
 {
 
-       if (fabs(scale-new_scale)<1e-6) return this;
+    if (fabs(scale-new_scale)<1e-6) return this;
 
-       for (size_t i=0;i<scaled_templates.size();++i) {
-               if (fabs(scaled_templates[i]->scale-new_scale)<1e-6) {
-                       return scaled_templates[i];
-               }
-       }
+    for (size_t i=0;i<scaled_templates.size();++i) {
+        if (fabs(scaled_templates[i]->scale-new_scale)<1e-6) {
+            return scaled_templates[i];
+        }
+    }
 
-       float scale_factor = new_scale/scale;
+    float scale_factor = new_scale/scale;
 
-       Template* tpl = new Template();
-       tpl->scale = new_scale;
+    Template* tpl = new Template();
+    tpl->scale = new_scale;
 
-       tpl->center.x = int(center.x*scale_factor+0.5);
-       tpl->center.y = int(center.y*scale_factor+0.5);
+    tpl->center.x = int(center.x*scale_factor+0.5);
+    tpl->center.y = int(center.y*scale_factor+0.5);
 
-       tpl->size.width = int(size.width*scale_factor+0.5);
-       tpl->size.height = int(size.height*scale_factor+0.5);
+    tpl->size.width = int(size.width*scale_factor+0.5);
+    tpl->size.height = int(size.height*scale_factor+0.5);
 
-       tpl->coords.resize(coords.size());
-       tpl->orientations.resize(orientations.size());
-       for (size_t i=0;i<coords.size();++i) {
-               tpl->coords[i].first = int(coords[i].first*scale_factor+0.5);
-               tpl->coords[i].second = int(coords[i].second*scale_factor+0.5);
-               tpl->orientations[i] = orientations[i];
-       }
-       scaled_templates.push_back(tpl);
+    tpl->coords.resize(coords.size());
+    tpl->orientations.resize(orientations.size());
+    for (size_t i=0;i<coords.size();++i) {
+        tpl->coords[i].first = int(coords[i].first*scale_factor+0.5);
+        tpl->coords[i].second = int(coords[i].second*scale_factor+0.5);
+        tpl->orientations[i] = orientations[i];
+    }
+    scaled_templates.push_back(tpl);
 
-       return tpl;
+    return tpl;
 
 }
 
@@ -879,42 +879,42 @@ ChamferMatcher::Template* ChamferMatcher::Template::rescale(float new_scale)
 
 void ChamferMatcher::Template::show() const
 {
-       int pad = 50;
-       //Attention size is not correct
-       Mat templ_color (Size(size.width+(pad*2), size.height+(pad*2)), CV_8UC3);
-       templ_color.setTo(0);
+    int pad = 50;
+    //Attention size is not correct
+    Mat templ_color (Size(size.width+(pad*2), size.height+(pad*2)), CV_8UC3);
+    templ_color.setTo(0);
 
-       for (size_t i=0;i<coords.size();++i) {
+    for (size_t i=0;i<coords.size();++i) {
 
-               int x = center.x+coords[i].first+pad;
-               int y = center.y+coords[i].second+pad;
-               templ_color.at<Vec3b>(y,x)[1]=255;
-               //CV_PIXEL(unsigned char, templ_color,x,y)[1] = 255;
+        int x = center.x+coords[i].first+pad;
+        int y = center.y+coords[i].second+pad;
+        templ_color.at<Vec3b>(y,x)[1]=255;
+        //CV_PIXEL(unsigned char, templ_color,x,y)[1] = 255;
 
-               if (i%3==0) {
+        if (i%3==0) {
                         if (orientations[i] < -CV_PI) {
-                               continue;
-                       }
-                       Point p1;
-                       p1.x = x;
-                       p1.y = y;
-                       Point p2;
-                       p2.x = x + pad*(int)(sin(orientations[i])*100)/100;
-                       p2.y = y + pad*(int)(cos(orientations[i])*100)/100;
-
-                       line(templ_color, p1,p2, CV_RGB(255,0,0));
-               }
-       }
+                continue;
+            }
+            Point p1;
+            p1.x = x;
+            p1.y = y;
+            Point p2;
+            p2.x = x + pad*(int)(sin(orientations[i])*100)/100;
+            p2.y = y + pad*(int)(cos(orientations[i])*100)/100;
+
+            line(templ_color, p1,p2, CV_RGB(255,0,0));
+        }
+    }
 
 
-       circle(templ_color,Point(center.x + pad, center.y + pad),1,CV_RGB(0,255,0));
+    circle(templ_color,Point(center.x + pad, center.y + pad),1,CV_RGB(0,255,0));
 
-       namedWindow("templ",1);
-       imshow("templ",templ_color);
+    namedWindow("templ",1);
+    imshow("templ",templ_color);
 
-       cvWaitKey(0);
+    cvWaitKey(0);
 
-       templ_color.release();
+    templ_color.release();
 }
 
 
@@ -923,17 +923,17 @@ void ChamferMatcher::Template::show() const
 
 void ChamferMatcher::Matching::addTemplateFromImage(Mat& templ, float scale)
 {
-       Template* cmt = new Template(templ, scale);
-       if(templates.size() > 0)
-               templates.clear();
-       templates.push_back(cmt);
-       cmt->show();
+    Template* cmt = new Template(templ, scale);
+    if(templates.size() > 0)
+        templates.clear();
+    templates.push_back(cmt);
+    cmt->show();
 }
 
 void ChamferMatcher::Matching::addTemplate(Template& template_){
-       if(templates.size() > 0)
-               templates.clear();
-       templates.push_back(&template_);
+    if(templates.size() > 0)
+        templates.clear();
+    templates.push_back(&template_);
 }
 /**
  * Alternative version of computeDistanceTransform, will probably be used to compute distance
@@ -941,224 +941,227 @@ void ChamferMatcher::Matching::addTemplate(Template& template_){
  */
 void ChamferMatcher::Matching::computeDistanceTransform(Mat& edges_img, Mat& dist_img, Mat& annotate_img, float truncate_dt, float a = 1.0, float b = 1.5)
 {
-       int d[][2] = { {-1,-1}, { 0,-1}, { 1,-1},
-                       {-1,0},          { 1,0},
-                       {-1,1}, { 0,1}, { 1,1} };
+    int d[][2] = { {-1,-1}, { 0,-1}, { 1,-1},
+            {-1,0},          { 1,0},
+            {-1,1}, { 0,1}, { 1,1} };
 
 
-       Size s = edges_img.size();
-       int w = s.width;
-       int h = s.height;
-       // set distance to the edge pixels to 0 and put them in the queue
+    Size s = edges_img.size();
+    int w = s.width;
+    int h = s.height;
+    // set distance to the edge pixels to 0 and put them in the queue
     std::queue<std::pair<int,int> > q;
 
 
 
-       for (int y=0;y<h;++y) {
-               for (int x=0;x<w;++x) {
+    for (int y=0;y<h;++y) {
+        for (int x=0;x<w;++x) {
 
-                       unsigned char edge_val = edges_img.at<uchar>(y,x);
-                       if ( (edge_val!=0) ) {
-                               q.push(std::make_pair(x,y));
-                               dist_img.at<float>(y,x)= 0;
+            unsigned char edge_val = edges_img.at<uchar>(y,x);
+            if ( (edge_val!=0) ) {
+                q.push(std::make_pair(x,y));
+                dist_img.at<float>(y,x)= 0;
 
-                               if (&annotate_img!=NULL) {
-                                       annotate_img.at<Vec2i>(y,x)[0]=x;
-                                       annotate_img.at<Vec2i>(y,x)[1]=y;
-                               }
-                       }
-                       else {
-                               dist_img.at<float>(y,x)=-1;
-                       }
-               }
-       }
+                if (&annotate_img!=NULL) {
+                    annotate_img.at<Vec2i>(y,x)[0]=x;
+                    annotate_img.at<Vec2i>(y,x)[1]=y;
+                }
+            }
+            else {
+                dist_img.at<float>(y,x)=-1;
+            }
+        }
+    }
 
-       // breadth first computation of distance transform
+    // breadth first computation of distance transform
     std::pair<int,int> crt;
-       while (!q.empty()) {
-               crt = q.front();
-               q.pop();
-
-               int x = crt.first;
-               int y = crt.second;
-
-               float dist_orig = dist_img.at<float>(y,x);
-               float dist;
-
-               for (size_t i=0;i<sizeof(d)/sizeof(d[0]);++i) {
-                       int nx = x + d[i][0];
-                       int ny = y + d[i][1];
-
-                       if (nx<0 || ny<0 || nx>=w || ny>=h) continue;
-
-                       if (std::abs(d[i][0]+d[i][1])==1) {
-                               dist = (dist_orig)+a;
-                       }
-                       else {
-                               dist = (dist_orig)+b;
-                       }
-
-                       float dt = dist_img.at<float>(ny,nx);
-
-                       if (dt==-1 || dt>dist) {
-                               dist_img.at<float>(ny,nx) = dist;
-                               q.push(std::make_pair(nx,ny));
-
-                               if (&annotate_img!=NULL) {
-                                       annotate_img.at<Vec2i>(ny,nx)[0]=annotate_img.at<Vec2i>(y,x)[0];
-                                       annotate_img.at<Vec2i>(ny,nx)[1]=annotate_img.at<Vec2i>(y,x)[1];
-                               }
-                       }
-               }
-       }
-       // truncate dt
-
-       if (truncate_dt>0) {
-               Mat dist_img_thr = dist_img.clone();
-               threshold(dist_img, dist_img_thr, truncate_dt,0.0 ,THRESH_TRUNC);
-               dist_img_thr.copyTo(dist_img);
-       }
+    while (!q.empty()) {
+        crt = q.front();
+        q.pop();
+
+        int x = crt.first;
+        int y = crt.second;
+
+        float dist_orig = dist_img.at<float>(y,x);
+        float dist;
+
+        for (size_t i=0;i<sizeof(d)/sizeof(d[0]);++i) {
+            int nx = x + d[i][0];
+            int ny = y + d[i][1];
+
+            if (nx<0 || ny<0 || nx>=w || ny>=h) continue;
+
+            if (std::abs(d[i][0]+d[i][1])==1) {
+                dist = (dist_orig)+a;
+            }
+            else {
+                dist = (dist_orig)+b;
+            }
+
+            float dt = dist_img.at<float>(ny,nx);
+
+            if (dt==-1 || dt>dist) {
+                dist_img.at<float>(ny,nx) = dist;
+                q.push(std::make_pair(nx,ny));
+
+                if (&annotate_img!=NULL) {
+                    annotate_img.at<Vec2i>(ny,nx)[0]=annotate_img.at<Vec2i>(y,x)[0];
+                    annotate_img.at<Vec2i>(ny,nx)[1]=annotate_img.at<Vec2i>(y,x)[1];
+                }
+            }
+        }
+    }
+    // truncate dt
+
+    if (truncate_dt>0) {
+        Mat dist_img_thr = dist_img.clone();
+        threshold(dist_img, dist_img_thr, truncate_dt,0.0 ,THRESH_TRUNC);
+        dist_img_thr.copyTo(dist_img);
+    }
 }
 
 
 void ChamferMatcher::Matching::computeEdgeOrientations(Mat& edge_img, Mat& orientation_img)
 {
-       Mat contour_img(edge_img.size(), CV_8UC1);
+    Mat contour_img(edge_img.size(), CV_8UC1);
 
         orientation_img.setTo(3*(-CV_PI));
-       template_coords_t coords;
-       template_orientations_t orientations;
-
-       while (ChamferMatcher::Matching::findContour(edge_img, coords)) {
-
-               ChamferMatcher::Matching::findContourOrientations(coords, orientations);
-
-               // set orientation pixel in orientation image
-               for (size_t i = 0; i<coords.size();++i) {
-                       int x = coords[i].first;
-                       int y = coords[i].second;
-                        //                     if (orientations[i]>-CV_PI)
-                       //      {
-                       //CV_PIXEL(unsigned char, contour_img, x, y)[0] = 255;
-                       contour_img.at<uchar>(y,x)=255;
-                       //      }
-                       //CV_PIXEL(float, orientation_img, x, y)[0] = orientations[i];
-                       orientation_img.at<float>(y,x)=orientations[i];
-               }
-               
-               
-               coords.clear();
-               orientations.clear();
-       }
-
-       //imwrite("contours.pgm", contour_img);
+    template_coords_t coords;
+    template_orientations_t orientations;
+
+    while (ChamferMatcher::Matching::findContour(edge_img, coords)) {
+
+        ChamferMatcher::Matching::findContourOrientations(coords, orientations);
+
+        // set orientation pixel in orientation image
+        for (size_t i = 0; i<coords.size();++i) {
+            int x = coords[i].first;
+            int y = coords[i].second;
+                        //            if (orientations[i]>-CV_PI)
+            //    {
+            //CV_PIXEL(unsigned char, contour_img, x, y)[0] = 255;
+            contour_img.at<uchar>(y,x)=255;
+            //    }
+            //CV_PIXEL(float, orientation_img, x, y)[0] = orientations[i];
+            orientation_img.at<float>(y,x)=orientations[i];
+        }
+
+
+        coords.clear();
+        orientations.clear();
+    }
+
+    //imwrite("contours.pgm", contour_img);
 }
 
 
 void ChamferMatcher::Matching::fillNonContourOrientations(Mat& annotated_img, Mat& orientation_img)
 {
-       int cols = annotated_img.cols;
-       int rows = annotated_img.rows;
-
-       assert(orientation_img.cols==cols && orientation_img.rows==rows);
-
-       for (int y=0;y<rows;++y) {
-               for (int x=0;x<cols;++x) {
-                       int xorig = annotated_img.at<Vec2i>(y,x)[0];
-                       int yorig = annotated_img.at<Vec2i>(y,x)[1];
-
-                       if (x!=xorig || y!=yorig) {
-                               //orientation_img.at<float>(yorig,xorig)=orientation_img.at<float>(y,x);
-                               orientation_img.at<float>(y,x)=orientation_img.at<float>(yorig,xorig);
-                       }
-               }
-       }
+    int cols = annotated_img.cols;
+    int rows = annotated_img.rows;
+
+    assert(orientation_img.cols==cols && orientation_img.rows==rows);
+
+    for (int y=0;y<rows;++y) {
+        for (int x=0;x<cols;++x) {
+            int xorig = annotated_img.at<Vec2i>(y,x)[0];
+            int yorig = annotated_img.at<Vec2i>(y,x)[1];
+
+            if (x!=xorig || y!=yorig) {
+                //orientation_img.at<float>(yorig,xorig)=orientation_img.at<float>(y,x);
+                orientation_img.at<float>(y,x)=orientation_img.at<float>(yorig,xorig);
+            }
+        }
+    }
 }
 
 
 ChamferMatcher::Match* ChamferMatcher::Matching::localChamferDistance(Point offset, Mat& dist_img, Mat& orientation_img,
-               ChamferMatcher::Template* tpl, float alpha)
+        ChamferMatcher::Template* tpl, float alpha)
 {
-       int x = offset.x;
-       int y = offset.y;
+    int x = offset.x;
+    int y = offset.y;
 
-       float beta = 1-alpha;
+    float beta = 1-alpha;
 
     std::vector<int>& addr = tpl->getTemplateAddresses(dist_img.cols);
 
-       float* ptr = dist_img.ptr<float>(y)+x;
-       
-       
-       float sum_distance = 0;
-       for (size_t i=0; i<addr.size();++i) {
-               if(addr[i] < (dist_img.cols*dist_img.rows) - (offset.y*dist_img.cols + offset.x)){
-                       sum_distance += *(ptr+addr[i]);
-               }
-       }
-
-       float cost = (sum_distance/truncate_)/addr.size();
-       
-
-       if (&orientation_img!=NULL) {
-               float* optr = orientation_img.ptr<float>(y)+x;
-               float sum_orientation = 0;
-               int cnt_orientation = 0;
-
-               for (size_t i=0;i<addr.size();++i) {
-               
-                       if(addr[i] < (orientation_img.cols*orientation_img.rows) - (offset.y*orientation_img.cols + offset.x)){
+    float* ptr = dist_img.ptr<float>(y)+x;
+
+
+    float sum_distance = 0;
+    for (size_t i=0; i<addr.size();++i) {
+        if(addr[i] < (dist_img.cols*dist_img.rows) - (offset.y*dist_img.cols + offset.x)){
+            sum_distance += *(ptr+addr[i]);
+        }
+    }
+
+    float cost = (sum_distance/truncate_)/addr.size();
+
+
+    if (&orientation_img!=NULL) {
+        float* optr = orientation_img.ptr<float>(y)+x;
+        float sum_orientation = 0;
+        int cnt_orientation = 0;
+
+        for (size_t i=0;i<addr.size();++i) {
+
+            if(addr[i] < (orientation_img.cols*orientation_img.rows) - (offset.y*orientation_img.cols + offset.x)){
                                 if (tpl->orientations[i]>=-CV_PI && (*(optr+addr[i]))>=-CV_PI) {
-                                       sum_orientation += orientation_diff(tpl->orientations[i], (*(optr+addr[i])));
-                                       cnt_orientation++;
-                               }
-                       }
-               }
+                    sum_orientation += orientation_diff(tpl->orientations[i], (*(optr+addr[i])));
+                    cnt_orientation++;
+                }
+            }
+        }
 
-               if (cnt_orientation>0) {
+        if (cnt_orientation>0) {
                         cost = (float)(beta*cost+alpha*(sum_orientation/(2*CV_PI))/cnt_orientation);
-               }
+        }
 
-       }
+    }
 
-       if(cost > 0){
-               ChamferMatcher::Match* istance(new ChamferMatcher::Match());
-               istance->cost = cost;
-               istance->offset = offset;
-               istance->tpl = tpl;
+    if(cost > 0){
+        ChamferMatcher::Match* istance = new ChamferMatcher::Match();
+        istance->cost = cost;
+        istance->offset = offset;
+        istance->tpl = tpl;
 
-               return istance;
-       }
+        return istance;
+    }
 
-       return NULL; 
+    return NULL;
 }
 
 
-ChamferMatcher::Matches* ChamferMatcher::Matching::matchTemplates(Mat& dist_img, Mat& orientation_img, const ImageRange& range, float orientation_weight)                      
+ChamferMatcher::Matches* ChamferMatcher::Matching::matchTemplates(Mat& dist_img, Mat& orientation_img, const ImageRange& range, float orientation_weight)
 {
-               
-       ChamferMatcher::Matches* matches(new Matches());
-       // try each template
-       for(size_t i = 0; i < templates.size(); i++) {
-               ImageIterator* it = range.iterator();
-               while (it->hasNext()) {
-                       location_scale_t crt = it->next();
-
-                       Point loc = crt.first;
-                       float scale = crt.second;
-                       Template* tpl = templates[i]->rescale(scale);
-       
-
-                       if (loc.x-tpl->center.x<0 || loc.x+tpl->size.width/2>=dist_img.cols) continue;
-                       if (loc.y-tpl->center.y<0 || loc.y+tpl->size.height/2>=dist_img.rows) continue;
-
-                       ChamferMatcher::Match* is = localChamferDistance(loc, dist_img, orientation_img, tpl, orientation_weight);
-                       if(is)
-                               matches->push_back(*is);
-               }
-
-               delete it;
-       }
-       return matches;
+
+    ChamferMatcher::Matches* matches(new Matches());
+    // try each template
+    for(size_t i = 0; i < templates.size(); i++) {
+        ImageIterator* it = range.iterator();
+        while (it->hasNext()) {
+            location_scale_t crt = it->next();
+
+            Point loc = crt.first;
+            float scale = crt.second;
+            Template* tpl = templates[i]->rescale(scale);
+
+
+            if (loc.x-tpl->center.x<0 || loc.x+tpl->size.width/2>=dist_img.cols) continue;
+            if (loc.y-tpl->center.y<0 || loc.y+tpl->size.height/2>=dist_img.rows) continue;
+
+            ChamferMatcher::Match* is = localChamferDistance(loc, dist_img, orientation_img, tpl, orientation_weight);
+            if(is)
+            {
+                matches->push_back(*is);
+                delete is;
+            }
+        }
+
+        delete it;
+    }
+    return matches;
 }
 
 
@@ -1170,184 +1173,184 @@ ChamferMatcher::Matches* ChamferMatcher::Matching::matchTemplates(Mat& dist_img,
  */
 ChamferMatcher::Matches* ChamferMatcher::Matching::matchEdgeImage(Mat& edge_img, const ImageRange& range, float orientation_weight, int /*max_matches*/, float /*min_match_distance*/)
 {
-       CV_Assert(edge_img.channels()==1);
-
-       Mat dist_img;
-       Mat annotated_img;
-       Mat orientation_img;
-
-       annotated_img.create(edge_img.size(), CV_32SC2);
-       dist_img.create(edge_img.size(),CV_32FC1);
-       dist_img.setTo(0);
-       // Computing distance transform
-       computeDistanceTransform(edge_img,dist_img, annotated_img, truncate_);
-
-
-       //orientation_img = NULL;
-       if (use_orientation_) {
-               orientation_img.create(edge_img.size(), CV_32FC1);
-               orientation_img.setTo(0);
-               Mat edge_clone = edge_img.clone();
-               computeEdgeOrientations(edge_clone, orientation_img );
-               edge_clone.release();
-               fillNonContourOrientations(annotated_img, orientation_img);
-       }
+    CV_Assert(edge_img.channels()==1);
+
+    Mat dist_img;
+    Mat annotated_img;
+    Mat orientation_img;
+
+    annotated_img.create(edge_img.size(), CV_32SC2);
+    dist_img.create(edge_img.size(),CV_32FC1);
+    dist_img.setTo(0);
+    // Computing distance transform
+    computeDistanceTransform(edge_img,dist_img, annotated_img, truncate_);
+
+
+    //orientation_img = NULL;
+    if (use_orientation_) {
+        orientation_img.create(edge_img.size(), CV_32FC1);
+        orientation_img.setTo(0);
+        Mat edge_clone = edge_img.clone();
+        computeEdgeOrientations(edge_clone, orientation_img );
+        edge_clone.release();
+        fillNonContourOrientations(annotated_img, orientation_img);
+    }
 
 
-       // Template matching
-       ChamferMatcher::Matches* matches = matchTemplates(      dist_img, 
-                                                                                                               orientation_img,
-                                                                                                               range, 
-                                                                                                               orientation_weight);
+    // Template matching
+    ChamferMatcher::Matches* matches = matchTemplates(    dist_img,
+                                                        orientation_img,
+                                                        range,
+                                                        orientation_weight);
 
 
-       if (use_orientation_) {
-               orientation_img.release();
-       }
-       dist_img.release();
-       annotated_img.release();
+    if (use_orientation_) {
+        orientation_img.release();
+    }
+    dist_img.release();
+    annotated_img.release();
 
-       return matches;
+    return matches;
 }
 
 
 void ChamferMatcher::addMatch(float cost, Point offset, const Template* tpl)
 {
-       bool new_match = true;
-       for (int i=0; i<count; ++i) {
-               if (std::abs(matches[i].offset.x-offset.x)+std::abs(matches[i].offset.y-offset.y)<min_match_distance_) {
-                       // too close, not a new match
-                       new_match = false;
-                       // if better cost, replace existing match
-                       if (cost<matches[i].cost) {
-                               matches[i].cost = cost;
-                               matches[i].offset = offset;
-                               matches[i].tpl = tpl;
-                       }
-                       // re-bubble to keep ordered
-                       int k = i;
-                       while (k>0) {
-                               if (matches[k-1].cost>matches[k].cost) {
+    bool new_match = true;
+    for (int i=0; i<count; ++i) {
+        if (std::abs(matches[i].offset.x-offset.x)+std::abs(matches[i].offset.y-offset.y)<min_match_distance_) {
+            // too close, not a new match
+            new_match = false;
+            // if better cost, replace existing match
+            if (cost<matches[i].cost) {
+                matches[i].cost = cost;
+                matches[i].offset = offset;
+                matches[i].tpl = tpl;
+            }
+            // re-bubble to keep ordered
+            int k = i;
+            while (k>0) {
+                if (matches[k-1].cost>matches[k].cost) {
                     std::swap(matches[k-1],matches[k]);
-                               }
-                               k--;
-                       }
-
-                       break;
-               }
-       }
-
-       if (new_match) {
-               // if we don't have enough matches yet, add it to the array
-               if (count<max_matches_) {
-                       matches[count].cost = cost;
-                       matches[count].offset = offset;
-                       matches[count].tpl = tpl;
-                       count++;
-               }
-               // otherwise find the right position to insert it
-               else {
-                       // if higher cost than the worst current match, just ignore it
-                       if (matches[count-1].cost<cost) {
-                               return;
-                       }
-
-                       int j = 0;
-                       // skip all matches better than current one
-                       while (matches[j].cost<cost) j++;
-
-                       // shift matches one position
-                       int k = count-2;
-                       while (k>=j) {
-                               matches[k+1] = matches[k];
-                               k--;
-                       }
-
-                       matches[j].cost = cost;
-                       matches[j].offset = offset;
-                       matches[j].tpl = tpl;
-               }
-       }
+                }
+                k--;
+            }
+
+            break;
+        }
+    }
+
+    if (new_match) {
+        // if we don't have enough matches yet, add it to the array
+        if (count<max_matches_) {
+            matches[count].cost = cost;
+            matches[count].offset = offset;
+            matches[count].tpl = tpl;
+            count++;
+        }
+        // otherwise find the right position to insert it
+        else {
+            // if higher cost than the worst current match, just ignore it
+            if (matches[count-1].cost<cost) {
+                return;
+            }
+
+            int j = 0;
+            // skip all matches better than current one
+            while (matches[j].cost<cost) j++;
+
+            // shift matches one position
+            int k = count-2;
+            while (k>=j) {
+                matches[k+1] = matches[k];
+                k--;
+            }
+
+            matches[j].cost = cost;
+            matches[j].offset = offset;
+            matches[j].tpl = tpl;
+        }
+    }
 }
 
 void ChamferMatcher::showMatch(Mat& img, int index)
 {
-       if (index>=count) {
+    if (index>=count) {
         std::cout << "Index too big.\n" << std::endl;
-       }
+    }
 
-       assert(img.channels()==3);
+    assert(img.channels()==3);
 
-       Match match = matches[index];
+    Match match = matches[index];
 
-       const template_coords_t& templ_coords = match.tpl->coords;
-       int x, y;
-       for (size_t i=0;i<templ_coords.size();++i) {
-               x = match.offset.x + templ_coords[i].first;
-               y = match.offset.y + templ_coords[i].second;
+    const template_coords_t& templ_coords = match.tpl->coords;
+    int x, y;
+    for (size_t i=0;i<templ_coords.size();++i) {
+        x = match.offset.x + templ_coords[i].first;
+        y = match.offset.y + templ_coords[i].second;
 
-               if ( x > img.cols-1 || x < 0 || y > img.rows-1 || y < 0) continue;
-               img.at<Vec3b>(y,x)[0]=0;
-               img.at<Vec3b>(y,x)[2]=0;
-               img.at<Vec3b>(y,x)[1]=255;
-       }
+        if ( x > img.cols-1 || x < 0 || y > img.rows-1 || y < 0) continue;
+        img.at<Vec3b>(y,x)[0]=0;
+        img.at<Vec3b>(y,x)[2]=0;
+        img.at<Vec3b>(y,x)[1]=255;
+    }
 }
 
 void ChamferMatcher::showMatch(Mat& img, Match match)
 {
-       assert(img.channels()==3);
-
-       const template_coords_t& templ_coords = match.tpl->coords;
-       for (size_t i=0;i<templ_coords.size();++i) {
-               int x = match.offset.x + templ_coords[i].first;
-               int y = match.offset.y + templ_coords[i].second;
-               if ( x > img.cols-1 || x < 0 || y > img.rows-1 || y < 0) continue;
-               img.at<Vec3b>(y,x)[0]=0;
-               img.at<Vec3b>(y,x)[2]=0;
-               img.at<Vec3b>(y,x)[1]=255;
-       }
-       match.tpl->show();
+    assert(img.channels()==3);
+
+    const template_coords_t& templ_coords = match.tpl->coords;
+    for (size_t i=0;i<templ_coords.size();++i) {
+        int x = match.offset.x + templ_coords[i].first;
+        int y = match.offset.y + templ_coords[i].second;
+        if ( x > img.cols-1 || x < 0 || y > img.rows-1 || y < 0) continue;
+        img.at<Vec3b>(y,x)[0]=0;
+        img.at<Vec3b>(y,x)[2]=0;
+        img.at<Vec3b>(y,x)[1]=255;
+    }
+    match.tpl->show();
 }
 
 const ChamferMatcher::Matches& ChamferMatcher::matching(Template& tpl, Mat& image_){
-       chamfer_->addTemplate(tpl);
+    chamfer_->addTemplate(tpl);
 
-       matches.clear();
-       matches.resize(max_matches_);
-       count = 0;
+    matches.clear();
+    matches.resize(max_matches_);
+    count = 0;
 
 
-       Matches* matches_ = chamfer_->matchEdgeImage(   image_, 
-                                                                                                       ChamferMatcher::
-                                                                                                               SlidingWindowImageRange(image_.cols, 
-                                                                                                                                                               image_.rows,
-                                                                                                                                                               pad_x,
-                                                                                                                                                               pad_y,
-                                                                                                                                                               scales,
-                                                                                                                                                               minScale,
-                                                                                                                                                               maxScale), 
-                                                                                                       orientation_weight, 
-                                                                                                       max_matches_, 
-                                                                                                       min_match_distance_);
+    Matches* matches_ = chamfer_->matchEdgeImage(    image_,
+                                                    ChamferMatcher::
+                                                        SlidingWindowImageRange(image_.cols,
+                                                                                image_.rows,
+                                                                                pad_x,
+                                                                                pad_y,
+                                                                                scales,
+                                                                                minScale,
+                                                                                maxScale),
+                                                    orientation_weight,
+                                                    max_matches_,
+                                                    min_match_distance_);
 
 
-       
-       for(int i = 0; i < (int)matches_->size(); i++){
-               addMatch(matches_->at(i).cost, matches_->at(i).offset, matches_->at(i).tpl);
-       }
 
-       matches_->clear();
-       delete matches_;
-       matches_ = NULL;
+    for(int i = 0; i < (int)matches_->size(); i++){
+        addMatch(matches_->at(i).cost, matches_->at(i).offset, matches_->at(i).tpl);
+    }
 
-       matches.resize(count);
+    matches_->clear();
+    delete matches_;
+    matches_ = NULL;
 
+    matches.resize(count);
 
-       return matches;
+
+    return matches;
 
 }
 
-    
+
 int chamerMatching( Mat& img, Mat& templ,
                     std::vector<std::vector<Point> >& results, std::vector<float>& costs,
                     double templScale, int maxMatches, double minMatchDistance, int padX,
@@ -1355,22 +1358,22 @@ int chamerMatching( Mat& img, Mat& templ,
                     double orientationWeight, double truncate )
 {
     CV_Assert(img.type() == CV_8UC1 && templ.type() == CV_8UC1);
-    
+
     ChamferMatcher matcher_(maxMatches, (float)minMatchDistance, padX, padY, scales,
                             (float)minScale, (float)maxScale,
                             (float)orientationWeight, (float)truncate);
 
     ChamferMatcher::Template template_(templ, (float)templScale);
     ChamferMatcher::Matches match_instances = matcher_.matching(template_, img);
-    
+
     size_t i, nmatches = match_instances.size();
-    
+
     results.resize(nmatches);
     costs.resize(nmatches);
-    
+
     int bestIdx = -1;
     double minCost = DBL_MAX;
-    
+
     for( i = 0; i < nmatches; i++ )
     {
         const ChamferMatcher::Match& match = match_instances[i];
@@ -1381,12 +1384,12 @@ int chamerMatching( Mat& img, Mat& templ,
             bestIdx = (int)i;
         }
         costs[i] = (float)cval;
-        
+
         const template_coords_t& templ_coords = match.tpl->coords;
         std::vector<Point>& templPoints = results[i];
         size_t j, npoints = templ_coords.size();
         templPoints.resize(npoints);
-        
+
         for (j = 0; j < npoints; j++ )
         {
             int x = match.offset.x + templ_coords[j].first;
@@ -1394,7 +1397,7 @@ int chamerMatching( Mat& img, Mat& templ,
             templPoints[j] = Point(x,y);
         }
     }
-    
+
     return bestIdx;
 }