- // 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
- match EEOver.EEOverlapArea e.Ellipse other.Ellipse with
- | Some (commonArea, _, _) ->
- 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)