Fix an out-of-bound array access.
[master-thesis.git] / Parasitemia / Parasitemia / Classifier.fs
index 52e7dc6..8467d24 100644 (file)
@@ -59,28 +59,47 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (fg:
 
         let ellipsesWithNeigbors = ellipsesInside |> List.choose (fun e -> if e.Removed then None else Some (e, neighbors e))
 
-        // 3) Remove ellipse with a lower percentage of foreground.
+        // 3) Remove ellipses with a lower percentage of foreground.
         for e, neighbors in ellipsesWithNeigbors do
             let minX, minY, maxX, maxY = ellipseWindow e
 
             let mutable totalElement = 0
             let mutable fgElement = 0
-
-            for y in minY .. maxY do
-                for x in minX .. maxX do
+            for y in (if minY < 0 then 0 else minY) .. (if maxY >= fg.Height then fg.Height - 1 else maxY) do
+                for x in (if minX < 0 then 0 else minX) .. (if maxX >= fg.Width then fg.Width - 1 else maxX) do
                     let yf, xf = float y, float x
                     if e.Contains xf yf && neighbors |> List.forall (fun (otherE, _, _) -> not <| otherE.Contains xf yf)
-                    then
-                        totalElement <- totalElement + 1
-                        if fg.Data.[y, x, 0] > 0uy
                         then
-                            fgElement <- fgElement + 1
+                            totalElement <- totalElement + 1
+                            if fg.Data.[y, x, 0] > 0uy
+                            then
+                                fgElement <- fgElement + 1
 
-            if totalElement < config.minimumCellArea || (float fgElement) / (float totalElement) < config.percentageOfFgValidCell
+            if (float fgElement) / (float totalElement) < config.percentageOfFgValidCell
             then
                 e.Removed <- true
 
-        // 3) Define pixels associated to each ellipse and create the cells.
+        // 4) Remove ellipses with little area.
+        for e, neighbors in ellipsesWithNeigbors do
+            if not e.Removed
+            then
+                let minX, minY, maxX, maxY = ellipseWindow e
+
+                let mutable area = 0
+                for y in (if minY < 0 then 0 else minY) .. (if maxY >= fg.Height then fg.Height - 1 else maxY) do
+                    for x in (if minX < 0 then 0 else minX) .. (if maxX >= fg.Width then fg.Width - 1 else maxX) do
+                        let yf, xf = float y, float x
+                        if fg.Data.[y, x, 0] > 0uy &&
+                           e.Contains xf yf &&
+                           neighbors |> List.forall (fun (otherE, _, _) -> otherE.Removed || not <| otherE.Contains xf yf)
+                            then
+                                area <- area + 1
+
+                if area < config.minimumCellArea
+                then
+                    e.Removed <- true
+
+        // 5) Define pixels associated to each ellipse and create the cells.
 
         // Return 'true' if the point 'p' is owned by e.
         // The lines represents all intersections with other ellipses.