Go to the documentation of this file.00001 #include "EdgeDetection/MacroEdgeDetector.h"
00002
00003 #include "EdgeDetection/Vector2.h"
00004 #include "EdgeDetection/Edge.h"
00005
00006 #include <vector>
00007
00008 namespace EdgeDetection
00009 {
00010 Line MacroEdgeDetector::DetectEdge(Image* image, BoundedLine estimatedEdge)
00011 {
00012
00013
00014
00015 if (estimatedEdge.GetLength() < 3 * microEdgeDetector->GetSize()) throw "The estimated edge cannot be shorter than three times the window size.";
00016
00017 vector<Vector2> edgePoints;
00018
00019 double stepFraction = microEdgeDetector->GetSize() / estimatedEdge.GetLength();
00020 double start = 0 + stepFraction;
00021 double end = 1 - stepFraction;
00022
00023 for (double fraction = start; fraction <= end; fraction += stepFraction)
00024 {
00025 Vector2 position = estimatedEdge.GetPosition(fraction);
00026
00027 int windowLeft = Round(position.GetX() + 0.5 - 0.5 * microEdgeDetector->GetSize());
00028 int windowRight = Round(position.GetX() + 0.5 + 0.5 * microEdgeDetector->GetSize());
00029 int windowTop = Round(position.GetY() + 0.5 - 0.5 * microEdgeDetector->GetSize());
00030 int windowBottom = Round(position.GetY() + 0.5 + 0.5 * microEdgeDetector->GetSize());
00031
00032 Image* windowRegion = image->GetRegion(windowLeft, windowRight, windowTop, windowBottom);
00033
00034 Edge measuredEdge = microEdgeDetector->DetectEdge(windowRegion);
00035 Edge correctedEdge = microEdgeCorrectionTable->Correct(measuredEdge);
00036
00037 delete windowRegion;
00038
00039 Vector2 windowCenter = Vector2(0.5 * ((windowLeft - 0.5) + (windowRight - 0.5)), 0.5 * ((windowTop - 0.5) + (windowBottom - 0.5)));
00040 Vector2 edgeCenter = Vector2::Add(windowCenter, Vector2::Multiply(0.5 * microEdgeDetector->GetSize(), correctedEdge.GetCenter()));
00041 Vector2 correctedEdgeCenter = pointCorrector->CorrectPoint(edgeCenter);
00042
00043
00044
00045
00046 edgePoints.push_back(correctedEdgeCenter);
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 }
00057
00058 double averageX = 0;
00059 for (vector<Vector2>::iterator edgePoint = edgePoints.begin(); edgePoint < edgePoints.end(); edgePoint++) averageX += edgePoint->GetX();
00060 averageX /= edgePoints.size();
00061
00062 double averageY = 0;
00063 for (vector<Vector2>::iterator edgePoint = edgePoints.begin(); edgePoint < edgePoints.end(); edgePoint++) averageY += edgePoint->GetY();
00064 averageY /= edgePoints.size();
00065
00066 double momentXX = 0;
00067 for (vector<Vector2>::iterator edgePoint = edgePoints.begin(); edgePoint < edgePoints.end(); edgePoint++) momentXX += (edgePoint->GetX() - averageX) * (edgePoint->GetX() - averageX);
00068 momentXX /= edgePoints.size() - 1;
00069
00070 double momentYY = 0;
00071 for (vector<Vector2>::iterator edgePoint = edgePoints.begin(); edgePoint < edgePoints.end(); edgePoint++) momentYY += (edgePoint->GetY() - averageY) * (edgePoint->GetY() - averageY);
00072 momentYY /= edgePoints.size() - 1;
00073
00074 double momentXY = 0;
00075 for (vector<Vector2>::iterator edgePoint = edgePoints.begin(); edgePoint < edgePoints.end(); edgePoint++) momentXY += (edgePoint->GetX() - averageX) * (edgePoint->GetY() - averageY);
00076 momentXY /= edgePoints.size() - 1;
00077
00078 double a = momentXX - momentYY;
00079 double b = momentXY + momentXY;
00080 double c = a * a + b * b;
00081
00082 double factorX = - b * averageX + a * averageY - sqrt(c) * averageY;
00083 double factorY = + b * averageY + a * averageX + sqrt(c) * averageX;
00084 double offset = b * averageX * averageX - 2 * a * averageX * averageY - b * averageY * averageY;
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 return Line(factorX, factorY, offset);
00119 }
00120 };