123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // Boost.GIL (Generic Image Library) - tests
- //
- // Copyright 2020 Olzhas Zhumabek <anonymous.from.applecity@gmail.com>
- //
- // Use, modification and distribution are subject to the Boost Software License,
- // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_GIL_EXTENSION_IMAGE_PROCESSING_HOUGH_PARAMETER_HPP
- #define BOOST_GIL_EXTENSION_IMAGE_PROCESSING_HOUGH_PARAMETER_HPP
- #include "boost/gil/point.hpp"
- #include <cmath>
- #include <cstddef>
- namespace boost
- {
- namespace gil
- {
- /// \ingroup HoughTransform
- /// \brief A type to encapsulate Hough transform parameter range
- ///
- /// This type provides a way to express value range for a parameter
- /// as well as some factory functions to simplify initialization
- template <typename T>
- struct hough_parameter
- {
- T start_point;
- T step_size;
- std::size_t step_count;
- /// \ingroup HoughTransform
- /// \brief Create Hough parameter from value neighborhood and step count
- ///
- /// This function will take start_point as middle point, and in both
- /// directions will try to walk half_step_count times until distance of
- /// neighborhood is reached
- static hough_parameter<T> from_step_count(T start_point, T neighborhood,
- std::size_t half_step_count)
- {
- T step_size = neighborhood / half_step_count;
- std::size_t step_count = half_step_count * 2 + 1;
- // explicitly fill out members, as aggregate init will error out with narrowing
- hough_parameter<T> parameter;
- parameter.start_point = start_point - neighborhood;
- parameter.step_size = step_size;
- parameter.step_count = step_count;
- return parameter;
- }
- /// \ingroup HoughTransform
- /// \brief Create Hough parameter from value neighborhood and step size
- ///
- /// This function will take start_point as middle point, and in both
- /// directions will try to walk step_size at a time until distance of
- /// neighborhood is reached
- static hough_parameter<T> from_step_size(T start_point, T neighborhood, T step_size)
- {
- std::size_t step_count =
- 2 * static_cast<std::size_t>(std::floor(neighborhood / step_size)) + 1;
- // do not use step_size - neighborhood, as step_size might not allow
- // landing exactly on that value when starting from start_point
- // also use parentheses on step_count / 2 because flooring is exactly
- // what we want
- // explicitly fill out members, as aggregate init will error out with narrowing
- hough_parameter<T> parameter;
- parameter.start_point = start_point - step_size * (step_count / 2);
- parameter.step_size = step_size;
- parameter.step_count = step_count;
- return parameter;
- }
- };
- /// \ingroup HoughTransform
- /// \brief Calculate minimum angle which would be observable if walked on a circle
- ///
- /// When drawing a circle or moving around a point in circular motion, it is
- /// important to not do too many steps, but also to not have disconnected
- /// trajectory. This function will calculate the minimum angle that is observable
- /// when walking on a circle or tilting a line.
- /// WARNING: do keep in mind IEEE 754 quirks, e.g. no-associativity,
- /// no-commutativity and precision. Do not expect expressions that are
- /// mathematically the same to produce the same values
- inline double minimum_angle_step(point_t dimensions)
- {
- auto longer_dimension = dimensions.x > dimensions.y ? dimensions.x : dimensions.y;
- return std::atan2(1, longer_dimension);
- }
- /// \ingroup HoughTransform
- /// \brief Create a Hough transform parameter with optimal angle step
- ///
- /// Due to computational intensity and noise sensitivity of Hough transform,
- /// having any candidates missed or computed again is problematic. This function
- /// will properly encapsulate optimal value range around approx_angle with amplitude of
- /// neighborhood in each direction.
- /// WARNING: do keep in mind IEEE 754 quirks, e.g. no-associativity,
- /// no-commutativity and precision. Do not expect expressions that are
- /// mathematically the same to produce the same values
- inline auto make_theta_parameter(double approx_angle, double neighborhood, point_t dimensions)
- -> hough_parameter<double>
- {
- auto angle_step = minimum_angle_step(dimensions);
- // std::size_t step_count =
- // 2 * static_cast<std::size_t>(std::floor(neighborhood / angle_step)) + 1;
- // return {approx_angle - angle_step * (step_count / 2), angle_step, step_count};
- return hough_parameter<double>::from_step_size(approx_angle, neighborhood, angle_step);
- }
- }} // namespace boost::gil
- #endif
|