00001 #include "EdgeDetection/AdaptiveRasterizer.h"
00002 #include "EdgeDetection/MicroEdgeDetector.h"
00003 #include "EdgeDetection/MicroEdgeCorrectionTable.h"
00004 #include "EdgeDetection/PointCorrector.h"
00005 #include "EdgeDetection/MacroEdgeDetector.h"
00006 #include "EdgeDetection/EdgeImage.h"
00007 #include "EdgeDetection/Image.h"
00008 #include "EdgeDetection/OwnedImage.h"
00009 #include "EdgeDetection/Edge.h"
00010 #include "EdgeDetection/Line.h"
00011 #include "EdgeDetection/BoundedLine.h"
00012
00013 #include <iostream>
00014 #include <fstream>
00015 #include <stdlib.h>
00016 #include <time.h>
00017
00018 using namespace std;
00019 using namespace EdgeDetection;
00020
00021 class NullPointCorrector : public PointCorrector
00022 {
00023 public: Vector2 CorrectPoint(Vector2 point) { return point; }
00024 };
00025
00026 double NextDouble()
00027 {
00028 return (double)rand() / (double)RAND_MAX;
00029 }
00030 double NextDouble(double minimum, double maximum)
00031 {
00032 return minimum + (maximum - minimum) * NextDouble();
00033 }
00034 double Clamp(double value, double minimum, double maximum)
00035 {
00036 value = max(value, minimum);
00037 value = min(value, maximum);
00038
00039 return value;
00040 }
00041 void SaveBitmap(Image* image, string path)
00042 {
00043 ifstream header("Header.bmp", ifstream::in | ifstream::binary);
00044
00045 ofstream bitmap(path.c_str(), ofstream::out | ofstream::binary);
00046
00047 bitmap << header.rdbuf();
00048
00049 for (int y = 0; y < image->GetHeight(); y++)
00050 for (int x = 0; x < image->GetWidth(); x++)
00051 {
00052 unsigned char value = (unsigned char)(image->Get(x, y) * 255);
00053
00054 bitmap.write((const char*)&value, sizeof(unsigned char));
00055 }
00056
00057 bitmap.close();
00058
00059 header.close();
00060 }
00061 double MeasureError(MacroEdgeDetector* macroEdgeDetector, BoundedLine realEdge, Image* image, double noiseLevel)
00062 {
00063 Line normalizedRealEdge = Line::Normalize(realEdge);
00064
00065 OwnedImage* noiseImage = new OwnedImage(image);
00066 for (int y = 0; y < noiseImage->GetHeight(); y++)
00067 for (int x = 0; x < noiseImage->GetWidth(); x++)
00068 noiseImage->Set(x, y, Clamp(noiseImage->Get(x, y) + NextDouble(-noiseLevel, +noiseLevel), 0, 1));
00069
00070
00071
00072
00073
00074 BoundedLine estimatedEdge = BoundedLine(Vector2(realEdge.GetStart().GetX() + NextDouble(-0.5, +0.5), realEdge.GetStart().GetY() + NextDouble(-0.5, +0.5)), Vector2(realEdge.GetEnd().GetX() + NextDouble(-0.5, +0.5), realEdge.GetEnd().GetY() + NextDouble(-0.5, +0.5)));
00075 Line normalizedEstimatedEdge = Line::Normalize(estimatedEdge);
00076
00077 Line measuredEdge = macroEdgeDetector->DetectEdge(noiseImage, estimatedEdge);
00078 Line normalizedMeasuredEdge = Line::Normalize(measuredEdge);
00079
00080 double realSlope = normalizedRealEdge.GetFactorX() / normalizedRealEdge.GetFactorY();
00081 double measuredSlope = normalizedMeasuredEdge.GetFactorX() / normalizedMeasuredEdge.GetFactorY();
00082
00083 if (abs(realSlope) > 1)
00084 {
00085 realSlope = 1 / realSlope;
00086 measuredSlope = 1 / measuredSlope;
00087 }
00088
00089 double error = abs(realSlope - measuredSlope);
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 delete noiseImage;
00105
00106 return error;
00107 }
00108 void GenerateStatistics(Rasterizer* rasterizer, MacroEdgeDetector* macroEdgeDetector, double noiseLevel, int edgeSampleCount)
00109 {
00110 cout << "Generating statistics (Noise level: " << noiseLevel << ")... ";
00111
00112 double errorMinimum = -1;
00113 double errorMaximum = -1;
00114 double errorSum = 0;
00115
00116 for (int i = 0; i < edgeSampleCount; i++)
00117 {
00118 BoundedLine line;
00119 while (line.GetLength() < 50) line = BoundedLine(Vector2(NextDouble(5, 95), NextDouble(5, 95)), Vector2(NextDouble(5, 95), NextDouble(5, 95)));
00120
00121 EdgeImage* edgeImage = new EdgeImage(line, Rectangle(-0.5, +99.5, -0.5, +99.5));
00122 Image* image = rasterizer->Rasterize(edgeImage, 100, 100);
00123
00124 double error = MeasureError(macroEdgeDetector, line, image, noiseLevel);
00125
00126 if (errorMinimum == -1 || error < errorMinimum) errorMinimum = error;
00127 if (errorMaximum == -1 || error > errorMaximum) errorMaximum = error;
00128 errorSum += error;
00129
00130 delete image;
00131 delete edgeImage;
00132 }
00133
00134 double errorAverage = errorSum / edgeSampleCount;
00135
00136 cout << "Errors: Minimum: " << errorMinimum << ", Maximum: " << errorMaximum << ", Average: " << errorAverage << endl;
00137 }
00138
00139 int main(int argc, char** argv)
00140 {
00141 cout << "Creating Rasterizer (coarse)..." << endl;
00142 Rasterizer* rasterizerCoarse = new AdaptiveRasterizer(0.0001);
00143 cout << "Creating Rasterizer (fine)..." << endl;
00144 Rasterizer* rasterizerFine = new AdaptiveRasterizer(0.00000001);
00145 cout << "Creating MicroEdgeDetector..." << endl;
00146 MicroEdgeDetector* microEdgeDetector = new MicroEdgeDetector(rasterizerFine, 5);
00147 cout << "Loading MicroEdgeCorrectionTable..." << endl;
00148 ifstream microEdgeCorrectionTableFile("MicroEdgeCorrectionTable.bin", ifstream::in | ifstream::binary);
00149 MicroEdgeCorrectionTable* microEdgeCorrectionTable = MicroEdgeCorrectionTable::Deserialize(µEdgeCorrectionTableFile);
00150 microEdgeCorrectionTableFile.close();
00151 cout << "Creating NullPointCorrector..." << endl;
00152 PointCorrector* nullPointCorrector = new NullPointCorrector();
00153 cout << "Creating MacroEdgeDetector..." << endl;
00154 MacroEdgeDetector* macroEdgeDetector = new MacroEdgeDetector(microEdgeDetector, microEdgeCorrectionTable, nullPointCorrector);
00155 cout << endl;
00156
00157 cout << "Generating statistics..." << endl;
00158
00159 srand(time(NULL));
00160
00161 for (double noiseLevel = 0; noiseLevel <= 1; noiseLevel += 0.1) GenerateStatistics(rasterizerCoarse, macroEdgeDetector, noiseLevel, 100);
00162
00163 delete rasterizerCoarse;
00164 delete rasterizerFine;
00165 delete microEdgeDetector;
00166 delete microEdgeCorrectionTable;
00167 delete nullPointCorrector;
00168 delete macroEdgeDetector;
00169
00170 return 0;
00171 }