00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_TRANSFORM_HOUGH_HH
00027 # define MLN_TRANSFORM_HOUGH_HH
00028
00032
00033
00034 # include <mln/core/image/image2d.hh>
00035 # include <mln/data/fill.hh>
00036
00037 # include <mln/geom/nrows.hh>
00038 # include <mln/geom/ncols.hh>
00039 # include <mln/geom/min_col.hh>
00040 # include <mln/geom/min_row.hh>
00041 # include <mln/geom/bbox.hh>
00042
00043 # include <mln/opt/at.hh>
00044
00045 # include <mln/math/sin.hh>
00046 # include <mln/math/cos.hh>
00047 # include <mln/math/pi.hh>
00048
00049 # include <mln/make/box2d.hh>
00050
00051 # include <mln/value/int_u8.hh>
00052
00053
00054 namespace mln
00055 {
00056
00057 namespace transform
00058 {
00059
00071
00072 template <typename I>
00073 image2d<float>
00074 hough(const Image<I>& input_);
00075
00076
00077
00078 # ifndef MLN_INCLUDE_ONLY
00079
00080
00081 namespace internal
00082 {
00083
00084
00086 double to_radians(double angle)
00087 {
00088 return angle * math::pi / 180.0f;
00089 }
00090
00091
00092 }
00093
00094
00095
00096 template <typename I>
00097 image2d<float>
00098 hough(const Image<I>& input_)
00099 {
00100 trace::entering("mln::transform::hough");
00101
00102 const I& input = exact(input_);
00103 mlc_equal(mln_value(I), bool)::check();
00104 mln_precondition(input.is_valid());
00105
00106 def::coord
00107 minrow = geom::min_row(input),
00108 mincol = geom::min_col(input);
00109 unsigned
00110 ncols = geom::ncols(input),
00111 nrows = geom::nrows(input);
00112 int maxRho = (int)(sqrt((ncols * nrows)
00113 + (ncols * nrows))
00114 + 0.5);
00115
00116 image2d<float> accu(360, 2*maxRho);
00117 data::fill(accu, 0.f);
00118
00119 mln_piter(image2d<int>) p(input.domain());
00120 for_all(p)
00121 if (input(p))
00122 for (int angle = 0 ; angle < 360 ; ++angle)
00123 {
00124 double
00125 theta = internal::to_radians(angle),
00126 rho = (p.row() - minrow) * math::cos(theta)
00127 + (p.col() - mincol) * math::sin(theta);
00128 int
00129 indexAngle = (int) (angle),
00130 indexRho = (int)(rho + maxRho + 0.5);
00131
00132 ++opt::at(accu, indexAngle, indexRho);
00133 }
00134
00135 trace::exiting("mln::transform::hough");
00136 return accu;
00137 }
00138
00139
00140 # endif // ! MLN_INCLUDE_ONLY
00141
00142 }
00143
00144 }
00145
00146
00147 #endif // ! MLN_TRANSFORM_HOUGH_HH