Turi Create  4.0
convolve.hpp
Go to the documentation of this file.
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 /*
7  Copyright 2005-2007 Adobe Systems Incorporated
8  Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
9  or a copy at http://opensource.adobe.com/licenses.html)
10 */
11 
12 /*************************************************************************************************/
13 
14 #ifndef GIL_CONVOLVE_HPP
15 #define GIL_CONVOLVE_HPP
16 
17 /*!
18 /// \file
19 /// \brief 2D seperable convolutions and correlations
20 ///
21 /// \author Hailin Jin and Lubomir Bourdev \n
22 /// Adobe Systems Incorporated
23 /// \date 2005-2007 \n Last updated on February 6, 2007
24 */
25 
26 
27 #include <cstddef>
28 #include <cassert>
29 #include <algorithm>
30 #include <vector>
31 #include <functional>
32 #include "../../gil_config.hpp"
33 #include "../../image_view_factory.hpp"
34 #include "../../algorithm.hpp"
35 #include "../../metafunctions.hpp"
37 #include "algorithm.hpp"
38 
39 namespace boost { namespace gil {
40 
41 /// \ingroup ImageAlgorithms
42 /// Boundary options for 1D correlations/convolutions
44  convolve_option_output_ignore, /// do nothing to the output
45  convolve_option_output_zero, /// set the output to zero
46  convolve_option_extend_padded, /// assume the source boundaries to be padded already
47  convolve_option_extend_zero, /// assume the source boundaries to be zero
48  convolve_option_extend_constant /// assume the source boundaries to be the boundary value
49 };
50 
51 namespace detail {
52 /// compute the correlation of 1D kernel with the rows of an image
53 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView,typename Correlator>
54 void correlate_rows_imp(const SrcView& src, const Kernel& ker, const DstView& dst,
56  Correlator correlator) {
57  assert(src.dimensions()==dst.dimensions());
58  assert(ker.size()!=0);
59 
60  typedef typename pixel_proxy<typename SrcView::value_type>::type PIXEL_SRC_REF;
61  typedef typename pixel_proxy<typename DstView::value_type>::type PIXEL_DST_REF;
62  typedef typename Kernel::value_type kernel_type;
63 
64  if(ker.size()==1) {//reduces to a multiplication
65  view_multiplies_scalar<PixelAccum>(src,*ker.begin(),dst);
66  return;
67  }
68 
69  int width=src.width(),height=src.height();
70  PixelAccum acc_zero; pixel_zeros_t<PixelAccum>()(acc_zero);
71  if (width==0) return;
72  if (option==convolve_option_output_ignore || option==convolve_option_output_zero) {
73  typename DstView::value_type dst_zero; pixel_assigns_t<PixelAccum,PIXEL_DST_REF>()(acc_zero,dst_zero);
74  if (width<(int)ker.size()) {
75  if (option==convolve_option_output_zero)
76  fill_pixels(dst,dst_zero);
77  } else {
78  std::vector<PixelAccum> buffer(width);
79  for(int rr=0;rr<height;++rr) {
80  assign_pixels(src.row_begin(rr),src.row_end(rr),&buffer.front());
81  typename DstView::x_iterator it_dst=dst.row_begin(rr);
82  if (option==convolve_option_output_zero)
83  std::fill_n(it_dst,ker.left_size(),dst_zero);
84  it_dst+=ker.left_size();
85  correlator(&buffer.front(),&buffer.front()+width+1-ker.size(),
86  ker.begin(),it_dst);
87  it_dst+=width+1-ker.size();
88  if (option==convolve_option_output_zero)
89  std::fill_n(it_dst,ker.right_size(),dst_zero);
90  }
91  }
92  } else {
93  std::vector<PixelAccum> buffer(width+ker.size()-1);
94  for(int rr=0;rr<height;++rr) {
95  PixelAccum* it_buffer=&buffer.front();
96  if (option==convolve_option_extend_padded) {
97  assign_pixels(src.row_begin(rr)-ker.left_size(),
98  src.row_end(rr)+ker.right_size(),
99  it_buffer);
100  } else if (option==convolve_option_extend_zero) {
101  std::fill_n(it_buffer,ker.left_size(),acc_zero);
102  it_buffer+=ker.left_size();
103  assign_pixels(src.row_begin(rr),src.row_end(rr),it_buffer);
104  it_buffer+=width;
105  std::fill_n(it_buffer,ker.right_size(),acc_zero);
106  } else if (option==convolve_option_extend_constant) {
107  PixelAccum filler;
108  pixel_assigns_t<PIXEL_SRC_REF,PixelAccum>()(*src.row_begin(rr),filler);
109  std::fill_n(it_buffer,ker.left_size(),filler);
110  it_buffer+=ker.left_size();
111  assign_pixels(src.row_begin(rr),src.row_end(rr),it_buffer);
112  it_buffer+=width;
113  pixel_assigns_t<PIXEL_SRC_REF,PixelAccum>()(src.row_end(rr)[-1],filler);
114  std::fill_n(it_buffer,ker.right_size(),filler);
115  }
116  correlator(&buffer.front(),&buffer.front()+width,
117  ker.begin(),
118  dst.row_begin(rr));
119  }
120  }
121 }
122 template <typename PixelAccum>
123 class correlator_n {
124 private:
125  std::size_t _size;
126 public:
127  correlator_n(std::size_t size_in) : _size(size_in) {}
128  template <typename SrcIterator,typename KernelIterator,typename DstIterator>
129  void operator()(SrcIterator src_begin,SrcIterator src_end,
130  KernelIterator ker_begin,
131  DstIterator dst_begin) {
132  correlate_pixels_n<PixelAccum>(src_begin,src_end,ker_begin,_size,dst_begin);
133  }
134 };
135 template <std::size_t Size,typename PixelAccum>
136 struct correlator_k {
137 public:
138  template <typename SrcIterator,typename KernelIterator,typename DstIterator>
139  void operator()(SrcIterator src_begin,SrcIterator src_end,
140  KernelIterator ker_begin,
141  DstIterator dst_begin){
142  correlate_pixels_k<Size,PixelAccum>(src_begin,src_end,ker_begin,dst_begin);
143  }
144 };
145 } // namespace detail
146 
147 /// \ingroup ImageAlgorithms
148 ///correlate a 1D variable-size kernel along the rows of an image
149 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
150 
151 void correlate_rows(const SrcView& src, const Kernel& ker, const DstView& dst,
152  convolve_boundary_option option=convolve_option_extend_zero) {
153  detail::correlate_rows_imp<PixelAccum>(src,ker,dst,option,detail::correlator_n<PixelAccum>(ker.size()));
154 }
155 
156 /// \ingroup ImageAlgorithms
157 ///correlate a 1D variable-size kernel along the columns of an image
158 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
159 
160 void correlate_cols(const SrcView& src, const Kernel& ker, const DstView& dst,
161  convolve_boundary_option option=convolve_option_extend_zero) {
162  correlate_rows<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
163 }
164 
165 /// \ingroup ImageAlgorithms
166 ///convolve a 1D variable-size kernel along the rows of an image
167 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
168 
169 void convolve_rows(const SrcView& src, const Kernel& ker, const DstView& dst,
170  convolve_boundary_option option=convolve_option_extend_zero) {
171  correlate_rows<PixelAccum>(src,reverse_kernel(ker),dst,option);
172 }
173 
174 /// \ingroup ImageAlgorithms
175 ///convolve a 1D variable-size kernel along the columns of an image
176 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
177 
178 void convolve_cols(const SrcView& src, const Kernel& ker, const DstView& dst,
179  convolve_boundary_option option=convolve_option_extend_zero) {
180  convolve_rows<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
181 }
182 
183 /// \ingroup ImageAlgorithms
184 ///correlate a 1D fixed-size kernel along the rows of an image
185 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
186 
187 void correlate_rows_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
188  convolve_boundary_option option=convolve_option_extend_zero) {
189  detail::correlate_rows_imp<PixelAccum>(src,ker,dst,option,detail::correlator_k<Kernel::static_size,PixelAccum>());
190 }
191 
192 /// \ingroup ImageAlgorithms
193 ///correlate a 1D fixed-size kernel along the columns of an image
194 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
195 
196 void correlate_cols_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
197  convolve_boundary_option option=convolve_option_extend_zero) {
198  correlate_rows_fixed<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
199 }
200 
201 /// \ingroup ImageAlgorithms
202 ///convolve a 1D fixed-size kernel along the rows of an image
203 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
204 
205 void convolve_rows_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
206  convolve_boundary_option option=convolve_option_extend_zero) {
207  correlate_rows_fixed<PixelAccum>(src,reverse_kernel(ker),dst,option);
208 }
209 
210 /// \ingroup ImageAlgorithms
211 ///convolve a 1D fixed-size kernel along the columns of an image
212 template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
213 
214 void convolve_cols_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
215  convolve_boundary_option option=convolve_option_extend_zero) {
216  convolve_rows_fixed<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
217 }
218 
219 } } // namespace boost::gil
220 
221 #endif
do nothing to the output
Definition: convolve.hpp:45
void correlate_rows_imp(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option, Correlator correlator)
compute the correlation of 1D kernel with the rows of an image
Definition: convolve.hpp:54
void correlate_rows(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:151
Kernel reverse_kernel(const Kernel &kernel)
reverse a kernel
Definition: kernel.hpp:96
void correlate_cols(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:160
void correlate_rows_fixed(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:187
convolve_boundary_option
Definition: convolve.hpp:43
assume the source boundaries to be padded already
Definition: convolve.hpp:47
void convolve_cols(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:178
void convolve_cols_fixed(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:214
void convolve_rows_fixed(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:205
Returns the reference proxy associated with a type that has a "reference" member typedef.
Definition: algorithm.hpp:39
Structures for pixel-wise numeric operations /.
assume the source boundaries to be zero
Definition: convolve.hpp:48
construct for setting a pixel to zero (for whatever zero means)
void convolve_rows(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:169
void correlate_cols_fixed(const SrcView &src, const Kernel &ker, const DstView &dst, convolve_boundary_option option=convolve_option_extend_zero)
Definition: convolve.hpp:196