private double EuclideanDistanceAtBestAngle(List <Point> points, DollarTemplate T, double thetaA, double thetaB, double thetaDelta, out double theta) { double f1 = EuclideanDistanceAtAngle(points, T, thetaA); double f2 = EuclideanDistanceAtAngle(points, T, thetaB); while (Math.Abs(thetaB - thetaA) > thetaDelta) { if (f1 < f2) { thetaB = (1 - PHI) * thetaA + PHI * thetaB; f2 = EuclideanDistanceAtAngle(points, T, thetaB); } else { thetaA = PHI * thetaA + (1 - PHI) * thetaB; f1 = EuclideanDistanceAtAngle(points, T, thetaA); } } if (f1 < f2) { theta = thetaB; return(f1); } else { theta = thetaA; return(f2); } }
/// <summary> /// Match this symbol to the best Template in templates. /// </summary> /// <param name="templates">Existing templates with which to match</param> /// <param name="score">Score of best matching template</param> public DollarTemplate RecognizeSymbol(List <DollarTemplate> templates, out double score) { score = 0.0; if (templates.Count == 0) { return(null); } DollarTemplate Tbest = templates[0]; double bestD = double.MaxValue; double bestTheta = 0.0; double d = 0.0; for (int i = 0; i < templates.Count; i++) { double theta; d = EuclideanDistanceAtBestAngle(m_Points, templates[i], -THETA_MAX, THETA_MAX, THETA_DELTA, out theta); if (d < bestD) { bestD = d; bestTheta = theta; Tbest = templates[i]; } } score = 1 - bestD / (0.5 * Math.Sqrt(Math.Pow(SIZE, 2.0) * 2)); return(Tbest); }
public string Recognize(List <DollarTemplate> templates) { if (m_Points.Count != NumResampledPoints) { return("Unknown"); } double score = 0.0; DollarTemplate best = RecognizeSymbol(templates, out score); if (score < SCORE_THRESHOLD) { return("Unknown"); } return(best.Name); }
/// <summary> /// Gets the result for the best matching template /// </summary> /// <param name="stroke">Stroke to be recognized</param> /// <returns>Class name of the best match</returns> public string Recognize(Substroke stroke) { DollarTemplate unknown = new DollarTemplate(stroke.PointsL); return(unknown.Recognize(_templates)); }
/// <summary> /// Computes the total Euclidean Distance between two templates at a specified angle /// </summary> /// <param name="avgPoints"></param> /// <param name="T"></param> /// <param name="theta"></param> /// <returns></returns> private double EuclideanDistanceAtAngle(List <Point> points, DollarTemplate T, double theta) { List <Point> newPoints = rotateBy(points, theta); return(EuclideanDistance(newPoints, T.m_Points) / (double)points.Count); }