00001 #ifndef HOUGH_TRANSFORM2_H
00002 #define HOUGH_TRANSFORM2_H
00003
00004 #include <boost/multi_array.hpp>
00005 #include <algorithm>
00006 #include <vector>
00007 #include <cmath>
00008
00009 #include "image.h"
00010 #include "multi_array_op.h"
00011 #include "image_fileinput.h"
00012 #include "image_funcs.h"
00013 #include "property_image.h"
00014 #include "image_draw.h"
00015 #include "primitives.h"
00016
00017 #ifndef NDEBUG
00018
00019 #include <iostream>
00020 #include <fstream>
00021
00022 #endif
00023
00024 namespace mimas{
00025
00026 typedef boost::multi_array<double,2> Array2D;
00027
00066 template< typename ImageIteratorSource >
00067 class find_line{
00068
00069 protected:
00070 int nbOrientationDiv;
00071 double thresh;
00072
00073 double maxVal;
00074
00075 ImageIteratorSource ul;
00076 ImageIteratorSource lr;
00077
00078 int w,h;
00079 int imageDiagonalSize;
00080 int center_x, center_y;
00081
00082 Array2D parameterSpace;
00083
00084
00085
00086
00087 void hough (void) {
00088 double conv = M_PI/nbOrientationDiv;
00089
00090
00091
00092
00093
00094
00095 ImageIteratorSource temp(ul);
00096 for (int i = 0; i < w; i++, temp.x++){
00097 ImageIteratorSource temp2(temp);
00098 for (int j = 0; j < h; j++,temp2.y++)
00099
00100 if (*temp2 != 0)
00101 for (int omega = 0; omega < nbOrientationDiv; omega++)
00102 {
00103 int r = (int)( (i - center_x) * cos(double(omega*conv)) - (j - center_y) * sin(double(omega*conv)));
00104
00105 assert(imageDiagonalSize / 2 + r > 0 ||imageDiagonalSize / 2 + r <= imageDiagonalSize);
00106 parameterSpace[omega][imageDiagonalSize / 2 + r] += 1;
00107 }
00108 }
00109 }
00110
00111 void findMax(void)
00112 {
00113 maxVal = *(std::max_element(parameterSpace.data(), parameterSpace.data()+parameterSpace.num_elements()));
00114 #ifndef NDEBUG
00115 std::cerr<< "find_line: MaxValue is: " <<maxVal<<std::endl;
00116 #endif
00117 }
00118
00119 void findLine(void){
00120
00121 for (int t=0; t<nbOrientationDiv; t++)
00122 for (int r=0; r< imageDiagonalSize; r++)
00123 if ((parameterSpace[t][r] >= maxVal * thresh))
00124 lines.push_back(polar_to_castesian( t,r - imageDiagonalSize /2));
00125 }
00126
00127
00128 image<unsigned char> displayLine(void) {
00129 image<unsigned char> x;
00130 x.init(w,h);
00131 for(typename std::vector< segment< point > >::iterator it = lines.begin(); it != lines.end(); it++)
00132 drawLine(x, it->p1.x, it->p1.y, it->p2.x, it->p2.y, (unsigned char)(200));
00133
00134 return x;
00135 }
00136
00137
00138 public:
00139 std::vector< segment< point > > lines;
00140
00141
00142
00143 segment< point > polar_to_castesian(double theta,double r)
00144 {
00145 int test = 1000;
00146
00147
00148
00149 double x = r * cos (double(theta*M_PI/nbOrientationDiv));
00150 double y = r * sin (double(theta*M_PI/nbOrientationDiv));
00151
00152
00153
00154
00155
00156 double size = sqrt(x*x + y*y);
00157
00158 point p1 = point( int(x + y * test /size) + center_x , center_y - int(y - x * test /size) );
00159 point p2 = point( int(x - y * test /size) + center_x , center_y - int(y + x * test /size) );
00160
00161 return segment< point >(p1,p2);
00162 }
00163
00164
00165
00166
00167
00168 find_line(ImageIteratorSource ul, ImageIteratorSource lr, double thresh_factor = .7, int orientationDivision = 180)
00169 :
00170 nbOrientationDiv(orientationDivision),
00171 thresh(thresh_factor),ul(ul),lr(lr),
00172 w(lr.x - ul.x),h(lr.y - ul.y),
00173 imageDiagonalSize(int(sqrt(double(w*w+h*h)))),
00174
00175 parameterSpace(boost::extents[orientationDivision][imageDiagonalSize])
00176 {
00177 assert(thresh < 1);
00178
00179 center_x = w /2;
00180 center_y = h /2;
00181 }
00182
00183 image< unsigned char > exec(void) {
00184 hough();
00185 findMax();
00186 findLine();
00187 return displayLine();
00188 }
00189
00190 std::vector< segment< point > > getLines(void) {
00191 hough();
00192 findMax();
00193 findLine();
00194 return lines;
00195 }
00196
00197 };
00198
00199 }
00200
00201 #endif