00001
00002 #include "VLCCenterCircleFinder.h"
00003
00004 VLCCenterCircleFinder::VLCCenterCircleFinder(const CameraMatrix& cMatrix, const Image& im):cameraMatrix(cMatrix), image(im)
00005 {
00006 circleFound = false;
00007 numberOfCandidates = 0;
00008 houghStepX = areaOfInterestX/houghDimensionX;
00009 houghStepY = areaOfInterestY/houghDimensionY;
00010
00011 for(int i = 0; i < maxNumber; i++)
00012 {
00013 circlePoints[i] = true;
00014 }
00015
00016 for(int i = 0; i < houghDimensionY; i++)
00017 {
00018 for(int j = 0; j < houghDimensionX; j++)
00019 houghSpace[i][j] = 0;
00020 flagY[i] = false;
00021 }
00022 }
00023
00024 void VLCCenterCircleFinder::reset()
00025 {
00026 circleFound = false;
00027 numberOfCandidates = 0;
00028
00029 for(int i = 0; i < maxNumber; i++)
00030 {
00031 circlePoints[i] = true;
00032 }
00033
00034 for(int i = 0; i < houghDimensionY; i++)
00035 {
00036 for(int j = 0; j < houghDimensionX; j++)
00037 houghSpace[i][j] = 0;
00038 flagY[i] = false;
00039 }
00040 }
00041
00042 void VLCCenterCircleFinder::addCandidate(Vector2<int>& candiOnField, Vector2<int>& candiOfImage)
00043 {
00044
00045
00046
00047
00048
00049
00050
00051
00052 if((candiOnField.x < areaOfInterestX/2) && (candiOnField.x > -areaOfInterestX/2) &&
00053 (candiOnField.y < areaOfInterestY/2) && (candiOnField.y > -areaOfInterestY/2))
00054 {
00055 if(numberOfCandidates < maxNumber)
00056 {
00057
00058
00059
00060 bool setAverage = false;
00061 for(int i = 0; i < numberOfCandidates; i++)
00062 {
00063 double distance;
00064 distance = sqrt(sqr(candidatePoints[i].pointOnField.x - candiOnField.x) + sqr(candidatePoints[i].pointOnField.y - candiOnField.y));
00065 if(distance < mergeDistance)
00066 {
00067 double x,y;
00068 x = (candidatePoints[i].pointOfImage.x + candiOfImage.x)/2;
00069 y = (candidatePoints[i].pointOfImage.y + candiOfImage.y)/2;
00070 candidatePoints[i].pointOfImage.x = int(x);
00071 candidatePoints[i].pointOfImage.y = int(y);
00072
00073 x = (candidatePoints[i].pointOnField.x + candiOnField.x)/2;
00074 y = (candidatePoints[i].pointOnField.y + candiOnField.y)/2;
00075 candidatePoints[i].pointOnField.x = x;
00076 candidatePoints[i].pointOnField.y = y;
00077 setAverage = true;
00078 }
00079 }
00080 if(setAverage == false)
00081 {
00082 Vector2<double> nullVector(0,0);
00083 candidatePoints[numberOfCandidates].pointOnField.x = double(candiOnField.x);
00084 candidatePoints[numberOfCandidates].pointOnField.y = double(candiOnField.y);
00085 candidatePoints[numberOfCandidates].pointOfImage = candiOfImage;
00086 numberOfCandidates++;
00087 }
00088 }
00089 else
00090 {
00091
00092 }
00093 }
00094
00095 }
00096
00097
00098
00099 void VLCCenterCircleFinder::transformArrayToField(int arrayIndex, bool xDirection, int& fieldPosition)
00100 {
00101 int border;
00102 int step;
00103 int dimension;
00104 if(xDirection)
00105 {
00106 border = areaOfInterestX;
00107 step = houghStepX;
00108 dimension = houghDimensionX;
00109 }
00110 else
00111 {
00112 border = areaOfInterestY;
00113 step = houghStepY;
00114 dimension = houghDimensionY;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 if(arrayIndex < (dimension/2))
00128 {
00129 fieldPosition = border/2 - step/2 - arrayIndex * step;
00130 }
00131 else if((arrayIndex >= (dimension/2)) && (arrayIndex < dimension))
00132 {
00133 fieldPosition = - step/2 - (arrayIndex-dimension/2) * step;
00134 }
00135 }
00136
00137
00138 void VLCCenterCircleFinder::transformFieldToArray(double fieldPos, bool xDirection, int& arrayIndex)
00139 {
00140 int border;
00141 int step;
00142 int dimension;
00143 if(xDirection)
00144 {
00145 border = areaOfInterestX;
00146 step = houghStepX;
00147 dimension = houghDimensionX;
00148 }
00149 else
00150 {
00151 border = areaOfInterestY;
00152 step = houghStepY;
00153 dimension = houghDimensionY;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 if((fieldPos >= 0) && (fieldPos < (border/2)))
00169 {
00170 arrayIndex = (dimension/2 - 1) - (int(fieldPos) / step);
00171 }
00172 else if((fieldPos < 0) && (fieldPos > -(border/2)))
00173 {
00174 fieldPos *= -1;
00175 arrayIndex = (int(fieldPos) / step) + (dimension/2);
00176 }
00177
00178 }
00179
00180 void VLCCenterCircleFinder::determineCirclePoint()
00181 {
00182
00183
00184 int xc = 0;
00185 int xc1 = 0;
00186 int yc = 0;
00187
00188
00189 for(int i = 0; i < numberOfCandidates; i++)
00190 {
00191 if(circlePoints[i] != false)
00192 {
00193 double help = 0;
00194 for(int y = 0; y < houghDimensionY; y++)
00195 {
00196 transformArrayToField(y,false,yc);
00197 help = double(radius - sqr(candidatePoints[i].pointOnField.y - yc));
00198 if(help > 0)
00199 {
00200 help = sqrt(help);
00201 xc = int(candidatePoints[i].pointOnField.x - help);
00202 xc1 = int(help + candidatePoints[i].pointOnField.x);
00203 int arrayIndex;
00204 if((xc < (areaOfInterestX/2)) && (xc > (-areaOfInterestX/2)))
00205 {
00206 transformFieldToArray(xc,true,arrayIndex),
00207 houghSpace[arrayIndex][y] += 1;
00208 flagY[y] = true;
00209 }
00210 if((xc1 < (areaOfInterestX/2)) && (xc1 > (-areaOfInterestX/2)))
00211 {
00212 transformFieldToArray(xc1,true,arrayIndex),
00213 houghSpace[arrayIndex][y] += 1;
00214 flagY[y] = true;
00215 }
00216
00217 }
00218
00219 }
00220
00221 }
00222 }
00223
00224
00225 int maxEntry = 0;
00226 int absMaxEntry = 0;
00227 bool existMaxEntry = false;
00228 xc = 0;
00229 yc = 0;
00230 for(int y = 0; y < houghDimensionY; y++)
00231 {
00232 if(flagY[y] == true)
00233 {
00234 for(int x = 0; x < houghDimensionX; x++)
00235 {
00236 if(houghSpace[x][y] >= maxEntry)
00237 {
00238 if(houghSpace[x][y] > absMaxEntry)
00239 {
00240 existMaxEntry = true;
00241 absMaxEntry = houghSpace[x][y];
00242 transformArrayToField(x,true,xc);
00243 transformArrayToField(y,false,yc);
00244 }
00245 else if(houghSpace[x][y] == absMaxEntry)
00246 {
00247 existMaxEntry = false;
00248 maxEntry = houghSpace[x][y];
00249 }
00250
00251 }
00252 }
00253 }
00254 }
00255
00256 if((maxEntry >= mEntry) || existMaxEntry)
00257 {
00258 if((existMaxEntry)&&(absMaxEntry >= aMaxEntry))
00259 {
00260 circleFound = true;
00261 midPoint.x = xc;
00262 midPoint.y = yc;
00263 CIRCLE(circlePoints_Field, xc, yc, 180, 30,Drawings::ps_dash, Drawings::blue);
00264 Vector2<int> midpointOnField;
00265 midpointOnField.x = int(xc);
00266 midpointOnField.y = int(yc);
00267 Vector2<int> midpointInImage;
00268 Geometry::calculatePointInImage(midpointOnField,cameraMatrix,image.cameraInfo,midpointInImage);
00269 DOT(circlePoints_image, midpointInImage.x, midpointInImage.y, Drawings::black, Drawings:: blue);
00270 }
00271 else if(maxEntry > mEntry)
00272 {
00273 for(int y = 0; y < houghDimensionY; y++)
00274 {
00275 if(flagY[y] == true)
00276 {
00277 for(int x = 0; x < houghDimensionX; x++)
00278 {
00279 if(houghSpace[x][y] == maxEntry)
00280 {
00281 transformArrayToField(x,true,xc);
00282 transformArrayToField(y,false,yc);
00283 CIRCLE(circlePoints_Field, xc, yc, 30, 30,Drawings::ps_dash, Drawings::green);
00284 Vector2<int> midpointOnField;
00285 midpointOnField.x = int(xc);
00286 midpointOnField.y = int(yc);
00287 Vector2<int> midpointInImage;
00288 Geometry::calculatePointInImage(midpointOnField,cameraMatrix,image.cameraInfo,midpointInImage);
00289 DOT(circlePoints_image, midpointInImage.x, midpointInImage.y, Drawings::black, Drawings::green);
00290 }
00291 }
00292 }
00293 }
00294 }
00295 }
00296
00297
00298 for(int i = 0; i < numberOfCandidates; i++)
00299 {
00300 if(circlePoints[i] != false)
00301 {
00302
00303 DOT(circlePoints_image, candidatePoints[i].pointOfImage.x, candidatePoints[i].pointOfImage.y, Drawings::black,Drawings::red);
00304 CIRCLE(circlePoints_Field, candidatePoints[i].pointOnField.x, candidatePoints[i].pointOnField.y, 30, 30,Drawings::ps_dash, Drawings::red);
00305
00306 }
00307 }
00308 }
00309
00310
00311 bool VLCCenterCircleFinder::getCircle(Vector2<double>& mid)
00312 {
00313 if(circleFound)
00314 {
00315 mid = midPoint;
00316 return(true);
00317 }
00318 else
00319 return(false);
00320 }
00321
00322
00323
00324
00325
00326