• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 Olzhas Zhumabek <anonymous.from.applecity@gmail.com>
3 //
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_HARRIS_HPP
9 #define BOOST_GIL_IMAGE_PROCESSING_HARRIS_HPP
10 
11 #include <boost/gil/image_view.hpp>
12 #include <boost/gil/typedefs.hpp>
13 #include <boost/gil/extension/numeric/kernel.hpp>
14 
15 namespace boost { namespace gil {
16 /// \defgroup CornerDetectionAlgorithms
17 /// \brief Algorithms that are used to find corners in an image
18 ///
19 /// These algorithms are used to find spots from which
20 /// sliding the window will produce large intensity change
21 
22 
23 /// \brief function to record Harris responses
24 /// \ingroup CornerDetectionAlgorithms
25 ///
26 /// This algorithm computes Harris responses
27 /// for structure tensor represented by m11, m12_21, m22 views.
28 /// Note that m12_21 represents both entries (1, 2) and (2, 1).
29 /// Window length represents size of a window which is slided around
30 /// to compute sum of corresponding entries. k is a discrimination
31 /// constant against edges (usually in range 0.04 to 0.06).
32 /// harris_response is an out parameter that will contain the Harris responses.
33 template <typename T, typename Allocator>
compute_harris_responses(boost::gil::gray32f_view_t m11,boost::gil::gray32f_view_t m12_21,boost::gil::gray32f_view_t m22,boost::gil::detail::kernel_2d<T,Allocator> weights,float k,boost::gil::gray32f_view_t harris_response)34 void compute_harris_responses(
35     boost::gil::gray32f_view_t m11,
36     boost::gil::gray32f_view_t m12_21,
37     boost::gil::gray32f_view_t m22,
38     boost::gil::detail::kernel_2d<T, Allocator> weights,
39     float k,
40     boost::gil::gray32f_view_t harris_response)
41 {
42     if (m11.dimensions() != m12_21.dimensions() || m12_21.dimensions() != m22.dimensions()) {
43         throw std::invalid_argument("m prefixed arguments must represent"
44             " tensor from the same image");
45     }
46 
47     auto const window_length = weights.size();
48     auto const width = m11.width();
49     auto const height = m11.height();
50     auto const half_length = window_length / 2;
51 
52     for (auto y = half_length; y < height - half_length; ++y)
53     {
54         for (auto x = half_length; x < width - half_length; ++x)
55         {
56             float ddxx = 0;
57             float dxdy = 0;
58             float ddyy = 0;
59             for (gil::gray32f_view_t::coord_t y_kernel = 0;
60                 y_kernel < window_length;
61                 ++y_kernel) {
62                 for (gil::gray32f_view_t::coord_t x_kernel = 0;
63                     x_kernel < window_length;
64                     ++x_kernel) {
65                     ddxx += m11(x + x_kernel - half_length, y + y_kernel - half_length)
66                         .at(std::integral_constant<int, 0>{}) * weights.at(x_kernel, y_kernel);
67                     dxdy += m12_21(x + x_kernel - half_length, y + y_kernel - half_length)
68                         .at(std::integral_constant<int, 0>{}) * weights.at(x_kernel, y_kernel);
69                     ddyy += m22(x + x_kernel - half_length, y + y_kernel - half_length)
70                         .at(std::integral_constant<int, 0>{}) * weights.at(x_kernel, y_kernel);
71                 }
72             }
73             auto det = (ddxx * ddyy) - dxdy * dxdy;
74             auto trace = ddxx + ddyy;
75             auto harris_value = det - k * trace * trace;
76             harris_response(x, y).at(std::integral_constant<int, 0>{}) = harris_value;
77         }
78     }
79 }
80 
81 }} //namespace boost::gil
82 #endif
83