X-Git-Url: http://git.euphorik.ch/?p=master-thesis.git;a=blobdiff_plain;f=Parasitemia%2FParasitemia%2FMatchingEllipses.fs;h=3599bb5471742bb2711378d4baab8bfe16d21523;hp=6e571995c0548da9486d8bd2b2e3201b03e65775;hb=81d1b86719a1ebaf649c1de4c1364603155a53e1;hpb=aaa250fab2ac3227bf45704355d389bc1a4ee7fc diff --git a/Parasitemia/Parasitemia/MatchingEllipses.fs b/Parasitemia/Parasitemia/MatchingEllipses.fs index 6e57199..3599bb5 100644 --- a/Parasitemia/Parasitemia/MatchingEllipses.fs +++ b/Parasitemia/Parasitemia/MatchingEllipses.fs @@ -8,14 +8,6 @@ open System.Collections.Generic open Types open Utils - -// Do not take in account matching score below this when two ellipses are matched. -[] -let matchingScoreThreshold1 = 0.6f - -[] -let scaleOverlapTest = 0.8f - type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) = let mutable matchingScore = matchingScore @@ -23,7 +15,7 @@ type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) = member this.MatchingScore = matchingScore - member this.AddMatchingScore(score: float32) = + member this.AddMatchingScore (score: float32) = matchingScore <- matchingScore + score member val Processed = false with get, set @@ -33,12 +25,11 @@ type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) = member this.X = this.Ellipse.Cx member this.Y = this.Ellipse.Cy - -type MatchingEllipses (radiusMin: float32) = +type MatchingEllipses (radius: float32) = let ellipses = List() // All ellipses with a score below this are removed. - let matchingScoreThreshold2 = 20.f * radiusMin + let matchingScoreThreshold = 1.f member this.Add (e: Ellipse) = ellipses.Add(EllipseScoreFlaggedKd(0.f, e)) @@ -46,7 +37,6 @@ type MatchingEllipses (radiusMin: float32) = member this.Ellipses : Ellipse list = List.ofSeq ellipses |> List.map (fun e -> e.Ellipse) - // Process all ellipses and return ellipses ordered from the best score to the worst. member this.PrunedEllipses : Ellipse list = if ellipses.Count = 0 then @@ -56,7 +46,7 @@ type MatchingEllipses (radiusMin: float32) = let tree = KdTree.Tree.BuildTree (List.ofSeq ellipses) // 2) Compute the matching score of each ellipses. - let windowSize = radiusMin + let windowSize = radius / 2.f for e in ellipses do e.Processed <- true let areaE = e.Ellipse.Area @@ -69,45 +59,33 @@ type MatchingEllipses (radiusMin: float32) = then let areaOther = other.Ellipse.Area match EEOver.EEOverlapArea e.Ellipse other.Ellipse with - | Some (commonArea, _, _) -> - let matchingScore = 2.f * commonArea / (areaE + areaOther) - if matchingScore >= matchingScoreThreshold1 + | Some (overlapArea, _, _) -> + let matchingScore = (2.f * overlapArea / (areaE + areaOther)) ** 20.f + if matchingScore <= 1.f // For approximation error. then - other.AddMatchingScore(matchingScore * e.Ellipse.Perimeter) - e.AddMatchingScore(matchingScore * other.Ellipse.Perimeter) + 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 with a low score. - let i = ellipses.BinarySearch(EllipseScoreFlaggedKd(matchingScoreThreshold2, Ellipse(0.f, 0.f, 0.f, 0.f, 0.f)), - { new IComparer 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 + // 3) Remove ellipses whose center is near the center of another ellipse with a better score. for e in ellipses do - if not e.Removed + 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 && other.MatchingScore < e.MatchingScore + 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 - if e.Ellipse.Scale(scaleOverlapTest).Contains other.Ellipse.Cx other.Ellipse.Cy - then - other.Removed <- true - ellipses.RemoveAll(fun e -> e.Removed) |> ignore - - List.ofSeq ellipses |> List.map (fun e -> e.Ellipse) - + 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)