HoughTransform2.C
00001 #ifndef HoughTransform2_C
00002 #define HoughTransform2_C
00003
00004 #include "BeoSub/HoughTransform2.H"
00005
00006 #include "Image/Image.H"
00007 #include "Image/Pixels.H"
00008 #include "Util/Timer.H"
00009 #include "Util/Types.H"
00010 #include "Util/log.H"
00011 #include "Image/ColorOps.H"
00012 #include "Image/Image.H"
00013 #include "Image/MathOps.H"
00014 #include "Image/DrawOps.H"
00015 #include "Image/FilterOps.H"
00016 #include "Image/Transforms.H"
00017 #include "Raster/Raster.H"
00018 #include "rutz/shared_ptr.h"
00019 #include "BeoSub/hysteresis.H"
00020 #include "VFAT/segmentImageTrackMC.H"
00021 #include <cstdio>
00022 #include <cstdlib>
00023 #include <cstring>
00024 #include <iostream>
00025 #include <math.h>
00026 #include <list>
00027 #include "Image/MatrixOps.H"
00028 #include "BeoSub/CannyEdge.H"
00029 #include "MBARI/Geometry2D.H"
00030 using namespace std;
00031
00032
00033 void findEndPoints(int p, float theta, Point2D<int> *intercept1, Point2D<int> *intercept2, Dims dimensions)
00034 {
00035 int imageWidth = dimensions.w();
00036 int imageHeight = dimensions.h();
00037
00038
00039 intercept1->i = -1;
00040 intercept2->i = -1;
00041 int tempX0, tempX1, tempY0, tempY1;
00042 int cosTheta = (int) cos(theta);
00043 int sinTheta = (int) sin(theta);
00044
00045
00046 tempX0 = (p) / cosTheta;
00047 tempX1 = (p-imageHeight*sinTheta)/cosTheta;
00048 tempY0 = (p / sinTheta);
00049 tempY1 = (p - imageWidth * cosTheta) / sinTheta;
00050
00051
00052 if(tempX0 > 0 && tempX0 < imageWidth)
00053 {
00054 intercept1->i = tempX0;
00055 intercept1->j = 0;
00056 }
00057 if(tempX1 > 0 && tempX1 < imageWidth)
00058 {
00059 if(intercept1->i == -1) {
00060 intercept1->i = tempX1;
00061 intercept1->j = imageHeight;
00062 }
00063 else {
00064 intercept2->i = tempX1;
00065 intercept2->j = imageHeight;
00066 }
00067 }
00068 if(tempY0 > 0 && tempY0 < imageHeight)
00069 {
00070 if(intercept1->i == -1) {
00071 intercept1->i = 0;
00072 intercept1->j = tempY0;
00073 }
00074 else {
00075 intercept2->i = 0;
00076 intercept2->j = tempY0;
00077 }
00078 }
00079 if(tempY1 > 0 && tempY1 < imageHeight)
00080 {
00081 if(intercept1->i == -1) {
00082 intercept1->i = imageWidth;
00083 intercept1->j = tempY1;
00084 }
00085 else {
00086 intercept2->i = imageWidth;
00087 intercept2->j = tempY1;
00088 }
00089 }
00090
00091 }
00092
00093
00094
00095
00096 std::vector <LineSegment2D> houghTransform(Image<byte> &inputImage,
00097 float thetaRes,
00098 float dRes,
00099 int threshold,
00100 Image< PixRGB<byte> > &output)
00101 {
00102 LDEBUG("Inside houghTransform");
00103 int imageWidth = inputImage.getWidth();
00104 int imageHeight = inputImage.getHeight();
00105
00106 int numAngle = (int) (360 / thetaRes);
00107 int numP = (int) (((max(imageHeight, imageWidth) / 2) - 1) / dRes);
00108
00109
00110
00111 std::vector <LineSegment2D> lines;
00112
00113
00114 int accumulator[numP][numAngle];
00115
00116 LDEBUG("Clearing accumulator");
00117
00118
00119 for(int i = 0; i<numP; i++)
00120 {
00121 for(int j = 0; j < numAngle; j++)
00122 {
00123 accumulator[i][j] = 0;
00124 }
00125 }
00126
00127
00128
00129
00130
00131 LDEBUG("Accumulator is cleared");
00132
00133 float theta;
00134 for(int p = 0; p < numP; p++)
00135 {
00136 for(int angle = 0; angle < numAngle; angle++)
00137 {
00138 theta = angle * thetaRes;
00139
00140
00141 if(theta == 180)
00142 theta = 271;
00143
00144 Point2D<int> intercept1, intercept2;
00145
00146 findEndPoints(p, theta, &intercept1, &intercept2, Dims(imageWidth, imageHeight));
00147
00148
00149
00150
00151 int x0 = intercept1.i;
00152 int x1 = intercept1.j;
00153 int y0 = intercept2.i;
00154 int y1 = intercept2.j;
00155
00156 bool steep = abs(y1 - y0) > abs(x1 - x0);
00157 if(steep)
00158 {
00159 swap(x0, y0);
00160 swap(x1, y1);
00161 }
00162
00163 if(x0 > x1)
00164 {
00165 swap(x0, x1);
00166 swap(y0, y1);
00167 }
00168
00169 int deltax = x1 - x0;
00170 int deltay = abs(y1 - y0);
00171 int error = -deltax / 2;
00172 int ystep;
00173 int y = y0;
00174 int x;
00175
00176 if(y0 < y1)
00177 {
00178 ystep = 1;
00179 }
00180 else
00181 {
00182 ystep = -1;
00183 }
00184
00185 for(x = x0; x < x1; x++)
00186 {
00187 if(steep)
00188 {
00189 if(inputImage.getVal(y,x) == 255)
00190 {
00191 accumulator[p][angle]++;
00192 }
00193 }
00194 else
00195 {
00196 if(inputImage.getVal(x,y) == 255)
00197 {
00198 accumulator[p][angle]++;
00199 }
00200 }
00201
00202 error = error + deltay;
00203
00204 if(error > 0)
00205 {
00206 y = y + ystep;
00207 error = error - deltax;
00208 }
00209 }
00210
00211 for(int i = 0; i<numP; i++)
00212 {
00213 for(int j = 0; j < numAngle; j++)
00214 {
00215 theta = j * thetaRes;
00216 if(accumulator[i][j] > threshold && accumulator[i][j] > accumulator[i-1][j]
00217 && accumulator[i][j] > accumulator[i+1][j] && accumulator[i][j] > accumulator[i][j-1]
00218 && accumulator[i][j] > accumulator[i][j+1])
00219 {
00220 Point2D<int> lineEndPoint1, lineEndPoint2;
00221 findEndPoints(i , theta, &lineEndPoint1, &lineEndPoint2, Dims(imageWidth, imageHeight));
00222
00223 LineSegment2D theLine(lineEndPoint1, lineEndPoint2);
00224
00225 lines.push_back(theLine);
00226 }
00227 }
00228 }
00229
00230 }
00231 }
00232
00233 return lines;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 #endif
00407