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
16namespace boost { namespace gil {
17
26template <typename GradientView, typename T, typename Allocator, typename OutputView>
27inline 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