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,
243 typedef typename MultiBlocking<DIM, C>::BlockWithBorder BlockWithBorder;
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{
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;
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 localOpt(sharedOpt_);
322 localOpt.subarray(roiBegin, roiEnd);
330 template<
unsigned int DIM,
unsigned int EV>
331 class HessianOfGaussianSelectedEigenvalueFunctor{
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;
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;
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>{
375 HessianOfGaussianFirstEigenvalueFunctor(
const ConvOpt & convOpt)
376 : HessianOfGaussianSelectedEigenvalueFunctor<DIM, 0>(convOpt){}
379 template<
unsigned int DIM>
380 class HessianOfGaussianLastEigenvalueFunctor
381 :
public HessianOfGaussianSelectedEigenvalueFunctor<DIM, DIM-1>{
384 HessianOfGaussianLastEigenvalueFunctor(
const ConvOpt & convOpt)
385 : HessianOfGaussianSelectedEigenvalueFunctor<DIM, DIM-1>(convOpt){}
395 template<
unsigned int N>
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>
459 gaussianGradientMagnitudeMultiArray(source, dest, options);
465 #endif // VIGRA_MULTI_BLOCKWISE_HXX size_t numBlocks() const
total number of blocks
Definition: multi_blocking.hxx:225
TinyVector< MultiArrayIndex, N > getBlockShapeN() const
Definition: multi_blockwise.hxx:89
void symmetricGradientMultiArray(...)
Calculate gradient of a multi-dimensional arrays using symmetric difference filters.
void gaussianDivergenceMultiArray(...)
Calculate the divergence of a vector field using Gaussian derivative filters.
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
MultiArrayView subarray(difference_type p, difference_type q) const
Definition: multi_array.hxx:1528
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.
const difference_type & shape() const
Definition: multi_array.hxx:1648
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.
const_pointer data() const
Definition: array_vector.hxx:209
Definition: multi_blockwise.hxx:54
Options class template for convolutions.
Definition: multi_convolution.hxx:335
Shape const & getBlockShape() const
Definition: multi_blockwise.hxx:71
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
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
void gaussianSmoothMultiArray(...)
Isotropic Gaussian smoothing of a multi-dimensional arrays.
size_type size() const
Definition: array_vector.hxx:358
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
int getNumThreads() const
Get desired number of threads.
Definition: threadpool.hxx:85
void structureTensorMultiArray(...)
Calculate the structure tensor of a multi-dimensional arrays.