- dprintfn "Number of ellipse: %A" ellipses.Count
-
- (*let sortedEllipses =
- List.filter (fun e -> e.matchingScore >= matchingScoreThreshold2) (List.ofSeq ellipses)
- |> List.sortWith (fun e1 e2 -> e2.matchingScore.CompareTo(e1.matchingScore))*)
-
- List.filter (fun e -> e.matchingScore >= matchingScoreThreshold2) (List.ofSeq ellipses)
- |> List.sortWith (fun e1 e2 -> e2.matchingScore.CompareTo(e1.matchingScore))
- |> List.map (fun { e = e } -> e)
-
- // ellipses.Where(fun e -> e.matchingScore >= matchingScoreThreshold2)
- // ([], fun acc { matchingScore = score; e = e } -> if score >= matchingScoreThreshold2 then e :: acc else acc)
-
-
-
+ List.ofSeq ellipses |> List.map (fun e -> e.Ellipse)
+
+ member this.PrunedEllipses : Ellipse list =
+ if ellipses.Count = 0
+ then
+ []
+ else
+ // 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 = radius / 2.f
+ for e in ellipses do
+ e.Processed <- true
+ let areaE = e.Ellipse.Area
+ let window = { KdTree.minX = e.Ellipse.Cx - windowSize / 2.f
+ KdTree.maxX = e.Ellipse.Cx + windowSize / 2.f
+ KdTree.minY = e.Ellipse.Cy - windowSize / 2.f
+ KdTree.maxY = e.Ellipse.Cy + windowSize / 2.f }
+ for other in tree.Search window do
+ if not other.Processed
+ then
+ let areaOther = other.Ellipse.Area
+ match EEOver.EEOverlapArea e.Ellipse other.Ellipse with
+ | Some (overlapArea, _, _) ->
+ let matchingScore = (2.f * overlapArea / (areaE + areaOther)) ** 20.f
+ if matchingScore <= 1.f // For approximation error.
+ then
+ other.AddMatchingScore(matchingScore)
+ e.AddMatchingScore(matchingScore)
+ | _ -> ()
+
+ // 3) Remove ellipses whose center is near the center of another ellipse with a better score.
+ for e in ellipses do
+ if e.MatchingScore < matchingScoreThreshold
+ then
+ e.Removed <- true
+ else
+ let window = { KdTree.minX = e.Ellipse.Cx - e.Ellipse.A
+ KdTree.maxX = e.Ellipse.Cx + e.Ellipse.A
+ KdTree.minY = e.Ellipse.Cy - e.Ellipse.A
+ KdTree.maxY = e.Ellipse.Cy + e.Ellipse.A }
+ for other in tree.Search window do
+ if not other.Removed && e.MatchingScore > other.MatchingScore &&
+ distanceTwoPoints (PointD(e.Ellipse.Cx, e.Ellipse.Cy)) (PointD(other.Ellipse.Cx, other.Ellipse.Cy)) < 0.3f * e.Ellipse.B
+ then
+ other.Removed <- true
+
+ ellipses
+ |> List.ofSeq
+ |> List.filter (fun e -> not e.Removed)
+ |> List.sortWith (fun e1 e2 -> e2.MatchingScore.CompareTo(e1.MatchingScore))
+ |> List.map (fun e -> e.Ellipse)