Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
FloodFiller.h
Go to the documentation of this file.
00001 /********************************************************************
00002 **                Image Component Library (ICL)                    **
00003 **                                                                 **
00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld          **
00005 **                         Neuroinformatics Group                  **
00006 ** Website: www.iclcv.org and                                      **
00007 **          http://opensource.cit-ec.de/projects/icl               **
00008 **                                                                 **
00009 ** File   : ICLCV/src/ICLCV/FloodFiller.h                          **
00010 ** Module : ICLCV                                                  **
00011 ** Authors: Christof Elbrechter                                    **
00012 **                                                                 **
00013 **                                                                 **
00014 ** GNU LESSER GENERAL PUBLIC LICENSE                               **
00015 ** This file may be used under the terms of the GNU Lesser General **
00016 ** Public License version 3.0 as published by the                  **
00017 **                                                                 **
00018 ** Free Software Foundation and appearing in the file LICENSE.GPL  **
00019 ** included in the packaging of this file.  Please review the      **
00020 ** following information to ensure the license requirements will   **
00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt                **
00022 **                                                                 **
00023 ** The development of this software was supported by the           **
00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology.    **
00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche       **
00026 ** Forschungsgemeinschaft (DFG) in the context of the German       **
00027 ** Excellence Initiative.                                          **
00028 **                                                                 **
00029 ********************************************************************/
00030 
00031 #pragma once
00032 
00033 #include <ICLCore/Img.h>
00034 
00035 namespace icl{
00036   namespace cv{
00037     
00039 
00069     class FloodFiller{
00071       std::vector<utils::Point> futurePoints;
00072       
00074       utils::Rect prepare(const utils::Size &imageSize, const utils::Point &seed);
00075   
00076       public:
00077   
00079       struct Result{
00080         std::vector<utils::Point> pixels; 
00081         core::Img8u ffLUT;               
00082       } result;
00083       
00085 
00087       const Result &apply(const core::ImgBase *image, const utils::Point &seed, double referenceValue, double threshold);
00088   
00089       
00091 
00093       const Result &applyColor(const core::ImgBase *image, const utils::Point &seed, 
00094                           double refR, double refG, double refB, double threshold);
00095       
00097 
00099       template<class T, class Criterion>
00100       inline const Result &applyGeneric(const core::Img<T> &image, const utils::Point &seed, Criterion crit){
00101         utils::Rect r = prepare(image.getSize(),seed);
00102         
00103         utils::Point *n = futurePoints.data(); // next point to seed from
00104         utils::Point *e = n;                   // end of stored seed points
00105         
00106         *e++ = seed;
00107         
00108         const core::Channel<T> im = image[0];
00109         core::Channel8u ff = result.ffLUT[0];
00110         
00111         ff(seed.x,seed.y) = 255;
00112   
00113         while(n != e){
00114           const int x = n->x;
00115           const int y = n->y;
00116           ++n;
00117           if(crit(im(x,y))){
00118             result.pixels.push_back(utils::Point(x,y));
00119   #define ICL_DYNAMIC_FLOOD_FILLER_P(x,y)                                 \
00120             if(r.contains(x,y) && !ff(x,y)){                              \
00121               *e++ = utils::Point(x,y);                                          \
00122               ff(x,y) = 255;                                              \
00123             }
00124             
00125             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y-1); 
00126             ICL_DYNAMIC_FLOOD_FILLER_P(x,y-1); 
00127             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y-1);
00128             
00129             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y);
00130             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y);
00131             
00132             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y+1); 
00133             ICL_DYNAMIC_FLOOD_FILLER_P(x,y+1); 
00134             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y+1);
00135   #undef ICL_DYNAMIC_FLOOD_FILLER_P
00136           }
00137         }
00138         return result;
00139       }
00140   
00142 
00145       template<class T, class Criterion3Channels>
00146       inline const Result &applyColorGeneric(const core::Img<T> &image, const utils::Point &seed, Criterion3Channels crit){
00147         utils::Rect r = prepare(image.getSize(),seed);
00148         
00149         utils::Point *n = futurePoints.data(); // next point to seed from
00150         utils::Point *e = n;                   // end of stored seed points
00151         
00152         *e++ = seed;
00153         
00154         const core::Channel<T> im0 = image[0];
00155         const core::Channel<T> im1 = image[1];
00156         const core::Channel<T> im2 = image[2];
00157   
00158         core::Channel8u ff = result.ffLUT[0];
00159         
00160         ff(seed.x,seed.y) = 255;
00161   
00162         while(n != e){
00163           const int x = n->x;
00164           const int y = n->y;
00165           ++n;
00166           if(crit(im0(x,y),im1(x,y),im2(x,y))){
00167             result.pixels.push_back(utils::Point(x,y));
00168   #define ICL_DYNAMIC_FLOOD_FILLER_P(x,y)                                 \
00169             if(r.contains(x,y) && !ff(x,y)){                              \
00170               *e++ = utils::Point(x,y);                                          \
00171               ff(x,y) = 255;                                              \
00172             }
00173             
00174             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y-1); 
00175             ICL_DYNAMIC_FLOOD_FILLER_P(x,y-1); 
00176             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y-1);
00177             
00178             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y);
00179             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y);
00180             
00181             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y+1); 
00182             ICL_DYNAMIC_FLOOD_FILLER_P(x,y+1); 
00183             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y+1);
00184   #undef ICL_DYNAMIC_FLOOD_FILLER_P
00185           }
00186         }
00187         return result;
00188       }
00189   
00191       template<class T>
00192       struct DefaultCriterion{
00193         T val;
00194         T thresh;
00195         inline DefaultCriterion(T val, T thresh):val(val),thresh(thresh){}
00196         inline bool operator()(const T &pix) const{
00197           return ::abs(val-pix) < thresh;
00198         }
00199       };
00200   
00202       template<class T>
00203       struct ReferenceColorCriterion{
00204         T refcol[3];
00205         T maxSquaredEuklDist;
00206         
00207         inline ReferenceColorCriterion(T refr, T refg, T refb, T maxEuclDist):
00208           maxSquaredEuklDist(maxEuclDist*maxEuclDist){
00209           refcol[0] = refr;
00210           refcol[1] = refg;
00211           refcol[2] = refb;
00212         }
00213         inline bool operator()( const T &r, const T &g, const T &b) const{
00214           return utils::sqr(r-refcol[0]) + utils::sqr(g-refcol[1]) + utils::sqr(b-refcol[2])  < maxSquaredEuklDist;
00215         }
00216       };
00217     };
00218   
00220     // specialized
00221     template<>
00222     struct FloodFiller::ReferenceColorCriterion<icl8u>{
00223       int refcol[3];
00224       int maxSquaredEuklDist;
00225       
00226       inline ReferenceColorCriterion(icl8u refr, icl8u refg, icl8u refb, int maxEuclDist):
00227       maxSquaredEuklDist(maxEuclDist*maxEuclDist){
00228         refcol[0] = refr;
00229         refcol[1] = refg;
00230         refcol[2] = refb;
00231       }
00232       inline bool operator()( const icl8u &r, const icl8u &g, const icl8u &b) const{
00233         return utils::sqr(int(r)-refcol[0]) + utils::sqr(int(g)-refcol[1]) + utils::sqr(int(b)-refcol[2]) < maxSquaredEuklDist;
00234       }
00235     };
00239   } // namespace cv
00240 }
00241 
00242 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines