/// <summary> /// Distance transform of 1D function /// </summary> /// <param name="source"></param> /// <param name="target"></param> private static void TransformSlice(IImageSlice <double> source, IImageSlice <double> target) { int n = source.Count; int[] v = new int[n]; double[] z = new double[n + 1]; int k = 0; v[0] = 0; // TODO: Is this correct or should we just use a large number? z[0] = -infinity; z[1] = infinity; for (int q = 1; q < n; ++q) { double s = S(source, q, v[k]); while (s <= z[k]) { --k; s = S(source, q, v[k]); } ++k; v[k] = q; z[k] = s; z[k + 1] = infinity; } k = 0; for (int q = 0; q < n; ++q) { while (z[k + 1] < q) { ++k; } target[q] = Square(q - v[k]) + source[v[k]]; } }
private static double S(IImageSlice <double> slice, int q, int vk) { return(((slice[q] + Square(q)) - (slice[vk] + Square(vk))) / (2 * q - 2 * vk)); }