00001 using System;
00002 using System.Collections.Generic;
00003 using System.Linq;
00004 using System.Text;
00005
00006 namespace EdgeClustering
00007 {
00008
00009
00010
00011
00012
00013
00014 static class KernelDensityEstimator
00015 {
00016 private static int histogramSize = 360;
00017 public static int HistogramSize
00018 {
00019 get { return KernelDensityEstimator.histogramSize; }
00020 set { KernelDensityEstimator.histogramSize = value; }
00021 }
00022
00023 private static double[] kernel;
00024
00025
00026
00027
00028
00029
00030 static public void GenerateKernel(double radius)
00031 {
00032 double h = 180.0 / (double)histogramSize;
00033
00034 int width = (int)Math.Floor(radius/h) * 2 + 1;
00035 double sigma = (double)radius / 3.0;
00036 double norm = 1.0 / (Math.Sqrt(2.0 * Math.PI) * sigma);
00037 double coeff = 2.0 * sigma * sigma;
00038
00039 kernel = new double[width];
00040
00041 double total = 0;
00042 double x = 0;
00043
00044 for (int i = 0; i < width; i++)
00045 {
00046 x = -radius + i*2*radius/(width-1);
00047
00048 kernel[i] = norm * Math.Exp(-x * x / coeff);
00049 total += kernel[i];
00050 }
00051
00052 for (int i = 0; i < width; i++)
00053 kernel[i] /= total;
00054 }
00055
00056
00057
00058
00059 public static double CalculateMaximum(double[] angles, double threshold)
00060 {
00061
00062 double[] hist = new double[histogramSize];
00063
00064 foreach (double a in angles)
00065 {
00066
00067
00068
00069 int k = (int)Math.Floor(a * histogramSize/180.0);
00070 hist[k]++;
00071 }
00072
00073 double[] axis = new double[hist.Length];
00074
00075 int radius = (int)Math.Floor(kernel.Length/2.0);
00076 double peakValue = 0;
00077 int peak = 0;
00078
00079
00080 for (int j=0; j<hist.Length; j++)
00081 {
00082 if(hist[j] > 0)
00083 for (int i = -radius; i <= radius; i++ )
00084 {
00085 int k = j + i;
00086
00087 if (k < 0)
00088 k = axis.Length + k;
00089 if (k >= axis.Length)
00090 k = k - axis.Length;
00091
00092 axis[k] += kernel[i + radius] * hist[j];
00093
00094
00095 if (axis[k] > peakValue)
00096 {
00097 peakValue = axis[k];
00098 peak = k;
00099 }
00100 }
00101 }
00102
00103
00104 peakValue /= angles.Length;
00105
00106
00107 return (peakValue > threshold) ? (peak + 0.5) * 180.0 / histogramSize : -1;
00108 }
00109 }
00110 }