[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

shockfilter.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2007-2014 by Benjamin Seppke */
4 /* Cognitive Systems Group, University of Hamburg, Germany */
5 /* */
6 /************************************************************************/
7 
8 #ifndef VIGRA_SHOCKFILTER_HXX
9 #define VIGRA_SHOCKFILTER_HXX
10 
11 #include "basicimage.hxx"
12 #include "convolution.hxx"
13 #include "tensorutilities.hxx"
14 
15 namespace vigra {
16 
17 
18 /********************************************************/
19 /* */
20 /* Coherence enhancing shock filter */
21 /* */
22 /********************************************************/
23 
24 /**
25  This function calculates of the coherence enhancing shock filter proposed by
26  J. Weickert (2002): Coherence-Enhancing Show Filters.
27  It uses the structure tensor information of an image and an iterative discrete upwinding scheme
28  instead of pure dilation and erosion to perform the necessary morphological operations
29  on the image.
30 */
31 //@{
32 
33 /** \brief This function calculates discrete upwinding scheme proposed by J. Weickert (2002) in Coherence-Enhancing Show Filters.
34 
35  An image is upwinded positively (dilation), if the given second src is positive.
36  Otherwise it is upwinds negatively (eroded). The effect can be steered by an upwinding
37  factor.
38 
39 
40  <b> Declarations:</b>
41 
42  pass 2D array views:
43  \code
44  namespace vigra {
45  template <class T1, class S1,
46  class T2, class S2
47  class T3, class S3>
48  void
49  upwindImage(MultiArrayView<2, T1, S1> const & src,
50  MultiArrayView<2, T2, S2> const & src2,
51  MultiArrayView<2, T3, S3> dest,
52  float upwind_factor_h);
53 
54  }
55  \endcode
56 
57  \deprecatedAPI{upwindImage}
58  pass \ref ImageIterators and \ref DataAccessors :
59  \code
60  namespace vigra {
61  template <class SrcIterator, class SrcAccessor,
62  class Src2Iterator, class Src2Accessor,
63  class DestIterator, class DestAccessor>
64  void upwindImage(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
65  Src2Iterator s2_ul, Src2Accessor s2_acc,
66  DestIterator d_ul, DestAccessor d_acc,
67  float upwind_factor_h)
68  }
69  \endcode
70  use argument objects in conjunction with \ref ArgumentObjectFactories :
71  \code
72  namespace vigra {
73  template <class SrcIterator, class SrcAccessor,
74  class Src2Iterator, class Src2Accessor,
75  class DestIterator, class DestAccessor>
76  void
77  upwindImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
78  pair<Src2Iterator, Src2Accessor> src2,
79  pair<DestIterator, DestAccessor> dest,
80  float upwind_factor_h);
81  }
82  \endcode
83  \deprecatedEnd
84 */
85 
86 
87 doxygen_overloaded_function(template <...> void upwindImage)
88 
89 template <class SrcIterator, class SrcAccessor,
90  class Src2Iterator, class Src2Accessor,
91  class DestIterator, class DestAccessor>
92 void upwindImage(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
93  Src2Iterator s2_ul, Src2Accessor s2_acc,
94  DestIterator d_ul, DestAccessor d_acc,
95  float upwind_factor_h)
96 {
97  using namespace std;
98 
99  typedef typename SrcIterator::difference_type DiffType;
100 
101  DiffType shape = s_lr - s_ul;
102 
103  typedef typename SrcAccessor::value_type SrcType;
104  typedef typename DestAccessor::value_type ResultType;
105 
106  SrcType upper, lower, left, right, center;
107  ResultType fx, fy;
108 
109 
110  for(int y=0; y<shape[1]; ++y)
111  {
112  for(int x=0; x<shape[0]; ++x)
113  {
114  upper = s_acc(s_ul + Diff2D(x, max(0, y-1)));
115  lower = s_acc(s_ul + Diff2D(x, min(shape[1]-1, y+1)));
116  left = s_acc(s_ul + Diff2D(max(0, x-1), y));
117  right = s_acc(s_ul + Diff2D(min(shape[0]-1, x+1), y));
118  center = s_acc(s_ul + Diff2D(x, y));
119 
120  if(s2_acc(s2_ul+Diff2D(x,y))<0)
121  {
122  fx = max(max(right - center, left - center), 0.0f);
123  fy = max(max(lower - center, upper - center), 0.0f);
124  d_acc.set (center + upwind_factor_h*sqrt( fx*fx + fy*fy), d_ul+Diff2D(x,y));
125  }
126  else
127  {
128  fx = max(max(center - right, center - left), 0.0f);
129  fy = max(max(center - lower, center - upper), 0.0f);
130  d_acc.set (center - upwind_factor_h*sqrt( fx*fx + fy*fy), d_ul+Diff2D(x,y));
131  }
132  }
133  }
134 }
135 
136 template <class SrcIterator, class SrcAccessor,
137  class Src2Iterator, class Src2Accessor,
138  class DestIterator, class DestAccessor>
139 inline void upwindImage(triple<SrcIterator, SrcIterator, SrcAccessor> s,
140  pair<Src2Iterator, Src2Accessor> s2,
141  pair<DestIterator, DestAccessor> d,
142  float upwind_factor_h)
143 {
144  upwindImage(s.first, s.second, s.third, s2.first, s2.second, d.first, d.second, upwind_factor_h);
145 }
146 
147 template <class T1, class S1,
148  class T2, class S2,
149  class T3, class S3>
150 inline void upwindImage(MultiArrayView<2, T1, S1> const & src,
151  MultiArrayView<2, T2, S2> const & src2,
152  MultiArrayView<2, T3, S3> dest,
153  float upwind_factor_h)
154 {
155  vigra_precondition(src.shape() == src2.shape() && src.shape() == dest.shape(),
156  "vigra::upwindImage(): shape mismatch between input and output.");
157  upwindImage(srcImageRange(src),
158  srcImage(src2),
159  destImage(dest),
160  upwind_factor_h);
161 }
162 
163 
164 /** \brief This function calculates of the coherence enhancing shock filter proposed by J. Weickert (2002) in Coherence-Enhancing Show Filters.
165 
166  <b> Declarations:</b>
167 
168  pass 2D array views:
169  \code
170  namespace vigra {
171  template <class T1, class S1,
172  class T2, class S2>
173  void
174  shockFilter(MultiArrayView<2, T1, S1> const & src,
175  MultiArrayView<2, T2, S2> dest,
176  float sigma, float rho, float upwind_factor_h,
177  unsigned int iterations);
178 
179  }
180  \endcode
181 
182  \deprecatedAPI{shockFilter}
183  pass \ref ImageIterators and \ref DataAccessors :
184  \code
185  namespace vigra {
186  template <class SrcIterator, class SrcAccessor,
187  class DestIterator, class DestAccessor>
188  void shockFilter(SrcIterator supperleft,
189  SrcIterator slowerright, SrcAccessor sa,
190  DestIterator dupperleft, DestAccessor da,
191  float sigma, float rho, float upwind_factor_h,
192  unsigned int iterations);
193  }
194  \endcode
195  use argument objects in conjunction with \ref ArgumentObjectFactories :
196  \code
197  namespace vigra {
198  template <class SrcIterator, class SrcAccessor,
199  class DestIterator, class DestAccessor>
200  void
201  shockFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
202  pair<DestIterator, DestAccessor> dest,
203  float sigma, float rho, float upwind_factor_h,
204  unsigned int iterations);
205  }
206  \endcode
207  \deprecatedEnd
208 
209  <b> Usage:</b>
210 
211  <b>\#include</b> <vigra/shockilter.hxx><br/>
212  Namespace: vigra
213 
214  \code
215  unsigned int w=1000, h=1000;
216  MultiArray<2, float> src(w,h), dest(w,h);
217  ...
218 
219 
220 
221  // apply a shock-filter:
222  shockFilter(src, dest, 1.0, 5.0, 0.3, 5);
223  \endcode
224 
225  <b> Preconditions:</b>
226 
227  The image must be larger than the window size of the filter.
228 */
229 
230 doxygen_overloaded_function(template <...> void upwindImage)
231 
232 template <class SrcIterator, class SrcAccessor,
233  class DestIterator, class DestAccessor>
234 void shockFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
235  DestIterator d_ul, DestAccessor d_acc,
236  float sigma, float rho, float upwind_factor_h,
237  unsigned int iterations)
238 {
239 
240  typedef typename SrcIterator::difference_type DiffType;
241  DiffType shape = s_lr - s_ul;
242 
243  unsigned int w = shape[0],
244  h = shape[1];
245 
246  FVector3Image tensor(w,h);
247  FVector3Image eigen(w,h);
248  FImage hxx(w,h), hxy(w,h), hyy(w,h), temp(w,h) ,result(w,h);
249 
250  float c, s, v_xx, v_xy, v_yy;
251 
252  copyImage(srcIterRange(s_ul, s_lr, s_acc), destImage(result));
253 
254  for(unsigned int i = 0; i<iterations; ++i)
255  {
256 
257  structureTensor(srcImageRange(result), destImage(tensor), sigma, rho);
258  tensorEigenRepresentation(srcImageRange(tensor), destImage(eigen));
259  hessianMatrixOfGaussian(srcImageRange(result),
260  destImage(hxx), destImage(hxy), destImage(hyy), sigma);
261 
262  for(int y=0; y<shape[1]; ++y)
263  {
264  for(int x=0; x<shape[0]; ++x)
265  {
266  c = cos(eigen(x,y)[2]);
267  s = sin(eigen(x,y)[2]);
268  v_xx = hxx(x,y);
269  v_xy = hxy(x,y);
270  v_yy = hyy(x,y);
271  //store signum image in hxx (safe, because no other will ever access hxx(x,y)
272  hxx(x,y) = c*c*v_xx + 2*c*s*v_xy + s*s*v_yy;
273  }
274  }
275  upwindImage(srcImageRange(result),srcImage(hxx), destImage(temp), upwind_factor_h);
276  result = temp;
277 
278  }
279  copyImage(srcImageRange(result), destIter(d_ul, d_acc));
280 }
281 
282 template <class SrcIterator, class SrcAccessor,
283  class DestIterator, class DestAccessor>
284 inline void shockFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
285  pair<DestIterator, DestAccessor> d,
286  float sigma, float rho, float upwind_factor_h,
287  unsigned int iterations)
288 {
289  shockFilter(s.first, s.second, s.third,
290  d.first, d.second,
291  sigma, rho, upwind_factor_h,
292  iterations);
293 }
294 
295 template <class T1, class S1,
296  class T2, class S2>
297 inline void shockFilter(MultiArrayView<2, T1, S1> const & src,
298  MultiArrayView<2, T2, S2> dest,
299  float sigma, float rho, float upwind_factor_h,
300  unsigned int iterations)
301 {
302  vigra_precondition(src.shape() == dest.shape(),
303  "vigra::shockFilter(): shape mismatch between input and output.");
304  shockFilter(srcImageRange(src),
305  destImage(dest),
306  sigma, rho, upwind_factor_h,
307  iterations);
308 }
309 
310 } //end of namespace vigra
311 
312 #endif //VIGRA_SHOCKFILTER_HXX
void upwindImage(...)
This function calculates discrete upwinding scheme proposed by J. Weickert (2002) in Coherence-Enhanc...
BasicImage< float > FImage
Definition: stdimage.hxx:143
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
BasicImage< TinyVector< float, 3 > > FVector3Image
Definition: stdimage.hxx:286
void tensorEigenRepresentation(...)
Calculate eigen representation of a symmetric 2x2 tensor.
void hessianMatrixOfGaussian(...)
Filter image with the 2nd derivatives of the Gaussian at the given scale to get the Hessian matrix...
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void copyImage(...)
Copy source image into destination image.
void structureTensor(...)
Calculate the Structure Tensor for each pixel of and image, using Gaussian (derivative) filters...
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)