$search
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 //stringstream path; 00071 //path << "test-" << noiseLevel << ".bmp"; 00072 //SaveBitmap(noiseImage, path.str()); 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 if (error > 0.01) 00093 { 00094 cout << "RealEdge: " << "[" << "(" << realEdge.GetStart().GetX() << ", " << realEdge.GetStart().GetY() << ")" << ", " << "(" << realEdge.GetEnd().GetX() << ", " << realEdge.GetEnd().GetY() << ")" << "]" << endl; 00095 cout << "RealEdge: (" << normalizedRealEdge.GetFactorX() << ") * x + (" << normalizedRealEdge.GetFactorY() << ") * y + (" << normalizedRealEdge.GetOffset() << ") = 0" << endl; 00096 cout << "EstimatedEdge: " << "[" << "(" << estimatedEdge.GetStart().GetX() << ", " << estimatedEdge.GetStart().GetY() << ")" << ", " << "(" << estimatedEdge.GetEnd().GetX() << ", " << estimatedEdge.GetEnd().GetY() << ")" << "]" << endl; 00097 cout << "EstimatedEdge: (" << normalizedEstimatedEdge.GetFactorX() << ") * x + (" << normalizedEstimatedEdge.GetFactorY() << ") * y + (" << normalizedEstimatedEdge.GetOffset() << ") = 0" << endl; 00098 cout << "MeasuredEdge: (" << normalizedMeasuredEdge.GetFactorX() << ") * x + (" << normalizedMeasuredEdge.GetFactorY() << ") * y + (" << normalizedMeasuredEdge.GetOffset() << ") = 0" << endl; 00099 cout << "Error: " << error << endl; 00100 cout << endl; 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 }