- for other in ellipses do
- let areaOther = ellipseArea other.e
- let commonArea = EEOver.EEOverlapArea e other.e
- let matchingScore = (2.0 * commonArea / (areaE + areaOther)) ** 2.0
- if matchingScore >= matchingScoreThreshold1
+ member this.Ellipses : Ellipse list =
+ // 1) Create a kd-tree from the ellipses list.
+ let tree = KdTree.Tree.buildTree (List.ofSeq ellipses)
+
+ // 2) Compute the matching score of each ellipses.
+ let windowSize = radiusMin
+ for e in ellipses do
+ e.Processed <- true
+ let areaE = e.Ellipse.Area
+ let window = { KdTree.minX = e.Ellipse.Cx - windowSize / 2.0
+ KdTree.maxX = e.Ellipse.Cx + windowSize / 2.0
+ KdTree.minY = e.Ellipse.Cy - windowSize / 2.0
+ KdTree.maxY = e.Ellipse.Cy + windowSize / 2.0 }
+ for other in KdTree.Tree.search tree window do
+ if not other.Processed
+ then
+ let areaOther = other.Ellipse.Area
+ let commonArea = EEOver.EEOverlapArea e.Ellipse other.Ellipse
+ let matchingScore = 2.0 * commonArea / (areaE + areaOther)
+ if matchingScore >= matchingScoreThreshold1
+ then
+ other.AddMatchingScore(matchingScore)
+ e.AddMatchingScore(matchingScore)
+
+ // 3) Sort ellipses by their score.
+ ellipses.Sort(fun e1 e2 -> e2.MatchingScore.CompareTo(e1.MatchingScore))
+
+ // 4) Remove ellipses wich have a low score.
+ let i = ellipses.BinarySearch(EllipseScore(matchingScoreThreshold2, Ellipse(0.0, 0.0, 0.0, 0.0, 0.0)),
+ { new IComparer<EllipseScore> with
+ member this.Compare(e1, e2) = e2.MatchingScore.CompareTo(e1.MatchingScore) }) |> abs
+ let nbToRemove = ellipses.Count - i
+ if nbToRemove > 0
+ then
+ for j in i .. nbToRemove - 1 do
+ ellipses.[j].Removed <- true
+ ellipses.RemoveRange(i, nbToRemove)
+
+ // 5) Remove ellipses whose center is into an ellipse with a better score
+ for e in ellipses do
+ if not e.Removed