Increase a bit the number of built ellipses.
[master-thesis.git] / Parasitemia / ParasitemiaCore / MatchingEllipses.fs
index b9b4b83..f028e90 100644 (file)
@@ -1,6 +1,7 @@
 module ParasitemiaCore.MatchingEllipses
 
 open System
+open System.Drawing
 open System.Linq
 open System.Collections
 open System.Collections.Generic
@@ -8,6 +9,12 @@ open System.Collections.Generic
 open Types
 open Utils
 
+// All ellipses with a score below this are removed.
+let matchingScoreThresholdPerRadiusUnit = 0.025f // For a radius of 1.
+let matchingScorePower = 20.f
+let windowSizeRadiusFactor = 1.f / 2.f
+let minimumDistanceFromCenterRadiusFactor = 1.f / 4.f
+
 type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) =
     let mutable matchingScore = matchingScore
 
@@ -28,9 +35,6 @@ type private EllipseScoreFlaggedKd (matchingScore: float32, e: Ellipse) =
 type MatchingEllipses (radius: float32) =
     let ellipses = List<EllipseScoreFlaggedKd>()
 
-    // All ellipses with a score below this are removed.
-    let matchingScoreThreshold = 0.8f
-
     member this.Add (e: Ellipse) =
         ellipses.Add(EllipseScoreFlaggedKd(0.f, e))
 
@@ -46,7 +50,7 @@ type MatchingEllipses (radius: float32) =
             let tree = KdTree.Tree.BuildTree (List.ofSeq ellipses)
 
             // 2) Compute the matching score of each ellipses.
-            let windowSize = radius / 2.f
+            let windowSize = radius * windowSizeRadiusFactor
             for e in ellipses do
                 e.Processed <- true
                 let areaE = e.Ellipse.Area
@@ -59,15 +63,16 @@ type MatchingEllipses (radius: float32) =
                     then
                         let areaOther = other.Ellipse.Area
                         match EEOver.EEOverlapArea e.Ellipse other.Ellipse with
-                        | Some (overlapArea, _, _) ->
-                            let matchingScore = (2.f * overlapArea / (areaE + areaOther)) ** 30.f
-                            if matchingScore <= 1.f // For approximation error.
-                            then
+                        | Some (overlapArea, _, _)
+                            // Because of approximation error, see https://github.com/chraibi/EEOver/issues/4
+                            when overlapArea - areaE < 1.f && overlapArea - areaOther < 1.f ->
+                                let matchingScore = (2.f * overlapArea / (areaE + areaOther)) ** matchingScorePower
                                 other.AddMatchingScore(matchingScore)
                                 e.AddMatchingScore(matchingScore)
                         | _ -> ()
 
             // 3) Remove ellipses whose center is near the center of another ellipse with a better score.
+            let matchingScoreThreshold = matchingScoreThresholdPerRadiusUnit * radius
             for e in ellipses do
                 if e.MatchingScore < matchingScoreThreshold
                 then
@@ -81,7 +86,7 @@ type MatchingEllipses (radius: float32) =
                         if not other.Removed && e.MatchingScore > other.MatchingScore
                         then
                             // Case where ellipses are too close.
-                            if distanceTwoPoints (PointD(e.Ellipse.Cx, e.Ellipse.Cy)) (PointD(other.Ellipse.Cx, other.Ellipse.Cy)) < 0.3f * e.Ellipse.B
+                            if distanceTwoPoints (PointF(e.Ellipse.Cx, e.Ellipse.Cy)) (PointF(other.Ellipse.Cx, other.Ellipse.Cy)) < minimumDistanceFromCenterRadiusFactor * e.Ellipse.B
                             then
                                 other.Removed <- true
                             else
@@ -91,7 +96,6 @@ type MatchingEllipses (radius: float32) =
                                     other.Removed <- true
                                 | _ ->
                                     ()
-
             ellipses
             |> List.ofSeq
             |> List.filter (fun e -> not e.Removed)