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

blockwise_convolution.hxx |

1 #ifndef VIGRA_BLOCKWISE_CONVOLUTION_HXX_
2 #define VIGRA_BLOCKWISE_CONVOLUTION_HXX_
3
4 #include <vigra/overlapped_blocks.hxx>
5 #include <vigra/multi_convolution.hxx>
6 #include <vigra/blockify.hxx>
7 #include <vigra/multi_array.hxx>
8
9 namespace vigra
10 {
11
12 namespace blockwise_convolution_detail
13 {
14
15 template <class DataArray, class OutputBlocksIterator, class KernelIterator>
16 void convolveImpl(const Overlaps<DataArray>& overlaps, OutputBlocksIterator output_blocks_begin, KernelIterator kit)
17 {
18 static const unsigned int N = DataArray::actual_dimension;
19 typedef typename MultiArrayShape<N>::type Shape;
20 typedef typename OutputBlocksIterator::value_type OutputBlock;
21
22 Shape shape = overlaps.shape();
23 vigra_assert(shape == output_blocks_begin.shape(), "");
24
25 MultiCoordinateIterator<N> it(shape);
26 MultiCoordinateIterator<N> end = it.getEndIterator();
27 for( ; it != end; ++it)
28 {
29 OutputBlock output_block = output_blocks_begin[*it];
30 OverlappingBlock<DataArray> data_block = overlaps[*it];
31 separableConvolveMultiArray(data_block.block, output_block, kit, data_block.inner_bounds.first, data_block.inner_bounds.second);
32 }
33 }
34
35 template <class Shape, class KernelIterator>
36 std::pair<Shape, Shape> kernelOverlap(KernelIterator kit)
37 {
38 Shape before;
39 Shape after;
40
41 for(unsigned int i = 0; i != Shape::static_size; ++i, ++kit)
42 {
43 // FIXME: is this correct?
44 before[i] = kit->right();
45 after[i] = -kit->left();
46 }
47 return std::make_pair(before, after);
48 }
49
50 }
51
52
53 template <unsigned int N, class T1, class S1,
54 class T2, class S2,
55 class KernelIterator>
56 void separableConvolveBlockwise(MultiArrayView<N, T1, S1> source, MultiArrayView<N, T2, S2> dest, KernelIterator kit,
57 const typename MultiArrayView<N, T1, S1>::difference_type& block_shape =
58 typename MultiArrayView<N, T1, S1>::difference_type(128))
59 {
60 using namespace blockwise_convolution_detail;
61
62 typedef typename MultiArrayView<N, T1, S1>::difference_type Shape;
63
64 Shape shape = source.shape();
65 vigra_precondition(shape == dest.shape(), "shape mismatch of source and destination");
66
67 std::pair<Shape, Shape> overlap = kernelOverlap<Shape, KernelIterator>(kit);
68 Overlaps<MultiArrayView<N, T2, S2> > overlaps(source, block_shape, overlap.first, overlap.second);
69
70 MultiArray<N, MultiArrayView<N, T2, S2> > destination_blocks = blockify(dest, block_shape);
71
72 convolveImpl(overlaps, destination_blocks.begin(), kit);
73 }
74 template <unsigned int N, class T1, class S1,
75 class T2, class S2,
76 class T3>
77 void separableConvolveBlockwise(MultiArrayView<N, T1, S1> source, MultiArrayView<N, T2, S2> dest, const Kernel1D<T3>& kernel,
78 const typename MultiArrayView<N, T1, S1>::difference_type& block_shape =
79 typename MultiArrayView<N, T1, S1>::difference_type(128))
80 {
81 std::vector<Kernel1D<T3> > kernels(N, kernel);
82 separableConvolveBlockwise(source, dest, kernels.begin(), block_shape);
83 }
84
85
86 /*******************************************************/
87 /* */
88 /* separableConvolveBlockwise */
89 /* */
90 /*******************************************************/
91
92 /** \brief Separated convolution on ChunkedArrays.
93
94 <b> Declarations:</b>
95
96 \code
97 namespace vigra {
98 // apply each kernel from the sequence 'kernels' in turn
99 template <unsigned int N, class T1, class T2, class KernelIterator>
100 void separableConvolveBlockwise(const ChunkedArra<N, T1>& source, ChunkedArray<N, T2>& destination, KernelIterator kernels);
101 // apply the same kernel to all dimensions
102 template <unsigned int N, class T1, class T2, class T3>
103 void separableConvolveBlockwise(const ChunkedArra<N, T1>& source, ChunkedArray<N, T2>& destination, Kernel1D<T3> const & kernel);
104 }
105 \endcode
106
107 This function computes a separated convolution for a given \ref ChunkedArray. For infinite precision T1, this is equivalent to
108 \ref separableConvolveMultiArray. In practice, floating point inaccuracies will make the result differ slightly.
109 */
110 doxygen_overloaded_function(template <...> void separableConvolveBlockwise)
111
112 template <unsigned int N, class T1, class T2, class KernelIterator>
113 void separableConvolveBlockwise(const ChunkedArray<N, T1>& source, ChunkedArray<N, T2>& destination, KernelIterator kit)
114 {
115 using namespace blockwise_convolution_detail;
116
117 typedef typename ChunkedArray<N, T1>::shape_type Shape;
118
119 Shape shape = source.shape();
120 vigra_precondition(shape == destination.shape(), "shape mismatch of source and destination");
121
122 std::pair<Shape, Shape> overlap = kernelOverlap<Shape, KernelIterator>(kit);
123 Shape block_shape = source.chunkShape();
124 vigra_precondition(block_shape == destination.chunkShape(), "chunk shapes do not match");
125 Overlaps<ChunkedArray<N, T1> > overlaps(source, block_shape, overlap.first, overlap.second);
126
127 convolveImpl(overlaps, destination.chunk_begin(Shape(0), shape), kit);
128 }
129 template <unsigned int N, class T1, class T2, class T>
130 void separableConvolveBlockwise(const ChunkedArray<N, T1>& source, ChunkedArray<N, T2>& destination, const Kernel1D<T>& kernel)
131 {
132 std::vector<Kernel1D<T> > kernels(N, kernel);
133 separableConvolveBlockse(source, destination, kernels.begin());
134 }
135
136
137 }
138
139 #endif
140
vigra::separableConvolveMultiArray
void separableConvolveMultiArray(...)
Separated convolution on multi-dimensional arrays.
vigra::boost_graph::source
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
vigra::doxygen_overloaded_function
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.

© 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)