@@ -218,6 +218,104 @@ auto correlate_pixels_k(
218218 return dst_begin;
219219}
220220
221+ template
222+ <
223+ typename PixelAccum,
224+ typename SrcIterator,
225+ typename KernelIterator,
226+ typename DstIterator
227+ >
228+ inline
229+ auto correlate_pixels_n_2d (
230+ SrcIterator src_begin,
231+ std::size_t src_size,
232+ KernelIterator kernel_begin,
233+ std::size_t kernel_dimension,
234+ DstIterator dst_begin)
235+ -> DstIterator
236+ {
237+ using src_pixel_ref_t = typename pixel_proxy
238+ <
239+ typename std::iterator_traits<SrcIterator>::value_type
240+ >::type;
241+ using dst_pixel_ref_t = typename pixel_proxy
242+ <
243+ typename std::iterator_traits<DstIterator>::value_type
244+ >::type;
245+ using kernel_value_t = typename std::iterator_traits<KernelIterator>::value_type;
246+
247+ PixelAccum accum_zero;
248+ pixel_zeros_t <PixelAccum>()(accum_zero);
249+ std::ptrdiff_t index = 0 ;
250+ std::ptrdiff_t const kernel_size = kernel_dimension * kernel_dimension;
251+
252+ // try eliminating "index" variable.
253+ while (index < src_size - kernel_size + 1 )
254+ {
255+ pixel_assigns_t <PixelAccum, dst_pixel_ref_t >()(
256+ std::inner_product (
257+ src_begin + index,
258+ src_begin + kernel_size + index,
259+ kernel_begin,
260+ accum_zero,
261+ pixel_plus_t <PixelAccum, PixelAccum, PixelAccum>(),
262+ pixel_multiplies_scalar_t <src_pixel_ref_t , kernel_value_t , PixelAccum>()),
263+ *dst_begin);
264+
265+ index += kernel_dimension;
266+ ++dst_begin;
267+ }
268+ return dst_begin;
269+ }
270+
271+ template
272+ <
273+ std::size_t kernel_dimension,
274+ typename PixelAccum,
275+ typename SrcIterator,
276+ typename KernelIterator,
277+ typename DstIterator
278+ >
279+ inline
280+ auto correlate_pixels_k_2d (
281+ SrcIterator src_begin,
282+ std::size_t src_size,
283+ KernelIterator kernel_begin,
284+ DstIterator dst_begin)
285+ -> DstIterator
286+ {
287+ using src_pixel_ref_t = typename pixel_proxy
288+ <
289+ typename std::iterator_traits<SrcIterator>::value_type
290+ >::type;
291+ using dst_pixel_ref_t = typename pixel_proxy
292+ <
293+ typename std::iterator_traits<DstIterator>::value_type
294+ >::type;
295+ using kernel_type = typename std::iterator_traits<KernelIterator>::value_type;
296+
297+ PixelAccum accum_zero;
298+ pixel_zeros_t <PixelAccum>()(accum_zero);
299+ std::ptrdiff_t index = 0 ;
300+ std::ptrdiff_t const kernel_size = kernel_dimension * kernel_dimension;
301+
302+ while (index < src_size - kernel_size + 1 )
303+ {
304+ pixel_assigns_t <PixelAccum, dst_pixel_ref_t >()(
305+ inner_product_k<kernel_size>(
306+ src_begin + index,
307+ kernel_begin,
308+ accum_zero,
309+ pixel_plus_t <PixelAccum, PixelAccum, PixelAccum>(),
310+ pixel_multiplies_scalar_t <src_pixel_ref_t , kernel_type, PixelAccum>()),
311+ *dst_begin);
312+
313+ index += kernel_dimension;
314+ ++dst_begin;
315+ }
316+ return dst_begin;
317+ }
318+
221319// / \brief destination is set to be product of the source and a scalar
222320// / \tparam PixelAccum - TODO
223321// / \tparam SrcView Models ImageViewConcept
@@ -255,11 +353,12 @@ void view_multiplies_scalar(SrcView const& src_view, Scalar const& scalar, DstVi
255353// / \brief Boundary options for image boundary extension
256354enum class boundary_option
257355{
258- output_ignore, // / do nothing to the output
259- output_zero, // / set the output to zero
260- extend_padded, // / assume the source boundaries to be padded already
261- extend_zero, // / assume the source boundaries to be zero
262- extend_constant // / assume the source boundaries to be the boundary value
356+ output_ignore, // / do nothing to the output
357+ output_zero, // / set the output to zero
358+ extend_padded, // / assume the source boundaries to be padded already
359+ extend_zero, // / assume the source boundaries to be zero
360+ extend_constant, // / assume the source boundaries to be the boundary value
361+ extend_reflection // / assumes boundary values as reflection of source row/column pixels
263362};
264363
265364namespace detail
0 commit comments