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.LGPL **
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 <ICLUtils/CompatMacros.h>
00034 #include <ICLCore/Img.h>
00035 
00036 namespace icl{
00037   namespace cv{
00038     
00040 
00070     class ICLCV_API FloodFiller{
00072       std::vector<utils::Point> futurePoints;
00073       
00075       utils::Rect prepare(const utils::Size &imageSize, const utils::Point &seed);
00076   
00077       public:
00078   
00080       struct ICLCV_API Result{
00081         std::vector<utils::Point> pixels; 
00082         core::Img8u ffLUT;               
00083       } result;
00084       
00086 
00088       const Result &apply(const core::ImgBase *image, const utils::Point &seed, double referenceValue, double threshold);
00089   
00090       
00092 
00094       const Result &applyColor(const core::ImgBase *image, const utils::Point &seed, 
00095                           double refR, double refG, double refB, double threshold);
00096       
00098 
00100       template<class T, class Criterion>
00101       inline const Result &applyGeneric(const core::Img<T> &image, const utils::Point &seed, Criterion crit){
00102         utils::Rect r = prepare(image.getSize(),seed);
00103         
00104         utils::Point *n = futurePoints.data(); // next point to seed from
00105         utils::Point *e = n;                   // end of stored seed points
00106         
00107         *e++ = seed;
00108         
00109         const core::Channel<T> im = image[0];
00110         core::Channel8u ff = result.ffLUT[0];
00111         
00112         ff(seed.x,seed.y) = 255;
00113   
00114         while(n != e){
00115           const int x = n->x;
00116           const int y = n->y;
00117           ++n;
00118           if(crit(im(x,y))){
00119             result.pixels.push_back(utils::Point(x,y));
00120   #define ICL_DYNAMIC_FLOOD_FILLER_P(x,y)                                 \
00121             if(r.contains(x,y) && !ff(x,y)){                              \
00122               *e++ = utils::Point(x,y);                                          \
00123               ff(x,y) = 255;                                              \
00124             }
00125             
00126             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y-1); 
00127             ICL_DYNAMIC_FLOOD_FILLER_P(x,y-1); 
00128             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y-1);
00129             
00130             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y);
00131             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y);
00132             
00133             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y+1); 
00134             ICL_DYNAMIC_FLOOD_FILLER_P(x,y+1); 
00135             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y+1);
00136   #undef ICL_DYNAMIC_FLOOD_FILLER_P
00137           }
00138         }
00139         return result;
00140       }
00141   
00143 
00146       template<class T, class Criterion3Channels>
00147       inline const Result &applyColorGeneric(const core::Img<T> &image, const utils::Point &seed, Criterion3Channels crit){
00148         utils::Rect r = prepare(image.getSize(),seed);
00149         
00150         utils::Point *n = futurePoints.data(); // next point to seed from
00151         utils::Point *e = n;                   // end of stored seed points
00152         
00153         *e++ = seed;
00154         
00155         const core::Channel<T> im0 = image[0];
00156         const core::Channel<T> im1 = image[1];
00157         const core::Channel<T> im2 = image[2];
00158   
00159         core::Channel8u ff = result.ffLUT[0];
00160         
00161         ff(seed.x,seed.y) = 255;
00162   
00163         while(n != e){
00164           const int x = n->x;
00165           const int y = n->y;
00166           ++n;
00167           if(crit(im0(x,y),im1(x,y),im2(x,y))){
00168             result.pixels.push_back(utils::Point(x,y));
00169   #define ICL_DYNAMIC_FLOOD_FILLER_P(x,y)                                 \
00170             if(r.contains(x,y) && !ff(x,y)){                              \
00171               *e++ = utils::Point(x,y);                                          \
00172               ff(x,y) = 255;                                              \
00173             }
00174             
00175             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y-1); 
00176             ICL_DYNAMIC_FLOOD_FILLER_P(x,y-1); 
00177             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y-1);
00178             
00179             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y);
00180             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y);
00181             
00182             ICL_DYNAMIC_FLOOD_FILLER_P(x-1,y+1); 
00183             ICL_DYNAMIC_FLOOD_FILLER_P(x,y+1); 
00184             ICL_DYNAMIC_FLOOD_FILLER_P(x+1,y+1);
00185   #undef ICL_DYNAMIC_FLOOD_FILLER_P
00186           }
00187         }
00188         return result;
00189       }
00190   
00192       template<class T>
00193       struct DefaultCriterion{
00194         T val;
00195         T thresh;
00196         inline DefaultCriterion(T val, T thresh):val(val),thresh(thresh){}
00197         inline bool operator()(const T &pix) const{
00198           return ::abs(val-pix) < thresh;
00199         }
00200       };
00201   
00203       template<class T>
00204       struct ReferenceColorCriterion{
00205         T refcol[3];
00206         T maxSquaredEuklDist;
00207         
00208         inline ReferenceColorCriterion(T refr, T refg, T refb, T maxEuclDist):
00209           maxSquaredEuklDist(maxEuclDist*maxEuclDist){
00210           refcol[0] = refr;
00211           refcol[1] = refg;
00212           refcol[2] = refb;
00213         }
00214         inline bool operator()( const T &r, const T &g, const T &b) const{
00215           return utils::sqr(r-refcol[0]) + utils::sqr(g-refcol[1]) + utils::sqr(b-refcol[2])  < maxSquaredEuklDist;
00216         }
00217       };
00218     };
00219   
00221     // specialized
00222     template<>
00223     struct FloodFiller::ReferenceColorCriterion<icl8u>{
00224       int refcol[3];
00225       int maxSquaredEuklDist;
00226       
00227       inline ReferenceColorCriterion(icl8u refr, icl8u refg, icl8u refb, int maxEuclDist):
00228       maxSquaredEuklDist(maxEuclDist*maxEuclDist){
00229         refcol[0] = refr;
00230         refcol[1] = refg;
00231         refcol[2] = refb;
00232       }
00233       inline bool operator()( const icl8u &r, const icl8u &g, const icl8u &b) const{
00234         return utils::sqr(int(r)-refcol[0]) + utils::sqr(int(g)-refcol[1]) + utils::sqr(int(b)-refcol[2]) < maxSquaredEuklDist;
00235       }
00236     };
00240   } // namespace cv
00241 }
00242 
00243 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines