00001
00002
00003
00004
00005
00006
00007 #include "GT2005EdgeSpecialist.h"
00008 #include "Representations/Perception/Image.h"
00009 #include "Representations/Perception/EdgesPercept.h"
00010 #include "GT2005ImageProcessorTools.h"
00011 #include <list>
00012 #include "Tools/Math/Common.h"
00013
00014 GT2005EdgeSpecialist::GT2005EdgeSpecialist
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 GT2005EdgeSpecialist::reset()
00043 {
00044 numOfEdgePoints = 0;
00045 }
00046
00047 void GT2005EdgeSpecialist::resetLine()
00048 {
00049 greenBefore = false;
00050 whiteBefore = false;
00051 numberOfContinuousNoColor = 0;
00052 }
00053
00054 void GT2005EdgeSpecialist::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 GT2005EdgeSpecialist::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 NDOT("gt05ip:edges-candidate-points", point.x, point.y, 0, 1);
00134 numOfEdgePoints++;
00135 }
00136 else
00137 {
00138 OUTPUT(idText,text,"EdgeSpecialist: candidate-point drop (raise maxNumberOfEdgePoints)");
00139 }
00140 }
00141 }
00142
00143 void GT2005EdgeSpecialist::getEdgesPercept(EdgesPercept& percept, const CameraMatrix& cameraMatrix, const CameraMatrix& prevCameraMatrix, const Image& image)
00144 {
00145 int i, j;
00146
00147 NDECLARE_DEBUGDRAWING( "gt05ip:edges-candidate-points" , "drawingOnImage" , "show candidate edge points" );
00148 NDECLARE_DEBUGDRAWING( "gt05ip:edges-points" , "drawingOnImage" , "show selected edge points" );
00149 NDECLARE_DEBUGDRAWING( "gt05ip:edges" , "drawingOnImage" , "show detected edges" );
00150
00151
00152 bool similar[maxNumberOfEdgePoints][maxNumberOfEdgePoints];
00153 int lineHeight[maxNumberOfEdgePoints];
00154 for(i = 1; i < numOfEdgePoints; i++)
00155 {
00156 lineHeight[i] = Geometry::calculateLineSize(edgePoints[i].offset, cameraMatrix, image.cameraInfo);
00157 for(j = 0; j < i; j++)
00158 {
00159
00160 bool sim = false;
00161
00162 double projection = edgePoints[i].line.direction * edgePoints[j].line.direction;
00163 if(projection > normProjection)
00164 {
00165
00166
00167
00168 double distance1 = (edgePoints[j].line.base - edgePoints[i].line.base) * edgePoints[i].line.direction;
00169 distance1 = distance1 * distance1;
00170 if(distance1 < normDistance * lineHeight[i])
00171 {
00172 double distance2 = (edgePoints[i].line.base - edgePoints[j].line.base) * edgePoints[j].line.direction;
00173 distance2 = distance2 * distance2;
00174 sim = (distance2 < normDistance * lineHeight[j]);
00175 }
00176 }
00177 similar[i][j] = sim;
00178 similar[j][i] = sim;
00179
00180
00181
00182
00183
00184
00185
00186
00187 }
00188 }
00189
00190
00191 int maxWeight = 0;
00192 int colorArrow = 0;
00193 int colorEdge = 0;
00194 for(int m = 0; m < 10; m++)
00195 {
00196 int edgePointWithHighestWeight = -1;
00197 maxWeight = 0;
00198
00199
00200 for(i = 0; i < numOfEdgePoints; i++)
00201 {
00202 if(edgePoints[i].belongsToLineNo == -1)
00203 for (j = i + 1; j < numOfEdgePoints; j++)
00204 {
00205 if(edgePoints[j].belongsToLineNo == -1)
00206 if(similar[i][j])
00207 {
00208
00209 edgePoints[i].weight++;
00210 edgePoints[j].weight++;
00211
00212 if(edgePoints[i].weight > maxWeight)
00213 {
00214 maxWeight = edgePoints[i].weight;
00215 edgePointWithHighestWeight = i;
00216 }
00217 if(edgePoints[j].weight > maxWeight)
00218 {
00219 maxWeight = edgePoints[j].weight;
00220 edgePointWithHighestWeight = j;
00221 }
00222 }
00223 }
00224 }
00225
00226
00227 if(maxWeight<1) break;
00228
00229
00230 DOT(imageProcessor_edges, edgePoints[edgePointWithHighestWeight].offset.x, edgePoints[edgePointWithHighestWeight].offset.y, colorArrow, colorArrow);
00231 NDOT("gt05ip:edges-points", edgePoints[edgePointWithHighestWeight].offset.x, edgePoints[edgePointWithHighestWeight].offset.y, colorArrow, colorArrow);
00232
00233
00234 Vector2<int>start, end;
00235 int numberOfEdges = 0;
00236 double averageDistance;
00237 struct Edge
00238 {
00239
00240 std::list <int> pointIndices;
00241 };
00242 std::list <int>::iterator it;
00243 Edge edges[30];
00244 for(i = 0; i < 30; i++) edges[i].pointIndices.clear();
00245
00246
00247 for(i = 0; i < numOfEdgePoints; i++)
00248 {
00249 if(edgePoints[i].belongsToLineNo == -1)
00250 {
00251 if(similar[i][edgePointWithHighestWeight])
00252 {
00253 ARROW(imageProcessor_edges,
00254 edgePoints[i].line.base.x,
00255 edgePoints[i].line.base.y,
00256 edgePoints[i].line.base.x + edgePoints[i].line.direction.x * 10,
00257 edgePoints[i].line.base.y + edgePoints[i].line.direction.y * 10, 1, 1, colorArrow
00258 );
00259 NARROW("gt05ip:edges-points",
00260 edgePoints[i].line.base.x,
00261 edgePoints[i].line.base.y,
00262 edgePoints[i].line.base.x + edgePoints[i].line.direction.x * 10,
00263 edgePoints[i].line.base.y + edgePoints[i].line.direction.y * 10, 1, 1, colorArrow
00264 );
00265
00266 for(it = edges[numberOfEdges].pointIndices.begin( ); it != edges[numberOfEdges].pointIndices.end( ); it++)
00267 {
00268 if(edgePoints[*it].offset.x > edgePoints[i].offset.x) break;
00269 }
00270 edges[numberOfEdges].pointIndices.insert(it, i);
00271 }
00272 }
00273 }
00274 colorArrow++;
00275 numberOfEdges++;
00276
00277
00278
00279
00280 if(edges[0].pointIndices.size() <= 1) continue;
00281 start = edgePoints[edges[0].pointIndices.front()].offset;
00282 end = edgePoints[edges[0].pointIndices.back()].offset;
00283
00284 averageDistance = Geometry::distance(start, end) / edges[0].pointIndices.size();
00285
00286 int current, last, size;
00287
00288 it = edges[numberOfEdges-1].pointIndices.begin();
00289 bool finished = (it != edges[numberOfEdges-1].pointIndices.end());
00290 while(finished)
00291 {
00292 size = edges[numberOfEdges-1].pointIndices.size();
00293 last = *it;
00294 it++;
00295 if(it != edges[numberOfEdges-1].pointIndices.end())
00296 {
00297 current = *it;
00298 int x1 = edgePoints[last].offset.x;
00299 int x2 = edgePoints[current].offset.x;
00300 if(x1 + multipleAverageDistance * averageDistance < x2)
00301 {
00302
00303 edges[numberOfEdges].pointIndices.splice(
00304 edges[numberOfEdges].pointIndices.begin(),
00305 edges[numberOfEdges-1].pointIndices,
00306 it,
00307 edges[numberOfEdges-1].pointIndices.end()
00308 );
00309 it = std::list <int>::iterator(edges[numberOfEdges].pointIndices.begin());
00310 numberOfEdges++;
00311 }
00312 }
00313 finished = (it != edges[numberOfEdges-1].pointIndices.end());
00314 }
00315
00316
00317
00318 for(int j = 0; j < numberOfEdges; j++)
00319 {
00320
00321 if(edges[j].pointIndices.size() > 4)
00322 {
00323
00324 for(it = edges[j].pointIndices.begin(); it != edges[j].pointIndices.end(); it++)
00325 {
00326 i = *it;
00327 Vector2<double> pointOnField;
00328 if(Geometry::calculatePointOnField(edgePoints[i].offset.x, edgePoints[i].offset.y, cameraMatrix, prevCameraMatrix, image.cameraInfo, pointOnField))
00329 {
00330 edgePoints[i].belongsToLineNo = edgePointWithHighestWeight;
00331 edgePoints[i].weight = 0;
00332 }
00333 }
00334 start = edgePoints[edges[j].pointIndices.front()].offset;
00335 end = edgePoints[edges[j].pointIndices.back()].offset;
00336 LINE(imageProcessor_edges,
00337 start.x,
00338 start.y,
00339 end.x,
00340 end.y,
00341 1, 1, colorEdge
00342 );
00343 NLINE("gt05ip:edges",
00344 start.x,
00345 start.y,
00346 end.x,
00347 end.y,
00348 1, 1, colorEdge
00349 );
00350 Vector2<double> point1OnField, point2OnField;
00351 Geometry::calculatePointOnField(start.x, start.y, cameraMatrix, prevCameraMatrix, image.cameraInfo, point1OnField);
00352 Geometry::calculatePointOnField(end.x, end.y, cameraMatrix, prevCameraMatrix, image.cameraInfo, point2OnField);
00353 Vector2<double> grad = edgePoints[edges[j].pointIndices.front()].line.direction;
00354 Vector2<double> dir(grad.y, -grad.x);
00355 if ((edgePoints[edges[j].pointIndices.back()].line.base - edgePoints[edges[j].pointIndices.front()].line.base) * dir > 0)
00356 percept.add(point2OnField, point1OnField, end, start);
00357 else
00358 percept.add(point1OnField, point2OnField, start, end);
00359 }
00360 }
00361 colorEdge++;
00362 if(edgePoints[edgePointWithHighestWeight].belongsToLineNo == -1) edgePoints[edgePointWithHighestWeight].belongsToLineNo = -2;
00363 }
00364 }