Boost GIL


hessian.hpp
1 //
2 // Copyright 2019 Olzhas Zhumabek <anonymous.from.applecity@gmail.com>
3 // Copyright 2021 Scramjet911 <36035352+Scramjet911@users.noreply.github.com>
4 // Use, modification and distribution are subject to the Boost Software License,
5 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_GIL_IMAGE_PROCESSING_HESSIAN_HPP
9 #define BOOST_GIL_IMAGE_PROCESSING_HESSIAN_HPP
10 
11 #include <boost/gil/image_view.hpp>
12 #include <boost/gil/typedefs.hpp>
13 #include <boost/gil/image_processing/kernel.hpp>
14 #include <stdexcept>
15 
16 namespace boost { namespace gil {
17 
26 template <typename GradientView, typename T, typename Allocator, typename OutputView>
27 inline void compute_hessian_responses(
28  GradientView ddxx,
29  GradientView dxdy,
30  GradientView ddyy,
31  const detail::kernel_2d<T, Allocator>& weights,
32  OutputView dst)
33 {
34  if (ddxx.dimensions() != ddyy.dimensions()
35  || ddyy.dimensions() != dxdy.dimensions()
36  || dxdy.dimensions() != dst.dimensions()
37  || weights.center_x() != weights.center_y())
38  {
39  throw std::invalid_argument("dimensions of views are not the same"
40  " or weights don't have equal width and height"
41  " or weights' dimensions are not odd");
42  }
43  // Use pixel type of output, as values will be written to output
44  using pixel_t = typename std::remove_reference<decltype(std::declval<OutputView>()(0, 0))>::type;
45 
46  using channel_t = typename std::remove_reference
47  <
48  decltype(std::declval<pixel_t>().at(std::integral_constant<int, 0>{}))
49  >::type;
50 
51 
52  auto center = weights.center_y();
53  for (auto y = center; y < dst.height() - center; ++y)
54  {
55  for (auto x = center; x < dst.width() - center; ++x)
56  {
57  auto ddxx_i = channel_t();
58  auto ddyy_i = channel_t();
59  auto dxdy_i = channel_t();
60  for (typename OutputView::coord_t w_y = 0; w_y < static_cast<std::ptrdiff_t>(weights.size()); ++w_y)
61  {
62  for (typename OutputView::coord_t w_x = 0; w_x < static_cast<std::ptrdiff_t>(weights.size()); ++w_x)
63  {
64  ddxx_i += ddxx(x + w_x - center, y + w_y - center)
65  .at(std::integral_constant<int, 0>{}) * weights.at(w_x, w_y);
66  ddyy_i += ddyy(x + w_x - center, y + w_y - center)
67  .at(std::integral_constant<int, 0>{}) * weights.at(w_x, w_y);
68  dxdy_i += dxdy(x + w_x - center, y + w_y - center)
69  .at(std::integral_constant<int, 0>{}) * weights.at(w_x, w_y);
70  }
71  }
72  auto determinant = ddxx_i * ddyy_i - dxdy_i * dxdy_i;
73  dst(x, y).at(std::integral_constant<int, 0>{}) = determinant;
74  }
75  }
76 }
77 
78 }} // namespace boost::gil
79 
80 #endif
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36