conv2d.hpp
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief 2d convolution kernel
5  *
6  * \author O. Krause
7  * \date 2012
8  *
9  *
10  * \par Copyright 1995-2015 Shark Development Team
11  *
12  * <BR><HR>
13  * This file is part of Shark.
14  * <http://image.diku.dk/shark/>
15  *
16  * Shark is free software: you can redistribute it and/or modify
17  * it under the terms of the GNU Lesser General Public License as published
18  * by the Free Software Foundation, either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * Shark is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public License
27  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
28  *
29  */
30 
31 #ifndef REMORA_KERNELS_CONV2D_HPP
32 #define REMORA_KERNELS_CONV2D_HPP
33 
34 #include "default/conv2d.hpp"
35 
36 
37 namespace remora{namespace kernels{
38 
39 
40 ///\brief Computes the convolution of a multi-channel image with a set of filters.
41 ///
42 /// Computes the result of applying k filters to an image where filters and image are allowed
43 /// to have multiple images (some would call this a 3d or even 4d convolution, but we refrain from this as
44 /// for two dimensions filter dimensions and image dimension must agree. E.g. it does not behave like convoluting a volume)
45 /// The base for the convolution is the upper left corner and there is no boundary handling, i.e. only pixels within the image area
46 /// are computed.
47 ///
48 /// The image are stored block-row-wise. i.e. an image of size nxm with k channels is stored as
49 /// and (n*k)x m matrix where n consecutive rows for the row of an image.
50 /// Filters are stored similarly, only that in their case we have the format (n1*k*l) x m1 for a
51 /// set of l filters of size n1 x m1 with k channels each. the n1 rows form a channel, k*n1 rows form
52 /// a filter.
53 /// the output format is stored in the same way as image just with size (l* (m-m1+1))x(n-n1+1).
54 /// The caller must ensure that enough memory is stored.
55 template<class E1, class E2, class M>
56 void conv2d(
57  vector_expression<E1, cpu_tag> const& image,
58  vector_expression<E2, cpu_tag> const& filter,
59  vector_expression<M, cpu_tag>& output,
60  std::size_t num_channels,
61  std::size_t num_filters,
62  std::size_t image_height,
63  std::size_t image_width,
64  std::size_t filter_height,
65  std::size_t filter_width,
66  std::size_t padding_height = 0,
67  std::size_t padding_width = 0
68 ){
69  std::size_t output_rows_per_filter = (image_height - filter_height +1 + padding_height) * (image_width - filter_width +1 + padding_width);
70  std::size_t filter_size = filter_width * filter_height * num_channels;
71 
72  REMORA_SIZE_CHECK(output().size() == num_filters * output_rows_per_filter);
73  REMORA_SIZE_CHECK(image().size() == num_channels * image_width * image_height);
74  REMORA_SIZE_CHECK(filter().size() == num_filters * filter_size);
75 
76  bindings::conv2d(
77  image, filter, output, num_channels, num_filters,
78  image_height, image_width, filter_height, filter_width,
79  padding_height, padding_width
80  );
81 }
82 
83 }}
84 #endif