00001
00002
00003
00004
00005
00006
00007 #include "GT2004EdgeSpecialist.h"
00008 #include "Representations/Perception/Image.h"
00009 #include "Representations/Perception/EdgesPercept.h"
00010 #include "GT2004ImageProcessorTools.h"
00011 #include <list>
00012 #include "Tools/Math/Common.h"
00013
00014 GT2004EdgeSpecialist::GT2004EdgeSpecialist
00015 (
00016 )
00017 {
00018
00019 greenBefore = false;
00020 whiteBefore = false;
00021 numberOfContinuousNoColor = 0;
00022
00023
00024 gradientThreshold = 8;
00025 double c = cos(3*pi/4);
00026 double s = sin(3*pi/4);
00027 const Matrix2x2<double> rotation(
00028 Vector2<double>(c,s),
00029 Vector2<double>(-s,c)
00030 );
00031 const Matrix2x2<double> invertY(
00032 Vector2<double>(1,0),
00033 Vector2<double>(0,-1)
00034 );
00035 referenceChange = invertY*rotation;
00036
00037 normDistance = 1.0;
00038 normProjection = 0.98;
00039 multipleAverageDistance = 2.0;
00040 }
00041
00042 void GT2004EdgeSpecialist::reset()
00043 {
00044 numOfEdgePoints = 0;
00045 }
00046
00047 void GT2004EdgeSpecialist::resetLine()
00048 {
00049 greenBefore = false;
00050 whiteBefore = false;
00051 numberOfContinuousNoColor = 0;
00052 }
00053
00054 void GT2004EdgeSpecialist::checkPoint(const Vector2<int> point, const colorClass color, const CameraMatrix& cameraMatrix, const CameraMatrix& prevCameraMatrix, const Image& image)
00055 {
00056 Vector2<int> pointOnField;
00057 if(Geometry::calculatePointOnField(point.x, point.y, cameraMatrix, image.cameraInfo, pointOnField))
00058 {
00059 switch(color)
00060 {
00061 case green:
00062 lastGreen = point;
00063 lastGreenField = pointOnField;
00064 if(whiteBefore)
00065 {
00066
00067 addCandidate(lastGreen, image);
00068 }
00069 greenBefore = true;
00070 whiteBefore = false;
00071 numberOfContinuousNoColor = 0;
00072 break;
00073 case white:
00074 lastWhite = pointOnField;
00075 if(greenBefore)
00076 {
00077
00078 addCandidate(lastGreen, image);
00079 }
00080 greenBefore = false;
00081 whiteBefore = true;
00082 numberOfContinuousNoColor = 0;
00083 break;
00084 case noColor:
00085 numberOfContinuousNoColor++;
00086 break;
00087 default:
00088 greenBefore = false;
00089 whiteBefore = false;
00090 numberOfContinuousNoColor = 0;
00091 break;
00092 }
00093 }
00094
00095 }
00096
00097 void GT2004EdgeSpecialist::addCandidate(const Vector2<int> point, const Image& image)
00098 {
00099 gradientThreshold = 3;
00100
00101
00102 Vector2<double> grad = Vector2<double>(image.image[point.y][0][point.x] - image.image[(point.y)-1][0][(point.x)-1] ,
00103 image.image[(point.y)-1][0][point.x] - image.image[point.y][0][(point.x)-1]);
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 if (grad.abs() > gradientThreshold)
00124 {
00125 if (numOfEdgePoints < maxNumberOfEdgePoints)
00126 {
00127 edgePoints[numOfEdgePoints].offset = point;
00128 Vector2<double> gradRotated = referenceChange * grad;
00129 edgePoints[numOfEdgePoints].line = Geometry::Line(point, gradRotated.normalize());
00130 edgePoints[numOfEdgePoints].weight = 0;
00131 edgePoints[numOfEdgePoints].belongsToLineNo = -1;
00132 DOT(imageProcessor_edges, point.x, point.y, 0, 1);
00133 numOfEdgePoints++;
00134 }
00135 else
00136 {
00137 OUTPUT(idText,text,"EdgeSpecialist: candidate-point drop (raise maxNumberOfEdgePoints)");
00138 }
00139 }
00140 }
00141
00142 void GT2004EdgeSpecialist::getEdgesPercept(EdgesPercept& percept, const CameraMatrix& cameraMatrix, const CameraMatrix& prevCameraMatrix, const Image& image)
00143 {
00144 int i, j;
00145
00146
00147 bool similar[maxNumberOfEdgePoints][maxNumberOfEdgePoints];
00148 for(i = 0; i < numOfEdgePoints; i++)
00149 {
00150 int lineHeightI = Geometry::calculateLineSize(edgePoints[i].offset, cameraMatrix, image.cameraInfo);
00151 for(j = i + 1; j < numOfEdgePoints; j++)
00152 {
00153
00154 bool sim = false;
00155
00156 double projection = edgePoints[i].line.direction * edgePoints[j].line.direction;
00157 if(projection > normProjection)
00158 {
00159
00160
00161
00162 double distance1 = fabs((edgePoints[j].line.base - edgePoints[i].line.base) * edgePoints[i].line.direction);
00163 int lineHeightJ = Geometry::calculateLineSize(edgePoints[j].offset, cameraMatrix, image.cameraInfo);
00164 double lineHeight = sqrt(double(min(lineHeightI, lineHeightJ)));
00165 if(distance1 < normDistance * lineHeight)
00166 {
00167 double distance2 = fabs((edgePoints[i].line.base - edgePoints[j].line.base) * edgePoints[j].line.direction);
00168 sim = (distance2 < normDistance * lineHeight);
00169 }
00170 }
00171 similar[i][j] = sim;
00172 similar[j][i] = sim;
00173
00174
00175
00176
00177
00178
00179
00180
00181 }
00182 }
00183
00184
00185 int maxWeight = 0;
00186 int colorArrow = 0;
00187 int colorEdge = 0;
00188 for(int m = 0; m < 10; m++)
00189 {
00190 int edgePointWithHighestWeight = -1;
00191 maxWeight = 0;
00192
00193
00194 for(i = 0; i < numOfEdgePoints; i++)
00195 {
00196 if(edgePoints[i].belongsToLineNo == -1)
00197 for (j = i + 1; j < numOfEdgePoints; j++)
00198 {
00199 if(edgePoints[j].belongsToLineNo == -1)
00200 if(similar[i][j])
00201 {
00202
00203 edgePoints[i].weight++;
00204 edgePoints[j].weight++;
00205
00206 if(edgePoints[i].weight > maxWeight)
00207 {
00208 maxWeight = edgePoints[i].weight;
00209 edgePointWithHighestWeight = i;
00210 }
00211 if(edgePoints[j].weight > maxWeight)
00212 {
00213 maxWeight = edgePoints[j].weight;
00214 edgePointWithHighestWeight = j;
00215 }
00216 }
00217 }
00218 }
00219
00220
00221 if(maxWeight<1) break;
00222
00223
00224 DOT(imageProcessor_edges, edgePoints[edgePointWithHighestWeight].offset.x, edgePoints[edgePointWithHighestWeight].offset.y, colorArrow, colorArrow);
00225
00226
00227 Vector2<int>start, end;
00228 int numberOfEdges = 0;
00229 double averageDistance;
00230 struct Edge
00231 {
00232
00233 std::list <int> pointIndices;
00234 };
00235 std::list <int>::iterator it;
00236 Edge edges[30];
00237 for(i = 0; i < 30; i++) edges[i].pointIndices.clear();
00238
00239
00240 for(i = 0; i < numOfEdgePoints; i++)
00241 {
00242 if(edgePoints[i].belongsToLineNo == -1)
00243 {
00244 if(similar[i][edgePointWithHighestWeight])
00245 {
00246 ARROW(imageProcessor_edges,
00247 edgePoints[i].line.base.x,
00248 edgePoints[i].line.base.y,
00249 edgePoints[i].line.base.x + edgePoints[i].line.direction.x * 10,
00250 edgePoints[i].line.base.y + edgePoints[i].line.direction.y * 10, 1, 1, colorArrow
00251 );
00252
00253 for(it = edges[numberOfEdges].pointIndices.begin( ); it != edges[numberOfEdges].pointIndices.end( ); it++)
00254 {
00255 if(edgePoints[*it].offset.x > edgePoints[i].offset.x) break;
00256 }
00257 edges[numberOfEdges].pointIndices.insert(it, i);
00258 }
00259 }
00260 }
00261 colorArrow++;
00262 numberOfEdges++;
00263
00264
00265
00266
00267 if(edges[0].pointIndices.size() <= 1) continue;
00268 start = edgePoints[edges[0].pointIndices.front()].offset;
00269 end = edgePoints[edges[0].pointIndices.back()].offset;
00270
00271 averageDistance = Geometry::distance(start, end) / edges[0].pointIndices.size();
00272
00273 int current, last, size;
00274
00275 it = edges[numberOfEdges-1].pointIndices.begin();
00276 bool finished = (it != edges[numberOfEdges-1].pointIndices.end());
00277 while(finished)
00278 {
00279 size = edges[numberOfEdges-1].pointIndices.size();
00280 last = *it;
00281 it++;
00282 if(it != edges[numberOfEdges-1].pointIndices.end())
00283 {
00284 current = *it;
00285 int x1 = edgePoints[last].offset.x;
00286 int x2 = edgePoints[current].offset.x;
00287 if(x1 + multipleAverageDistance * averageDistance < x2)
00288 {
00289
00290 edges[numberOfEdges].pointIndices.splice(
00291 edges[numberOfEdges].pointIndices.begin(),
00292 edges[numberOfEdges-1].pointIndices,
00293 it,
00294 edges[numberOfEdges-1].pointIndices.end()
00295 );
00296 it = std::list <int>::iterator(edges[numberOfEdges].pointIndices.begin());
00297 numberOfEdges++;
00298 }
00299 }
00300 finished = (it != edges[numberOfEdges-1].pointIndices.end());
00301 }
00302
00303
00304
00305 for(int j = 0; j < numberOfEdges; j++)
00306 {
00307
00308 if(edges[j].pointIndices.size() > 4)
00309 {
00310
00311 for(it = edges[j].pointIndices.begin(); it != edges[j].pointIndices.end(); it++)
00312 {
00313 i = *it;
00314 Vector2<int> pointOnField;
00315 if(Geometry::calculatePointOnField(edgePoints[i].offset.x, edgePoints[i].offset.y, cameraMatrix, prevCameraMatrix, image.cameraInfo, pointOnField))
00316 {
00317 edgePoints[i].belongsToLineNo = edgePointWithHighestWeight;
00318 edgePoints[i].weight = 0;
00319 }
00320 }
00321 start = edgePoints[edges[j].pointIndices.front()].offset;
00322 end = edgePoints[edges[j].pointIndices.back()].offset;
00323 LINE(imageProcessor_edges,
00324 start.x,
00325 start.y,
00326 end.x,
00327 end.y,
00328 1, 1, colorEdge
00329 );
00330 Vector2<int> point1OnField, point2OnField;
00331 Geometry::calculatePointOnField(start.x, start.y, cameraMatrix, prevCameraMatrix, image.cameraInfo, point1OnField);
00332 Geometry::calculatePointOnField(end.x, end.y, cameraMatrix, prevCameraMatrix, image.cameraInfo, point2OnField);
00333 percept.add(point1OnField, point2OnField);
00334 }
00335 }
00336 colorEdge++;
00337 if(edgePoints[edgePointWithHighestWeight].belongsToLineNo == -1) edgePoints[edgePointWithHighestWeight].belongsToLineNo = -2;
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