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.