Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:51:45

0001 // Boost.GIL (Generic Image Library) - tests
0002 //
0003 // Copyright 2020 Olzhas Zhumabek <anonymous.from.applecity@gmail.com>
0004 //
0005 // Use, modification and distribution are subject to the Boost Software License,
0006 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 #ifndef BOOST_GIL_EXTENSION_IMAGE_PROCESSING_HOUGH_PARAMETER_HPP
0010 #define BOOST_GIL_EXTENSION_IMAGE_PROCESSING_HOUGH_PARAMETER_HPP
0011 
0012 #include "boost/gil/point.hpp"
0013 
0014 #include <cmath>
0015 #include <cstddef>
0016 
0017 namespace boost
0018 {
0019 namespace gil
0020 {
0021 /// \ingroup HoughTransform
0022 /// \brief A type to encapsulate Hough transform parameter range
0023 ///
0024 /// This type provides a way to express value range for a parameter
0025 /// as well as some factory functions to simplify initialization
0026 template <typename T>
0027 struct hough_parameter
0028 {
0029     T start_point;
0030     T step_size;
0031     std::size_t step_count;
0032 
0033     /// \ingroup HoughTransform
0034     /// \brief Create Hough parameter from value neighborhood and step count
0035     ///
0036     /// This function will take start_point as middle point, and in both
0037     /// directions will try to walk half_step_count times until distance of
0038     /// neighborhood is reached
0039     static hough_parameter<T> from_step_count(T start_point, T neighborhood,
0040                                               std::size_t half_step_count)
0041     {
0042         T step_size = neighborhood / half_step_count;
0043         std::size_t step_count = half_step_count * 2 + 1;
0044         // explicitly fill out members, as aggregate init will error out with narrowing
0045         hough_parameter<T> parameter;
0046         parameter.start_point = start_point - neighborhood;
0047         parameter.step_size = step_size;
0048         parameter.step_count = step_count;
0049         return parameter;
0050     }
0051 
0052     /// \ingroup HoughTransform
0053     /// \brief Create Hough parameter from value neighborhood and step size
0054     ///
0055     /// This function will take start_point as middle point, and in both
0056     /// directions will try to walk step_size at a time until distance of
0057     /// neighborhood is reached
0058     static hough_parameter<T> from_step_size(T start_point, T neighborhood, T step_size)
0059     {
0060         std::size_t step_count =
0061             2 * static_cast<std::size_t>(std::floor(neighborhood / step_size)) + 1;
0062         // do not use step_size - neighborhood, as step_size might not allow
0063         // landing exactly on that value when starting from start_point
0064         // also use parentheses on step_count / 2 because flooring is exactly
0065         // what we want
0066 
0067         // explicitly fill out members, as aggregate init will error out with narrowing
0068         hough_parameter<T> parameter;
0069         parameter.start_point = start_point - step_size * (step_count / 2);
0070         parameter.step_size = step_size;
0071         parameter.step_count = step_count;
0072         return parameter;
0073     }
0074 };
0075 
0076 /// \ingroup HoughTransform
0077 /// \brief Calculate minimum angle which would be observable if walked on a circle
0078 ///
0079 /// When drawing a circle or moving around a point in circular motion, it is
0080 /// important to not do too many steps, but also to not have disconnected
0081 /// trajectory. This function will calculate the minimum angle that is observable
0082 /// when walking on a circle or tilting a line.
0083 /// WARNING: do keep in mind IEEE 754 quirks, e.g. no-associativity,
0084 /// no-commutativity and precision. Do not expect expressions that are
0085 /// mathematically the same to produce the same values
0086 inline double minimum_angle_step(point_t dimensions)
0087 {
0088     auto longer_dimension = dimensions.x > dimensions.y ? dimensions.x : dimensions.y;
0089     return std::atan2(1, longer_dimension);
0090 }
0091 
0092 /// \ingroup HoughTransform
0093 /// \brief Create a Hough transform parameter with optimal angle step
0094 ///
0095 /// Due to computational intensity and noise sensitivity of Hough transform,
0096 /// having any candidates missed or computed again is problematic. This function
0097 /// will properly encapsulate optimal value range around approx_angle with amplitude of
0098 /// neighborhood in each direction.
0099 /// WARNING: do keep in mind IEEE 754 quirks, e.g. no-associativity,
0100 /// no-commutativity and precision. Do not expect expressions that are
0101 /// mathematically the same to produce the same values
0102 inline auto make_theta_parameter(double approx_angle, double neighborhood, point_t dimensions)
0103     -> hough_parameter<double>
0104 {
0105     auto angle_step = minimum_angle_step(dimensions);
0106 
0107     // std::size_t step_count =
0108     //     2 * static_cast<std::size_t>(std::floor(neighborhood / angle_step)) + 1;
0109     // return {approx_angle - angle_step * (step_count / 2), angle_step, step_count};
0110     return hough_parameter<double>::from_step_size(approx_angle, neighborhood, angle_step);
0111 }
0112 }} // namespace boost::gil
0113 #endif