4231: mln/transform/hough.hh: Improve.

--- milena/ChangeLog | 4 + milena/mln/transform/hough.hh | 159 ++++++++++++----------------------------- 2 files changed, 50 insertions(+), 113 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 51bcd4e..ae208c4 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,7 @@ +2009-07-01 Guillaume Lazzara <guillaume.lazzara@lrde.epita.fr> + + * mln/transform/hough.hh: Improve. + 2009-06-30 Guillaume Lazzara <guillaume.lazzara@lrde.epita.fr> Small fixes. diff --git a/milena/mln/transform/hough.hh b/milena/mln/transform/hough.hh index 65d4512..19ed1b0 100644 --- a/milena/mln/transform/hough.hh +++ b/milena/mln/transform/hough.hh @@ -30,12 +30,13 @@ /// /// Compute the hough transform. - # include <mln/core/image/image2d.hh> # include <mln/data/fill.hh> # include <mln/geom/nrows.hh> # include <mln/geom/ncols.hh> +# include <mln/geom/min_col.hh> +# include <mln/geom/min_row.hh> # include <mln/geom/bbox.hh> # include <mln/opt/at.hh> @@ -49,14 +50,6 @@ # include <mln/value/int_u8.hh> -//FIXME: to be removed. For debug purpose. -//#include <mln/data/convert.hh> -//#include <mln/value/rgb8.hh> -//#include <mln/draw/line.hh> -//#include <mln/literal/colors.hh> -//#include <mln/io/ppm/save.hh> - - namespace mln { @@ -67,8 +60,6 @@ namespace mln /// Objects used for computation must be set to 'true'. /// /// \param[in] input_ A binary image. - /// \param[in] min_angle Minimum angle which can be found. - /// \param[in] max_angle Maximum angle which can be found. /// /// \return A 2D image of float. Rows are used for the distance and /// columns are used for the angles. Angles go from 0 to 359. @@ -79,129 +70,71 @@ namespace mln // template <typename I> image2d<float> - hough(const Image<I>& input_, int min_angle, int max_angle); + hough(const Image<I>& input_); - /// \overload - template <typename I> - image2d<float> - hough(const Image<I>& input); - # ifndef MLN_INCLUDE_ONLY + namespace internal + { + + + /// FIXME: we may prefer to have an angle value type. + double to_radians(double angle) + { + return angle * math::pi / 180.0f; + } + + + } // end of namespace mln::transform::internal + template <typename I> image2d<float> - hough(const Image<I>& input_, int min_angle, int max_angle) + hough(const Image<I>& input_) { trace::entering("mln::transform::hough"); - mln_precondition(min_angle < max_angle); const I& input = exact(input_); mlc_equal(mln_value(I), bool)::check(); mln_precondition(input.is_valid()); - math::round<int> rd; - double deg2rad = math::pi / 180.0f; - int range = rd(sqrt((double)(geom::ncols(input) * geom::ncols(input) - + geom::nrows(input) * geom::nrows(input)))); - - long temp = min_angle; - min_angle = 450 - max_angle; - max_angle = 450 - temp; - - // Pre-compute sin and cos values. - util::array<double> sin_cache(360), - cos_cache(360); - for (int omega = 0; omega < 360; ++omega) - { - sin_cache[omega] = math::sin((double)(omega * deg2rad)); - cos_cache[omega] = math::cos((double)(omega * deg2rad)); - } - - image2d<float> output(make::box2d(range,360)); - data::fill(output, 0); - - mln_piter(I) p(input.domain()); + def::coord + minrow = geom::min_row(input), + mincol = geom::min_col(input); + unsigned + ncols = geom::ncols(input), + nrows = geom::nrows(input); + int compt = 0; + int maxRho = (int)(sqrt((ncols * nrows) + + (ncols * nrows)) + + 0.5); + + image2d<float> accu(360, 2*maxRho); + data::fill(accu, 0.f); + + mln_piter(image2d<int>) p(input.domain()); for_all(p) - if (input(p)) // Is this site part of an objet? - { - - long teta1 = min_angle; - long teta2 = max_angle; - for (int omega = teta1; omega < teta2; ++omega) + if (input(p)) + for (int angle = 0 ; angle < 360 ; ++angle) { - long tetad = omega%360; - long r = rd(p.col() * sin_cache[tetad] - + p.row() * cos_cache[tetad]); - if (r > 0 && r < range) - output.at_(r, tetad) += 1; - } - - teta1 = min_angle + 180; - teta2 = max_angle + 180; - for (int omega = teta1; omega < teta2; ++omega) - { - long tetad = omega%360; - long r = rd(p.col() * sin_cache[tetad] - + p.row() * cos_cache[tetad]); - if (r > 0 && r < range) - output.at_(r, tetad) += 1; - } - - } - -// { -// point2d max_p(0,0); -// mln_piter_(image2d<float>) p(output.domain()); -// for_all(p) -// if (output(max_p) < output(p)) -// max_p = p; -// -// point2d b,e; -// b.col() = 0; -// b.row() = max_p.row()/cos(deg2rad*max_p.col()); -// if (b.row() < 0) -// { -// b.row() = 0; -// b.col() = max_p.row()/sin(deg2rad*max_p.col()); -// } else if (b.row() >= input.nrows()) -// { -// b.row() = input.nrows() - 1; -// b.col() = max_p.row() - b.row() * cos(deg2rad*max_p.col())/sin(deg2rad*max_p.col()); -// } -// -// e.col() = input.ncols() - 1; -// e.row() = max_p.row() - e.col() * sin(deg2rad*max_p.col()) / cos(deg2rad*max_p.col()); -// if (e.row() < 0) -// { -// e.row() = 0; -// e.col() = max_p.row()/sin(deg2rad*max_p.col()); -// } else if (e.row() >= input.nrows()) -// { -// e.row() = input.nrows() - 1; -// e.col() = max_p.row() - e.row() * cos(deg2rad*max_p.col())/sin(deg2rad*max_p.col()); -// } -// -// std::cout << b << " - " << e << std::endl; -// -// image2d<value::rgb8> toto = data::convert(value::rgb8(), input); -// draw::line(toto, b, e, literal::red); -// io::ppm::save(toto, "tmp_input.ppm"); -// } - trace::exiting("mln::transform::hough"); - return output; - } + double + theta = internal::to_radians(angle), + rho = (p.row() - minrow) * math::cos(theta) + + (p.col() - mincol) * math::sin(theta); + int + indexAngle = (int) (angle), + indexRho = (int)(rho + maxRho + 0.5); + ++opt::at(accu, indexAngle, indexRho); + } - template <typename I> - image2d<float> - hough(const Image<I>& input) - { - return hough(input, -180, 180); + trace::exiting("mln::transform::hough"); + return accu; } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::transform -- 1.5.6.5
participants (1)
-
Guillaume Lazzara