Image Component Library (ICL)
RegionGrower.h
Go to the documentation of this file.
1 /********************************************************************
2 ** Image Component Library (ICL) **
3 ** **
4 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld **
5 ** Neuroinformatics Group **
6 ** Website: www.iclcv.org and **
7 ** http://opensource.cit-ec.de/projects/icl **
8 ** **
9 ** File : ICLCV/src/ICLCV/RegionGrower.h **
10 ** Module : ICLCV **
11 ** Authors: Andre Ueckermann **
12 ** **
13 ** **
14 ** GNU LESSER GENERAL PUBLIC LICENSE **
15 ** This file may be used under the terms of the GNU Lesser General **
16 ** Public License version 3.0 as published by the **
17 ** **
18 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
19 ** included in the packaging of this file. Please review the **
20 ** following information to ensure the license requirements will **
21 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt **
22 ** **
23 ** The development of this software was supported by the **
24 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. **
25 ** The Excellence Cluster EXC 277 is a grant of the Deutsche **
26 ** Forschungsgemeinschaft (DFG) in the context of the German **
27 ** Excellence Initiative. **
28 ** **
29 ********************************************************************/
30 
31 #pragma once
32 
33 #include <ICLMath/FixedVector.h>
34 #include <ICLCore/Img.h>
35 #include <ICLCore/DataSegment.h>
37 #include <ICLUtils/Exception.h>
38 
39 namespace icl{
40  namespace cv{
41 
43 
47  class RegionGrower{
48 
49  public:
50 
52 
59  template<class Criterion>
60  const core::Img32s &apply(const core::Img8u &image, Criterion crit, core::Img8u *initialMask = 0,
61  const unsigned int minSize=0, const unsigned int startID=1){
62  this->result=core::Img32s(image.getParams());
63  //this->mask=Img8u(image.getParams());
64  core::Img8u &useMask = initialMask ? *initialMask : this->mask;
65  if(image.getChannels() == 1){
66  region_grow<core::Img8u,icl8u,1, Criterion>(image, useMask, this->result, crit, minSize, startID);
67  }else{
68  throw utils::ICLException("wrong number of image channels");
69  }
70  return this->result;
71  }
72 
74 
81  const core::Img32s &applyColorImageGrowing(const core::Img8u &image, float const th, core::Img8u *initialMask = 0,
82  const unsigned int minSize=0, const unsigned int startID=1){
83  this->result=core::Img32s(image.getSize(),1);
84  //this->mask=Img8u(image.getParams());
85  core::Img8u &useMask = initialMask ? *initialMask : this->mask;
86  if(image.getChannels() == 3){
87  region_grow<core::Img8u,icl8u,3, U8EuclideanDistance>(image, useMask, this->result, U8EuclideanDistance(th), minSize, startID);
88  }else{
89  throw utils::ICLException("wrong number of image channels");
90  }
91  return this->result;
92  }
93 
95 
102  template<class Criterion>
103  const core::Img32s &apply(const core::DataSegment<float,4> &dataseg, Criterion crit, core::Img8u *initialMask = 0,
104  const unsigned int minSize=0, const unsigned int startID=1){
105  core::Img8u &useMask = initialMask ? *initialMask : this->mask;
106  this->result.setSize(dataseg.getSize());
107  this->result.setChannels(1);
108  region_grow<core::DataSegment<float,4>,float,4, Criterion>(dataseg, useMask, this->result, crit, minSize, startID);
109  return this->result;
110  }
111 
112 
114 
122  const int threshold, const unsigned int minSize=0, const unsigned int startID=1){
123  return apply(dataseg, Float4EuclideanDistance(threshold), &mask, minSize, startID);
124  }
125 
126 
128 
135  const core::Img32s &applyEqualThreshold(const core::Img8u &image, core::Img8u mask, const int threshold,
136  const unsigned int minSize=0, const unsigned int startID=1){
137  return apply(image, EqualThreshold(threshold), &mask, minSize, startID);
138  }
139 
140 
142 
144  std::vector<std::vector<int> > getRegions(){
145  return regions;
146  }
147 
148 
149  private:
150 
153  std::vector<std::vector<int> > regions;
154 
155  template<class T, class DataT, int DIM>
158  int w() const { return 0; }
159  int h() const { return 0; }
161  };
162 
165  return sqrt( c[0]*c[0] + c[1]*c[1] + c[2]*c[2] );
166  }
167 
169  float t;
172  return dist3u8(a,b) < t;
173  }
174  };
175 
177  int t;
178  EqualThreshold(int t):t(t){}
179  bool operator()(icl8u a, icl8u b) const{
180  return (int)b == t;
181  }
182  };
183 
184 
186  float t;
189  return math::dist3(a,b) < t;
190  }
191  };
192 
193 
194  template<class T, class DataT, int DIM, class Criterion>
195  static void flood_fill(const RegionGrowerDataAccessor<T,DataT,DIM> &a, int xStart, int yStart,
196  core::Channel8u &processed, Criterion crit, std::vector<int> &result, core::Channel32s &result2, int id);
197 
198 
199  template<class T, class DataT, int DIM, class Criterion>
200  void region_grow(const T &data, core::Img8u &mask, core::Img32s &result, Criterion crit, const unsigned int minSize, const unsigned int startID=1){
202 
203  core::Img8u processed = mask;
204  core::Channel8u p = processed[0];
205  std::vector<int> r;
206  core::Channel32s res = result[0];
207  result.fill(0);
208 
209  int nextID = startID;
210  regions.clear();
211 
212  std::vector<std::vector<int> > clear;
213 
214  for(int y=0;y<a.h();++y){
215  for(int x=0;x<a.w();++x){
216  if(!p(x,y) && crit(a(x,y),a(x,y))){
217  r.clear();
218  flood_fill<T,DataT,DIM,Criterion>(a ,x ,y ,p, crit, r, res, nextID++);
219  if(r.size()<minSize){
220  nextID--;
221  clear.push_back(r);//delete later
222  }else{
223  regions.push_back(r);//add region
224  }
225  }
226  }
227  }
228 
229  //clear regions smaller minSize
230  for(unsigned int i=0; i<clear.size(); i++){
231  for(unsigned int j=0; j<clear.at(i).size(); j++){
232  p[clear.at(i).at(j)]=false;
233  res[clear.at(i).at(j)]=0;
234  }
235  }
236  }
237 
238  };
239 
240 
241  template<>
243  const core::Channel8u c;
244  RegionGrowerDataAccessor(const core::Img8u &image):c(image[0]){}
245  int w() const { return c.getWidth(); }
246  int h() const { return c.getHeight(); }
248  };
249 
250  template<>
252  core::Channel8u c[3];
254  for(int i=0;i<3;++i){
255  c[i] = ((core::Img8u&)image)[i];
256  }
257  }
258  int w() const { return c[0].getWidth(); }
259  int h() const { return c[0].getHeight(); }
261  return math::FixedColVector<icl8u,3>(c[0](x,y), c[1](x,y), c[2](x,y));
262  }
263  };
264 
265  template<>
266  struct RegionGrower::RegionGrowerDataAccessor<core::DataSegment<float,4>, float, 4>{
268  int ww,hh;
270  ww = data.getSize().width;
271  hh = data.getSize().height;
272  }
273  int w() const { return ww; }
274  int h() const { return hh; }
275  math::FixedColVector<float,4> operator()(int x, int y) const { return data(x,y); }
276  };
277 
278  template<class T, class DataT, int DIM, class Criterion>
280  core::Channel8u &processed, Criterion crit, std::vector<int> &result, core::Channel32s &result2, int id){
281  std::vector<utils::Point> stack(1,utils::Point(xStart,yStart));
282  processed(xStart,yStart) = true;//update mask
283  result2(xStart,yStart) = id;//update result image
284  result.push_back(xStart+yStart*a.w());//add to region vector
285  unsigned int next = 0;
286  while(next < stack.size()){
287  const utils::Point p = stack[next];
288  next++;
289  for(int dy=-1;dy<=1;++dy){
290  const int y = p.y+dy;
291  if(y < 0 || y >=a.h()) continue;
292  for(int dx=-1;dx<=1;++dx){
293  const int x = p.x+dx;
294  if(x < 0 || x >=a.w()) continue;
295  if(dx==0 && dy==0) continue;
296 
297  if(crit(a(p.x,p.y),a(x,y)) && processed(x,y)==false){
298  stack.push_back(utils::Point(x,y));
299  processed(x,y) = true;
300  result2(x,y) = id;
301  result.push_back(x+y*a.w());
302  }
303  }
304  }
305  }
306  }
307 
308  } // namespace cv
309 }
core::DataSegment< float, 4 > data
Definition: RegionGrower.h:267
std::vector< std::vector< int > > regions
Definition: RegionGrower.h:153
ICLQt_API ImgQ sqrt(const ImgQ &image)
calls sqrt( each pixel)
int t
Definition: RegionGrower.h:177
const ImgParams & getParams() const
returns all params in terms of a const ImgParams reference
Definition: ImgBase.h:473
static void flood_fill(const RegionGrowerDataAccessor< T, DataT, DIM > &a, int xStart, int yStart, core::Channel8u &processed, Criterion crit, std::vector< int > &result, core::Channel32s &result2, int id)
Definition: RegionGrower.h:279
Definition: RegionGrower.h:168
virtual void setSize(const utils::Size &s)
resizes the image to new values
undocument this line if you encounter any issues!
Definition: Any.h:37
int h() const
Definition: RegionGrower.h:159
bool operator()(icl8u a, icl8u b) const
Definition: RegionGrower.h:179
Ipp8u icl8u
8Bit unsigned integer type for the ICL
Definition: BasicTypes.h:64
const core::Img32s & applyFloat4EuclideanDistance(const core::DataSegment< float, 4 > &dataseg, core::Img8u mask, const int threshold, const unsigned int minSize=0, const unsigned int startID=1)
Applies the region growing on an input data segment with euclidean distance criterion.
Definition: RegionGrower.h:121
math::FixedColVector< DataT, DIM > operator()(int x, int y) const
Definition: RegionGrower.h:160
Img< icl32s > Img32s
typedef for 8bit integer images
Definition: Types.h:51
virtual void setChannels(int iNewNumChannels)
sets the channel count to a new value
const core::Img32s & apply(const core::Img8u &image, Criterion crit, core::Img8u *initialMask=0, const unsigned int minSize=0, const unsigned int startID=1)
Applies the region growing on an input image with a growing criterion.
Definition: RegionGrower.h:60
void region_grow(const T &data, core::Img8u &mask, core::Img32s &result, Criterion crit, const unsigned int minSize, const unsigned int startID=1)
Definition: RegionGrower.h:200
EqualThreshold(int t)
Definition: RegionGrower.h:178
const core::Channel8u c
Definition: RegionGrower.h:243
const core::Img32s & applyColorImageGrowing(const core::Img8u &image, float const th, core::Img8u *initialMask=0, const unsigned int minSize=0, const unsigned int startID=1)
Applies the region growing on an input image with a growing criterion.
Definition: RegionGrower.h:81
math::FixedColVector< icl8u, 3 > operator()(int x, int y) const
Definition: RegionGrower.h:260
ICLQt_API ImgROI data(ImgQ &r)
creates full ROI ROI-struct
float t
Definition: RegionGrower.h:169
RegionGrowerDataAccessor(const core::DataSegment< float, 4 > &data)
Definition: RegionGrower.h:269
Img< icl8u > Img8u
typedef for 8bit integer images
Definition: Types.h:42
float t
Definition: RegionGrower.h:186
std::vector< std::vector< int > > getRegions()
Returns a vector of regions containing the image IDs. This is an additional representation of the res...
Definition: RegionGrower.h:144
int w() const
Definition: RegionGrower.h:158
utils::Size getSize() const
returns the ordred size of the segment of utils::Size::null if it's not organized
Definition: DataSegmentBase.h:141
const core::Img32s & apply(const core::DataSegment< float, 4 > &dataseg, Criterion crit, core::Img8u *initialMask=0, const unsigned int minSize=0, const unsigned int startID=1)
Applies the region growing on an input data segment with a growing criterion.
Definition: RegionGrower.h:103
U8EuclideanDistance(float t)
Definition: RegionGrower.h:170
RegionGrowerDataAccessor(const core::Img8u &image)
Definition: RegionGrower.h:244
Point class of the ICL used e.g. for the Images ROI offset.
Definition: Point.h:58
static float dist3u8(const math::FixedColVector< icl8u, 3 > &a, const math::FixedColVector< icl8u, 3 > &b)
Definition: RegionGrower.h:163
Definition: FixedVector.h:40
int getChannels() const
returns the channel count of the image
Definition: ImgBase.h:489
const core::Img32s & applyEqualThreshold(const core::Img8u &image, core::Img8u mask, const int threshold, const unsigned int minSize=0, const unsigned int startID=1)
Applies the region growing on an input image with value-equals-threshold criterion.
Definition: RegionGrower.h:135
Base class for Exception handling in the ICL.
Definition: Exception.h:42
RegionGrowerDataAccessor(const T &t)
Definition: RegionGrower.h:157
bool operator()(const math::FixedColVector< float, 4 > &a, const math::FixedColVector< float, 4 > &b) const
Definition: RegionGrower.h:188
bool operator()(const math::FixedColVector< icl8u, 3 > &a, const math::FixedColVector< icl8u, 3 > &b) const
Definition: RegionGrower.h:171
RegionGrowerDataAccessor(const core::Img8u &image)
Definition: RegionGrower.h:253
void fill(const T &value)
fills the whole image with given source type value
Definition: Img.h:1322
Definition: RegionGrower.h:176
core::Img8u mask
Definition: RegionGrower.h:151
class for region growing on images and DataSegments (e.g. poincloud xyzh)
Definition: RegionGrower.h:47
math::FixedColVector< float, 4 > operator()(int x, int y) const
Definition: RegionGrower.h:275
Float4EuclideanDistance(float t)
Definition: RegionGrower.h:187
math::FixedColVector< icl8u, 1 > operator()(int x, int y) const
Definition: RegionGrower.h:247
The Img class implements the ImgBase Image interface with type specific functionalities .
Definition: Img.h:49
core::Img32s result
Definition: RegionGrower.h:152
float dist3(const Vec4 &a, const Vec4 &b)
3d euclidian distance
Definition: HomogeneousMath.h:179
const utils::Size & getSize() const
returns the size of the images
Definition: ImgBase.h:477