Add a way to detect the membrane of a parasite in the ring stage.
[master-thesis.git] / Parasitemia / ParasitemiaCore / Classifier.fs
index 9f4fdd0..a3bfa9c 100644 (file)
@@ -59,9 +59,9 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img:
                     then
                         let p' = Utils.pointFromTwoLines d1 d2
                         let delta, delta' =
-                            let d = c.X - p.X
-                            // To avoid rounding.
-                            if abs d < 0.001f then c.Y - p.Y, c.Y - p'.Y else d, c.X - p'.X
+                            let dx1, dx2 = (c.X - p.X), (c.X - p'.X)
+                            // To avoid rounding issue.
+                            if abs dx1 < 0.01f || abs dx2 < 0.01f then c.Y - p.Y, c.Y - p'.Y else dx1, dx2
 
                         // Yield 'false' when the point is owned by another ellipse.
                         if case1
@@ -148,6 +148,12 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img:
                     e.Removed <- true
 
         // 5) Define pixels associated to each ellipse and create the cells.
+        let radiusParasiteRatio = 0.4f
+        let radiusParasite = config.RBCRadius.Pixel * 0.5f
+        let perimeterParasiteSquared = (2.f * radiusParasite) ** 2.f |> roundInt
+        let parasiteOccupation = 0.08f // 8 %
+        let minimumParasiteArea = Const.PI * radiusParasite ** 2.f * parasiteOccupation |> roundInt
+        //let minimumStainArea = roundInt <| config.RBCRadius.Area * 0.02f // 1.5 %
         ellipsesWithNeigbors
         |> List.choose (fun (e, neighbors) ->
             if e.Removed
@@ -157,7 +163,9 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img:
                 let minX, minY, maxX, maxY = ellipseWindow e
 
                 let infectedPixels = List<Point>()
-                let mutable stainPixels = 0
+                let stainPixels = List<Point>()
+
+                //let mutable stainPixels = 0
                 let mutable darkStainPixels = 0
                 let mutable nbElement = 0
 
@@ -170,34 +178,49 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img:
                             elements.[y-minY, x-minX] <- 1uy
                             nbElement <- nbElement + 1
 
-                            if infection.Data.[y, x, 0] > 0uy
+                            let infected = infection.Data.[y, x, 0] > 0uy
+                            let stain = parasites.stain.Data.[y, x, 0] > 0uy
+                            let darkStain = parasites.darkStain.Data.[y, x, 0] > 0uy
+
+                            if infected
                             then
                                 infectedPixels.Add(Point(x, y))
 
-                            if parasites.stain.Data.[y, x, 0] > 0uy
+                            if stain
                             then
-                                stainPixels <- stainPixels + 1
+                                stainPixels.Add(Point(x, y))
 
-                            if parasites.darkStain.Data.[y, x, 0] > 0uy
+                            if darkStain
                             then
                                 darkStainPixels <- darkStainPixels + 1
 
+                let mutable stainArea = 0
+                if infectedPixels.Count > 0
+                then
+                    for stainPixel in stainPixels do
+                        if infectedPixels.Exists(fun p -> pown (p.X - stainPixel.X) 2 + pown (p.Y - stainPixel.Y) 2 <= perimeterParasiteSquared)
+                        then
+                            stainArea <- stainArea + 1
+
+
                 let cellClass =
-                    if float darkStainPixels > config.Parameters.maxDarkStainRatio * (float nbElement) ||
-                       float stainPixels > config.Parameters.maxStainRatio * (float nbElement)
+                    if float darkStainPixels > config.Parameters.maxDarkStainRatio * (float nbElement)
+                       //|| float stainPixels > config.Parameters.maxStainRatio * (float nbElement)
                     then
                         Peculiar
-                    elif infectedPixels.Count >= 1
+
+                    elif infectedPixels.Count > 0 && stainArea >= minimumParasiteArea
                     then
                         let infectionToRemove = ImgTools.connectedComponents parasites.stain infectedPixels
                         for p in infectionToRemove do
                             infection.Data.[p.Y, p.X, 0] <- 0uy
                         InfectedRBC
+
                     else
                         HealthyRBC
 
                 Some { cellClass = cellClass
                        center = Point(roundInt e.Cx, roundInt e.Cy)
-                       infectedArea = infectedPixels.Count
-                       stainArea = stainPixels
+                       infectedArea = if cellClass = InfectedRBC then infectedPixels.Count else 0
+                       stainArea = stainArea
                        elements = elements })