HoughTransform.C
Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef HoughTransform_C
00038 #define HoughTransform_C
00039
00040 #include "BeoSub/HoughTransform.H"
00041
00042 #include "Image/Image.H"
00043 #include "Image/Pixels.H"
00044 #include "Util/Timer.H"
00045 #include "Util/Types.H"
00046 #include "Util/log.H"
00047 #include "Image/ColorOps.H"
00048 #include "Image/Image.H"
00049 #include "Image/MathOps.H"
00050 #include "Image/DrawOps.H"
00051 #include "Image/FilterOps.H"
00052 #include "Image/Transforms.H"
00053 #include "Raster/Raster.H"
00054 #include "rutz/shared_ptr.h"
00055 #include "BeoSub/hysteresis.H"
00056 #include "VFAT/segmentImageTrackMC.H"
00057 #include <cstdio>
00058 #include <cstdlib>
00059 #include <cstring>
00060 #include <iostream>
00061 #include <math.h>
00062 #include <list>
00063 #include "Image/MatrixOps.H"
00064 #include "BeoSub/CannyEdge.H"
00065 #include "MBARI/Geometry2D.H"
00066 using namespace std;
00067
00068
00069
00070
00071
00072 std::vector <LineSegment2D> houghTransform
00073 (Image<byte> &inputImage, float thetaRes, float dRes, int threshold,
00074 Image< PixRGB<byte> > &output)
00075 {
00076
00077
00078
00079 uint w = inputImage.getWidth();
00080 uint h = inputImage.getHeight();
00081
00082
00083 int numAngle = (int) (M_PI / thetaRes);
00084 int numD = (int)(sqrt((w*w + h*h)/ dRes) / 2);
00085 int centerX = (int)(w/2);
00086 int centerY = (int)(h/2);
00087
00088 std::vector <LineSegment2D> lines;
00089 std::vector <Point2D<int> > edgePoints;
00090
00091
00092 for(int y = 0; y < inputImage.getHeight(); y++)
00093 {
00094 for(int x = 0; x < inputImage.getWidth(); x++)
00095 {
00096
00097 if(inputImage.getVal(x,y) == 255)
00098
00099
00100
00101 edgePoints.push_back(Point2D<int>(x - centerX, y - centerY));
00102 }
00103 }
00104
00105
00106 std::vector<std::vector<std::vector<Point2D<int> > > > ptList;
00107 ptList.resize(numD);
00108 for(int i = 0; i < numD; i++) ptList[i].resize(numAngle);
00109
00110
00111
00112
00113 for(uint c = 0; c < edgePoints.size(); c++)
00114 {
00115 int edgePointX = edgePoints[c].i;
00116 int edgePointY = edgePoints[c].j;
00117
00118
00119 for(int n = 0; n < numAngle; n++)
00120 {
00121 int r = (int)(edgePointX * cos(n*thetaRes) + edgePointY * sin(n*thetaRes));
00122
00123
00124
00125
00126 r = abs(r);
00127
00128 ptList[r][n].push_back(edgePoints[c]);
00129
00130 }
00131 }
00132
00133
00134
00135 for(int i = 1; i < numD - 1; i++) {
00136 for(int j = 1; j < numAngle - 1; j++)
00137 {
00138 uint currentPointCount = ptList[i][j].size();
00139
00140 if(currentPointCount > (unsigned int)(threshold) &&
00141 currentPointCount > ptList[i-1][j].size() &&
00142 currentPointCount > ptList[i+1][j].size() &&
00143 currentPointCount > ptList[i][j-1].size() &&
00144 currentPointCount > ptList[i][j+1].size() )
00145 {
00146
00147 int minx = ptList[i][j][1].i, maxx = ptList[i][j][1].i;
00148 int miny = ptList[i][j][1].j, maxy = ptList[i][j][1].j;
00149
00150 uint mini = 0, maxi = 0;
00151 for(uint k = 1; k < currentPointCount; k++)
00152 {
00153 if(minx > ptList[i][j][k].i)
00154 { minx = ptList[i][j][k].i; mini = k; }
00155 if(maxx < ptList[i][j][k].i)
00156 { maxx = ptList[i][j][k].i; maxi = k; }
00157 }
00158
00159
00160
00161
00162
00163 if(minx == maxx)
00164 {
00165 for(uint k = 1; k < currentPointCount; k++)
00166 {
00167 if(miny > ptList[i][j][k].j)
00168 { miny = ptList[i][j][k].j; mini = k; }
00169 if(maxy > ptList[i][j][k].j)
00170 { maxy = ptList[i][j][k].j; maxi = k; }
00171 }
00172 }
00173
00174
00175 Point2D<int> p1 = ptList[i][j][mini];
00176 Point2D<int> p2 = ptList[i][j][maxi];
00177
00178
00179
00180 p1.i += centerX;
00181 p1.j += centerY;
00182 p2.i += centerX;
00183 p2.j += centerY;
00184
00185 LineSegment2D thisLine(p1,p2);
00186
00187 if(thisLine.isValid())
00188 {
00189 lines.push_back(thisLine);
00190 drawLine(output, p1, p2, PixRGB<byte> (255,0,0), 1);
00191 }
00192 }
00193 }
00194 }
00195
00196 return lines;
00197
00198 }
00199
00200 #endif
00201
00202
00203
00204
00205
00206