Boost GIL


hessian.hpp
1 #ifndef BOOST_GIL_IMAGE_PROCESSING_HESSIAN_HPP
2 #define BOOST_GIL_IMAGE_PROCESSING_HESSIAN_HPP
3 
4 #include <boost/gil/image_view.hpp>
5 #include <boost/gil/typedefs.hpp>
6 #include <boost/gil/extension/numeric/kernel.hpp>
7 #include <stdexcept>
8 
9 namespace boost { namespace gil {
10 
19 template <typename GradientView, typename T, typename Allocator, typename OutputView>
20 inline void compute_hessian_responses(
21  GradientView ddxx,
22  GradientView dxdy,
23  GradientView ddyy,
24  const detail::kernel_2d<T, Allocator>& weights,
25  OutputView dst)
26 {
27  if (ddxx.dimensions() != ddyy.dimensions()
28  || ddyy.dimensions() != dxdy.dimensions()
29  || dxdy.dimensions() != dst.dimensions()
30  || weights.center_x() != weights.center_y())
31  {
32  throw std::invalid_argument("dimensions of views are not the same"
33  " or weights don't have equal width and height"
34  " or weights' dimensions are not odd");
35  }
36  // Use pixel type of output, as values will be written to output
37  using pixel_t = typename std::remove_reference<decltype(std::declval<OutputView>()(0, 0))>::type;
38 
39  using channel_t = typename std::remove_reference
40  <
41  decltype(std::declval<pixel_t>().at(std::integral_constant<int, 0>{}))
42  >::type;
43 
44 
45  auto center = weights.center_y();
46  for (auto y = center; y < dst.height() - center; ++y)
47  {
48  for (auto x = center; x < dst.width() - center; ++x)
49  {
50  auto ddxx_i = channel_t();
51  auto ddyy_i = channel_t();
52  auto dxdy_i = channel_t();
53  for (typename OutputView::coord_t w_y = 0; w_y < weights.size(); ++w_y)
54  {
55  for (typename OutputView::coord_t w_x = 0; w_x < weights.size(); ++w_x)
56  {
57  ddxx_i += ddxx(x + w_x - center, y + w_y - center)
58  .at(std::integral_constant<int, 0>{}) * weights.at(w_x, w_y);
59  ddyy_i += ddyy(x + w_x - center, y + w_y - center)
60  .at(std::integral_constant<int, 0>{}) * weights.at(w_x, w_y);
61  dxdy_i += dxdy(x + w_x - center, y + w_y - center)
62  .at(std::integral_constant<int, 0>{}) * weights.at(w_x, w_y);
63  }
64  }
65  auto determinant = ddxx_i * ddyy_i - dxdy_i * dxdy_i;
66  dst(x, y).at(std::integral_constant<int, 0>{}) = determinant;
67  }
68  }
69 }
70 
71 }} // namespace boost::gil
72 
73 #endif