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 threadId,
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,
243 typedef typename MultiBlocking<DIM, C>::BlockWithBorder BlockWithBorder;
248 auto beginIter = blocking.blockWithBorderBegin(borderWidth);
249 auto endIter = blocking.blockWithBorderEnd(borderWidth);
253 [&](
const int threadId,
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 : convOpt_(convOpt){} \ 278 template<class S, class D> \ 279 void operator()(const S & s, D & d)const{ \ 280 FUNCTION_NAME(s, d, convOpt_); \ 282 template<class S, class D,class SHAPE> \ 283 void operator()(const S & s, D & d, const SHAPE & roiBegin, const SHAPE & roiEnd){ \ 284 ConvOpt convOpt(convOpt_); \ 285 convOpt.subarray(roiBegin, roiEnd); \ 286 FUNCTION_NAME(s, d, convOpt); \ 302 #undef CONVOLUTION_FUNCTOR 304 template<
unsigned int DIM>
305 class HessianOfGaussianEigenvaluesFunctor{
308 HessianOfGaussianEigenvaluesFunctor(
const ConvOpt & convOpt)
309 : convOpt_(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;
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;
321 convOpt_.subarray(roiBegin, roiEnd);
329 template<
unsigned int DIM,
unsigned int EV>
330 class HessianOfGaussianSelectedEigenvalueFunctor{
333 HessianOfGaussianSelectedEigenvalueFunctor(
const ConvOpt & convOpt)
334 : convOpt_(convOpt){}
335 template<
class S,
class D>
336 void operator()(
const S & s, D & d)
const{
337 typedef typename vigra::NumericTraits<typename S::value_type>::RealPromote RealType;
346 d = allEigenvalues.bindElementChannel(EV);
348 template<
class S,
class D,
class SHAPE>
349 void operator()(
const S & s, D & d,
const SHAPE & roiBegin,
const SHAPE & roiEnd){
351 typedef typename vigra::NumericTraits<typename S::value_type>::RealPromote RealType;
355 convOpt_.subarray(roiBegin, roiEnd);
361 d = allEigenvalues.bindElementChannel(EV);
368 template<
unsigned int DIM>
369 class HessianOfGaussianFirstEigenvalueFunctor
370 :
public HessianOfGaussianSelectedEigenvalueFunctor<DIM, 0>{
373 HessianOfGaussianFirstEigenvalueFunctor(
const ConvOpt & convOpt)
374 : HessianOfGaussianSelectedEigenvalueFunctor<DIM, 0>(convOpt){}
377 template<
unsigned int DIM>
378 class HessianOfGaussianLastEigenvalueFunctor
379 :
public HessianOfGaussianSelectedEigenvalueFunctor<DIM, DIM-1>{
382 HessianOfGaussianLastEigenvalueFunctor(
const ConvOpt & convOpt)
383 : HessianOfGaussianSelectedEigenvalueFunctor<DIM, DIM-1>(convOpt){}
393 template<
unsigned int N>
397 const bool usesOuterScale =
false 401 if(opt.getFilterWindowSize()<=0.00001){
402 for(
size_t d=0; d<N; ++d){
403 double stdDev = opt.getStdDev()[d];
405 stdDev += opt.getOuterScale()[d];
406 res[d] =
static_cast<MultiArrayIndex>(3.0 * stdDev + 0.5*
static_cast<double>(order)+0.5);
410 throw std::runtime_error(
"blockwise filters do not allow a user defined FilterWindowSize");
417 #define VIGRA_BLOCKWISE(FUNCTOR, FUNCTION, ORDER, USES_OUTER_SCALE) \ 418 template <unsigned int N, class T1, class S1, class T2, class S2> \ 420 MultiArrayView<N, T1, S1> const & source, \ 421 MultiArrayView<N, T2, S2> dest, \ 422 BlockwiseConvolutionOptions<N> const & options \ 425 typedef MultiBlocking<N, vigra::MultiArrayIndex> Blocking; \ 426 typedef typename Blocking::Shape Shape; \ 427 const Shape border = blockwise::getBorder(options, ORDER, USES_OUTER_SCALE); \ 428 BlockwiseConvolutionOptions<N> subOptions(options); \ 429 subOptions.subarray(Shape(0), Shape(0)); \ 430 const Blocking blocking(source.shape(), options.template getBlockShapeN<N>()); \ 431 blockwise::FUNCTOR<N> f(subOptions); \ 432 blockwise::blockwiseCaller(source, dest, f, blocking, border, options); \ 440 VIGRA_BLOCKWISE(HessianOfGaussianEigenvaluesFunctor, hessianOfGaussianEigenvaluesMultiArray, 2,
false );
441 VIGRA_BLOCKWISE(HessianOfGaussianFirstEigenvalueFunctor, hessianOfGaussianFirstEigenvalueMultiArray, 2,
false );
442 VIGRA_BLOCKWISE(HessianOfGaussianLastEigenvalueFunctor, hessianOfGaussianLastEigenvalueMultiArray, 2,
false );
444 VIGRA_BLOCKWISE(GaussianGradientMagnitudeFunctor, gaussianGradientMagnitudeMultiArray, 1,
false );
447 #undef VIGRA_BLOCKWISE 450 template <
unsigned int N,
class T1,
class S1,
class T2,
class S2>
457 gaussianGradientMagnitudeMultiArray(source, dest, options);
463 #endif // VIGRA_MULTI_BLOCKWISE_HXX size_t numBlocks() const
total number of blocks
Definition: multi_blocking.hxx:225
const difference_type & shape() const
Definition: multi_array.hxx:1596
void gaussianSmoothMultiArray(...)
Isotropic Gaussian smoothing of a multi-dimensional arrays.
void gaussianGradientMagnitude(...)
Calculate the gradient magnitude by means of a 1st derivatives of Gaussian filter.
int getNumThreads() const
Get desired number of threads.
Definition: threadpool.hxx:90
iterator begin()
Definition: multi_array.hxx:1869
void laplacianOfGaussianMultiArray(...)
Calculate Laplacian of a N-dimensional arrays using Gaussian derivative filters.
Main MultiArray class containing the memory management.
Definition: multi_array.hxx:2422
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:116
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
BlockwiseOptions & blockShape(MultiArrayIndex blockShape)
Definition: multi_blockwise.hxx:134
Definition: multi_blocking.hxx:49
Definition: accessor.hxx:43
void gaussianDivergenceMultiArray(...)
Calculate the divergence of a vector field using Gaussian derivative filters.
void gaussianGradientMultiArray(...)
Calculate Gaussian gradient of a multi-dimensional arrays.
TinyVector< MultiArrayIndex, N > getBlockShapeN() const
Definition: multi_blockwise.hxx:89
iterator begin()
Definition: tinyvector.hxx:861
void symmetricGradientMultiArray(...)
Calculate gradient of a multi-dimensional arrays using symmetric difference filters.
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
Definition: multi_blockwise.hxx:54
Options class template for convolutions.
Definition: multi_convolution.hxx:332
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:66
void hessianOfGaussianMultiArray(...)
Calculate Hessian matrix of a N-dimensional arrays using Gaussian derivative filters.
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:652
const_pointer data() const
Definition: array_vector.hxx:209
size_type size() const
Definition: array_vector.hxx:358
MultiArrayView subarray(difference_type p, difference_type q) const
Definition: multi_array.hxx:1476
void structureTensorMultiArray(...)
Calculate th structure tensor of a multi-dimensional arrays.
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