harris.hpp 3.3 KB

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