37 #ifndef VIGRA_MULTI_BLOCKWISE_HXX
38 #define VIGRA_MULTI_BLOCKWISE_HXX
42 #include "multi_blocking.hxx"
43 #include "multi_convolution.hxx"
44 #include "multi_tensorutilities.hxx"
45 #include "threadpool.hxx"
46 #include "array_vector.hxx"
77 Shape readBlockShape()
const
91 if(blockShape_.
size() > 1)
93 vigra_precondition(blockShape_.
size() == (size_t)N,
94 "BlockwiseOptions::getBlockShapeN(): dimension mismatch between N and stored block shape.");
97 else if(blockShape_.
size() == 1)
103 return detail::ChunkShape<N>::defaultShape();
126 template <
class T,
int N>
128 Shape(blockShape.
begin(), blockShape.
end()).swap(blockShape_);
135 Shape(1, blockShape).swap(blockShape_);
145 void setNumThreads(
const int n)
159 template<
unsigned int N>
180 class T_IN,
class ST_IN,
181 class T_OUT,
class ST_OUT,
182 class FILTER_FUNCTOR,
185 void blockwiseCallerNoRoiApi(
188 FILTER_FUNCTOR & functor,
194 typedef typename MultiBlocking<DIM, C>::BlockWithBorder BlockWithBorder;
196 auto beginIter = blocking.blockWithBorderBegin(borderWidth);
197 auto endIter = blocking.blockWithBorderEnd(borderWidth);
201 [&](
const int ,
const BlockWithBorder bwb)
209 functor(sourceSub, destSub);
212 bwb.localCore().end());
214 dest.
subarray(bwb.core().begin()-blocking.roiBegin(),
215 bwb.core().end() -blocking.roiBegin() ) = destSubCore;
229 class T_IN,
class ST_IN,
230 class T_OUT,
class ST_OUT,
231 class FILTER_FUNCTOR,
234 void blockwiseCaller(
237 FILTER_FUNCTOR & functor,
240 const BlockwiseConvolutionOptions<DIM> & options
243 typedef typename MultiBlocking<DIM, C>::BlockWithBorder BlockWithBorder;
245 typedef typename MultiBlocking<DIM, C>::Block Block;
248 auto beginIter = blocking.blockWithBorderBegin(borderWidth);
249 auto endIter = blocking.blockWithBorderEnd(borderWidth);
253 [&](
const int ,
const BlockWithBorder bwb)
261 const Block localCore = bwb.localCore();
263 functor(sourceSub, destCore, localCore.
begin(), localCore.end());
271 #define CONVOLUTION_FUNCTOR(FUNCTOR_NAME, FUNCTION_NAME) \
272 template<unsigned int DIM> \
273 class FUNCTOR_NAME{ \
275 typedef ConvolutionOptions<DIM> ConvOpt; \
276 FUNCTOR_NAME(const ConvOpt & convOpt) \
277 : sharedOpt_(convOpt){} \
278 template<class S, class D> \
279 void operator()(const S & s, D & d)const{ \
280 FUNCTION_NAME(s, d, sharedOpt_); \
282 template<class S, class D,class SHAPE> \
283 void operator()(const S & s, D & d, const SHAPE & roiBegin, const SHAPE & roiEnd){ \
284 ConvOpt localOpt(sharedOpt_); \
285 localOpt.subarray(roiBegin, roiEnd); \
286 FUNCTION_NAME(s, d, localOpt); \
289 ConvOpt sharedOpt_; \
302 #undef CONVOLUTION_FUNCTOR
304 template<
unsigned int DIM>
305 class HessianOfGaussianEigenvaluesFunctor{
307 typedef ConvolutionOptions<DIM> ConvOpt;
308 HessianOfGaussianEigenvaluesFunctor(
const ConvOpt & convOpt)
309 : sharedOpt_(convOpt){}
310 template<
class S,
class D>
311 void operator()(
const S & s, D & d)
const{
312 typedef typename vigra::NumericTraits<typename S::value_type>::RealPromote RealType;
313 vigra::MultiArray<DIM, TinyVector<RealType, int(DIM*(DIM+1)/2)> > hessianOfGaussianRes(d.shape());
317 template<
class S,
class D,
class SHAPE>
318 void operator()(
const S & s, D & d,
const SHAPE & roiBegin,
const SHAPE & roiEnd){
319 typedef typename vigra::NumericTraits<typename S::value_type>::RealPromote RealType;
320 vigra::MultiArray<DIM, TinyVector<RealType, int(DIM*(DIM+1)/2)> > hessianOfGaussianRes(roiEnd-roiBegin);
321 ConvOpt localOpt(sharedOpt_);
322 localOpt.subarray(roiBegin, roiEnd);
330 template<
unsigned int DIM,
unsigned int EV>
331 class HessianOfGaussianSelectedEigenvalueFunctor{
333 typedef ConvolutionOptions<DIM> ConvOpt;
334 HessianOfGaussianSelectedEigenvalueFunctor(
const ConvOpt & convOpt)
335 : sharedOpt_(convOpt){}
336 template<
class S,
class D>
337 void operator()(
const S & s, D & d)
const{
338 typedef typename vigra::NumericTraits<typename S::value_type>::RealPromote RealType;
341 vigra::MultiArray<DIM, TinyVector<RealType, int(DIM*(DIM+1)/2)> > hessianOfGaussianRes(s.shape());
347 d = allEigenvalues.bindElementChannel(EV);
349 template<
class S,
class D,
class SHAPE>
350 void operator()(
const S & s, D & d,
const SHAPE & roiBegin,
const SHAPE & roiEnd){
352 typedef typename vigra::NumericTraits<typename S::value_type>::RealPromote RealType;
355 vigra::MultiArray<DIM, TinyVector<RealType, int(DIM*(DIM+1)/2)> > hessianOfGaussianRes(roiEnd-roiBegin);
356 ConvOpt localOpt(sharedOpt_);
357 localOpt.subarray(roiBegin, roiEnd);
363 d = allEigenvalues.bindElementChannel(EV);
370 template<
unsigned int DIM>
371 class HessianOfGaussianFirstEigenvalueFunctor
372 :
public HessianOfGaussianSelectedEigenvalueFunctor<DIM, 0>{
374 typedef ConvolutionOptions<DIM> ConvOpt;
375 HessianOfGaussianFirstEigenvalueFunctor(
const ConvOpt & convOpt)
376 : HessianOfGaussianSelectedEigenvalueFunctor<DIM, 0>(convOpt){}
379 template<
unsigned int DIM>
380 class HessianOfGaussianLastEigenvalueFunctor
381 :
public HessianOfGaussianSelectedEigenvalueFunctor<DIM, DIM-1>{
383 typedef ConvolutionOptions<DIM> ConvOpt;
384 HessianOfGaussianLastEigenvalueFunctor(
const ConvOpt & convOpt)
385 : HessianOfGaussianSelectedEigenvalueFunctor<DIM, DIM-1>(convOpt){}
395 template<
unsigned int N>
397 const BlockwiseConvolutionOptions<N> & opt,
399 const bool usesOuterScale =
false
403 if(opt.getFilterWindowSize()<=0.00001){
404 for(
size_t d=0; d<N; ++d){
405 double stdDev = opt.getStdDev()[d];
407 stdDev += opt.getOuterScale()[d];
408 res[d] =
static_cast<MultiArrayIndex>(3.0 * stdDev + 0.5*
static_cast<double>(order)+0.5);
412 throw std::runtime_error(
"blockwise filters do not allow a user defined FilterWindowSize");
419 #define VIGRA_BLOCKWISE(FUNCTOR, FUNCTION, ORDER, USES_OUTER_SCALE) \
420 template <unsigned int N, class T1, class S1, class T2, class S2> \
422 MultiArrayView<N, T1, S1> const & source, \
423 MultiArrayView<N, T2, S2> dest, \
424 BlockwiseConvolutionOptions<N> const & options \
427 typedef MultiBlocking<N, vigra::MultiArrayIndex> Blocking; \
428 typedef typename Blocking::Shape Shape; \
429 const Shape border = blockwise::getBorder(options, ORDER, USES_OUTER_SCALE); \
430 BlockwiseConvolutionOptions<N> subOptions(options); \
431 subOptions.subarray(Shape(0), Shape(0)); \
432 const Blocking blocking(source.shape(), options.template getBlockShapeN<N>()); \
433 blockwise::FUNCTOR<N> f(subOptions); \
434 blockwise::blockwiseCaller(source, dest, f, blocking, border, options); \
442 VIGRA_BLOCKWISE(HessianOfGaussianEigenvaluesFunctor, hessianOfGaussianEigenvaluesMultiArray, 2,
false );
443 VIGRA_BLOCKWISE(HessianOfGaussianFirstEigenvalueFunctor, hessianOfGaussianFirstEigenvalueMultiArray, 2,
false );
444 VIGRA_BLOCKWISE(HessianOfGaussianLastEigenvalueFunctor, hessianOfGaussianLastEigenvalueMultiArray, 2,
false );
446 VIGRA_BLOCKWISE(GaussianGradientMagnitudeFunctor, gaussianGradientMagnitudeMultiArray, 1,
false );
449 #undef VIGRA_BLOCKWISE
452 template <
unsigned int N,
class T1,
class S1,
class T2,
class S2>
455 MultiArrayView<N, T1, S1>
const & source,
456 MultiArrayView<N, T2, S2> dest,
457 BlockwiseConvolutionOptions<N>
const & options)
459 gaussianGradientMagnitudeMultiArray(source, dest, options);
465 #endif // VIGRA_MULTI_BLOCKWISE_HXX
void symmetricGradientMultiArray(...)
Calculate gradient of a multi-dimensional arrays using symmetric difference filters.
size_t numBlocks() const
total number of blocks
Definition: multi_blocking.hxx:225
const difference_type & shape() const
Definition: multi_array.hxx:1648
void gaussianDivergenceMultiArray(...)
Calculate the divergence of a vector field using Gaussian derivative filters.
int getNumThreads() const
Get desired number of threads.
Definition: threadpool.hxx:85
iterator begin()
Definition: multi_array.hxx:1921
Main MultiArray class containing the memory management.
Definition: multi_array.hxx:2474
iterator end()
Definition: tinyvector.hxx:864
ParallelOptions & numThreads(const int n)
Set the number of threads or one of the constants Auto, Nice and NoThreads.
Definition: threadpool.hxx:111
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
BlockwiseOptions & blockShape(MultiArrayIndex blockShape)
Definition: multi_blockwise.hxx:134
Definition: multi_blocking.hxx:49
void gaussianGradientMultiArray(...)
Calculate Gaussian gradient of a multi-dimensional arrays.
void laplacianOfGaussianMultiArray(...)
Calculate Laplacian of a N-dimensional arrays using Gaussian derivative filters.
TinyVector< MultiArrayIndex, N > getBlockShapeN() const
Definition: multi_blockwise.hxx:89
iterator begin()
Definition: tinyvector.hxx:861
vigra::GridGraph< N, DirectedTag >::vertex_descriptor source(typename vigra::GridGraph< N, DirectedTag >::edge_descriptor const &e, vigra::GridGraph< N, DirectedTag > const &g)
Get a vertex descriptor for the start vertex of edge e in graph g (API: boost).
Definition: multi_gridgraph.hxx:2943
void gaussianGradientMagnitude(...)
Calculate the gradient magnitude by means of a 1st derivatives of Gaussian filter.
Definition: multi_blockwise.hxx:54
Options class template for convolutions.
Definition: multi_convolution.hxx:335
void parallel_foreach(...)
Apply a functor to all items in a range in parallel.
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
Option base class for parallel algorithms.
Definition: threadpool.hxx:61
Shape const & getBlockShape() const
Definition: multi_blockwise.hxx:71
BlockwiseOptions & blockShape(const TinyVector< T, N > &blockShape)
Definition: multi_blockwise.hxx:127
Definition: multi_blockwise.hxx:160
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:704
const_pointer data() const
Definition: array_vector.hxx:209
size_type size() const
Definition: array_vector.hxx:358
void gaussianSmoothMultiArray(...)
Isotropic Gaussian smoothing of a multi-dimensional arrays.
MultiArrayView subarray(difference_type p, difference_type q) const
Definition: multi_array.hxx:1528
void hessianOfGaussianMultiArray(...)
Calculate Hessian matrix of a N-dimensional arrays using Gaussian derivative filters.
void tensorEigenvaluesMultiArray(...)
Calculate the tensor eigenvalues for every element of a N-D tensor array.
BlockwiseOptions & blockShape(const Shape &blockShape)
Definition: multi_blockwise.hxx:114
void structureTensorMultiArray(...)
Calculate the structure tensor of a multi-dimensional arrays.