Image Component Library (ICL)
LocalThresholdOpHelpers.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 : ICLFilter/src/ICLFilter/LocalThresholdOpHelpers.h **
10 ** Module : ICLFilter **
11 ** Authors: Christof Elbrechter **
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 <stdint.h>
34 
35 namespace icl{
36  namespace filter{
37  namespace {
38  template<class TT>
39  struct ThreshType{ typedef TT T; };
40 
41  template<> struct ThreshType<uint8_t> { typedef int T; };
42  template<> struct ThreshType<int16_t> { typedef int T; };
43  template<> struct ThreshType<int32_t> { typedef int T; };
44  template<> struct ThreshType<float> { typedef float T; };
45  template<> struct ThreshType<double> { typedef double T; };
46 
47  inline float lt_clip_float(float f) { return f > 255 ? 255 : f < 0 ? 0 : f; }
48 
49  typedef uint8_t lt_icl8u;
50  typedef int16_t lt_icl16s;
51  typedef int32_t lt_icl32s;
52  typedef float lt_icl32f;
53  typedef double lt_icl64f;
54  }
56 
59  template<class TS, class TI, class TD, class TT, bool WITH_GAMMA>
60  void fast_lt(const TS *psrc, const TI *ii, TD *pdst, int w, int h, int r, TT t, float gs, int channel);
61 
63 
65  template<class TS, class TI, class TD, class TT, bool WITH_GAMMA>
66  void fast_lt_impl(const TS *psrc, const TI *ii, TD *pdst, int w, int h, int r, TT t, float gs, int channel){
67  const int r2 = 2*r;
68  const int yEnd = h-r;
69  const int dim = r2*r2;
70  t*=dim; // help to avoid /dim in the loop
71 
72  /* Explanation
73  B-----C
74  | |
75  | x<-|--- here we are mean value in rect is B - C - D + A
76  | |
77  D-----A
78 
79  Image parts for all border Regions (id = 1..8) we have to
80  work with a pixel dependend rectangle dimension
81 
82  1| 2 |3
83  -------------------
84  | |
85  4| CENTER |5
86  | |
87  -------------------
88  6| 7 |8
89  */
90 
91 #define GET_II(x,y) ii[(x)+(y)*w]
92 #define GET_A(rx,ry,rw,rh) GET_II((rx+rw),(ry+rh))
93 #define GET_B(rx,ry,rw,rh) GET_II((rx),(ry))
94 #define GET_C(rx,ry,rw,rh) GET_II((rx+rw),(ry))
95 #define GET_D(rx,ry,rw,rh) GET_II((rx),(ry+rh))
96 
97 #define GET_RECT(rx,ry,rw,rh) (GET_B((rx),(ry),(rw),(rh)) - GET_C((rx),(ry),(rw),(rh)) - GET_D((rx),(ry),(rw),(rh)) + GET_A((rx),(ry),(rw),(rh)) + t)
98 #define COMPLEX_STEP(rx,ry,rw,rh) pdst[x+w*y] = (!WITH_GAMMA) ? \
99  (255 * (psrc[x+w*y]*((rw)*(rh)) > (GET_RECT((rx),(ry),(rw),(rh)))) ) : \
100  ((TD)lt_clip_float( gs * (psrc[x+w*y] - float(GET_RECT((rx),(ry),(rw),(rh)))/((rw)*(rh)) ) + 128))
101 
102 
103  // [1][2][3]
104  for(int y=0;y<r;++y){
105  for(int x=0;x<r;++x){ //[1]
106  COMPLEX_STEP(0,0,r+x,r+y);
107  }
108  for(int x=r;x<w-r;++x){ //[2]
109  COMPLEX_STEP(x-r,0,r2,r+y);
110  }
111  for(int x=w-r;x<w;++x){ //[3]
112  COMPLEX_STEP(x-r,0,w+r-x-1,y+r);
113  }
114  }
115 
116  // [4][CENTER][5]
117  for(int y=r; y<yEnd; ++y){
118  //[4]
119  for(int x=0;x<r;++x){
120  COMPLEX_STEP(0,y-r,x+r,r2);
121  }
122 
123  // [CENTER]
124  const TI *B = ii+(y-r)*w;
125  const TI *C = B + r2;
126  const TI *D = B + r2*w;
127  const TI *A = D + r2;
128  const TS *s = psrc+y*w + r;
129  TD *d = pdst+y*w + r;
130  const TS *ends = s+w-r2;
131 
132 #define STEP *d = (!WITH_GAMMA) ? \
133  (255 * ( (*s*dim) > (*B - *C - *D + *A + t))) : \
134  ((TD)lt_clip_float( gs * (*s - float(*B - *C - *D + *A + t)/dim ) + 128)) \
135  ; ++B; ++C; ++D; ++A; ++s; ++d;
136 
137  // 16x loop unrolling here
138  for(int n = ((int)(ends-s)) >> 4; n > 0; --n){
141  }
142 
143  while(s<ends){
144  STEP
145  }
146 #undef STEP
147  //[5]
148  for(int x=w-r;x<w;++x){
149  COMPLEX_STEP(x-r,y-r,w+r-x-1,r2);
150  }
151  }
152 
153  // [6][7][8]
154  for(int y=h-r;y<h;++y){
155  for(int x=0;x<r;++x){ //[6]
156  COMPLEX_STEP(0,y-r,r+x,h+r-y-1);
157  }
158  for(int x=r;x<w-r;++x){ //[7]
159  COMPLEX_STEP(x-r,y-r,r2,h+r-y-1);
160  }
161  for(int x=w-r;x<w;++x){ //[8]
162  COMPLEX_STEP(x-r,y-r,w+r-x-1,h+r-y-1);
163  }
164  }
165 #undef GET_II
166 #undef GET_A
167 #undef GET_B
168 #undef GET_C
169 #undef GET_D
170 #undef GET_RECT
171 #undef COMPLEX_STEP
172  }
173  }
174 }
175 
176 #define FAST_LT_DEFINITION \
177  template<class TS, class TI, class TD, class TT, bool WITH_GAMMA> \
178  void fast_lt(const TS *psrc, const TI *iim, TD *pdst, int w, int h, \
179  int r, TT t, float gs, int channel){ \
180  fast_lt_impl<TS,TI,TD,TT,WITH_GAMMA>(psrc,iim,pdst,w,h,r,t,gs,channel); \
181  }
182 
183 #define INST_FAST_LT(TS,TI,TD,WITH_GAMMA) \
184  template void fast_lt<lt_icl##TS,lt_icl##TI,lt_icl##TD, \
185  ThreshType<lt_icl##TS>::T,WITH_GAMMA> \
186  (const lt_icl##TS*, const lt_icl##TI*, lt_icl##TD*, int, int, \
187  int, ThreshType<lt_icl##TS>::T,float,int)
188 
189 #define INST_FAST_LT_FOR_SRC_TYPE(SRC,WITH_GAMMA) \
190  INST_FAST_LT(SRC,32s,8u,WITH_GAMMA); \
191  INST_FAST_LT(SRC,32f,8u,WITH_GAMMA); \
192  INST_FAST_LT(SRC,64f,8u,WITH_GAMMA); \
193  INST_FAST_LT(SRC,32s,16s,WITH_GAMMA); \
194  INST_FAST_LT(SRC,32f,16s,WITH_GAMMA); \
195  INST_FAST_LT(SRC,64f,16s,WITH_GAMMA); \
196  INST_FAST_LT(SRC,32s,32s,WITH_GAMMA); \
197  INST_FAST_LT(SRC,32f,32s,WITH_GAMMA); \
198  INST_FAST_LT(SRC,64f,32s,WITH_GAMMA); \
199  INST_FAST_LT(SRC,32s,32f,WITH_GAMMA); \
200  INST_FAST_LT(SRC,32f,32f,WITH_GAMMA); \
201  INST_FAST_LT(SRC,64f,32f,WITH_GAMMA); \
202  INST_FAST_LT(SRC,32s,64f,WITH_GAMMA); \
203  INST_FAST_LT(SRC,32f,64f,WITH_GAMMA); \
204  INST_FAST_LT(SRC,64f,64f,WITH_GAMMA);
205 
206 
undocument this line if you encounter any issues!
Definition: Any.h:37
#define STEP
ICLQt_API core::Img< T > filter(const core::Img< T > &image, const std::string &filter)
applies a filter operation on the source image (affinity for float)
#define COMPLEX_STEP(rx, ry, rw, rh)
ICLQt_API ImgQ channel(const ImgQ &image, int channel)
picks a specific image channel
void fast_lt(const TS *psrc, const TI *ii, TD *pdst, int w, int h, int r, TT t, float gs, int channel)
Internally used helper function.
void fast_lt_impl(const TS *psrc, const TI *ii, TD *pdst, int w, int h, int r, TT t, float gs, int channel)
Internally used helper function.
Definition: LocalThresholdOpHelpers.h:66