Simplification of the parasite marker.
authorGreg Burri <greg.burri@gmail.com>
Fri, 1 Jan 2016 09:39:27 +0000 (10:39 +0100)
committerGreg Burri <greg.burri@gmail.com>
Fri, 1 Jan 2016 09:39:27 +0000 (10:39 +0100)
Parasitemia/Parasitemia/Classifier.fs
Parasitemia/Parasitemia/Config.fs
Parasitemia/Parasitemia/MainAnalysis.fs
Parasitemia/Parasitemia/Parasitemia.fsproj
Parasitemia/Parasitemia/ParasitesMarker.fs
Parasitemia/Parasitemia/ParasitesMarker2.fs [deleted file]
Parasitemia/Parasitemia/Program.fs

index 3113d6f..99b6edc 100644 (file)
@@ -21,7 +21,7 @@ type private EllipseFlaggedKd (e: Ellipse) =
         member this.Y = this.Cy
 
 
         member this.Y = this.Cy
 
 
-let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker2.Result) (img: Image<Gray, byte>) (config: Config.Config) : Cell list =
+let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker.Result) (img: Image<Gray, byte>) (config: Config.Config) : Cell list =
     if ellipses.IsEmpty
     then
         []
     if ellipses.IsEmpty
     then
         []
@@ -162,7 +162,7 @@ let findCells (ellipses: Ellipse list) (parasites: ParasitesMarker2.Result) (img
                         sqrt (((float sumCoords_x) / (float nbElement) - e.Cx) ** 2.0 + ((float sumCoords_y) / (float nbElement) - e.Cy) ** 2.0) > e.A * config.maxOffcenter *)
                     then
                         Peculiar
                         sqrt (((float sumCoords_x) / (float nbElement) - e.Cx) ** 2.0 + ((float sumCoords_y) / (float nbElement) - e.Cy) ** 2.0) > e.A * config.maxOffcenter *)
                     then
                         Peculiar
-                    elif infectedPixels.Count > config.Parameters.parasitePixelsRequired
+                    elif infectedPixels.Count >= 1
                     then
                         let infectionToRemove = ImgTools.connectedComponents parasites.stain infectedPixels
                         for p in infectionToRemove do
                     then
                         let infectionToRemove = ImgTools.connectedComponents parasites.stain infectedPixels
                         for p in infectionToRemove do
index 5cf392c..45b1ca3 100644 (file)
@@ -23,12 +23,11 @@ type Parameters = {
     maxDarkStainRatio: float
 
     stainArea: float // Factor of a RBC area. 0.5 means the half of RBC area.
     maxDarkStainRatio: float
 
     stainArea: float // Factor of a RBC area. 0.5 means the half of RBC area.
-    stainLevel: float // [0, 2]
+    stainLevel: float // > 1
     maxStainRatio: float // [0, 1]
 
     infectionArea: float // Factor of a RBC area. 0.5 means the half of RBC area.
     maxStainRatio: float // [0, 1]
 
     infectionArea: float // Factor of a RBC area. 0.5 means the half of RBC area.
-    infectionLevel: float // [0, 2]
-    parasitePixelsRequired: int
+    infectionLevel: float // > 1
 
     standardDeviationMaxRatio: float // The standard deviation of the pixel values of a cell can't be greater than standardDeviationMaxRatio * global standard deviation
     minimumCellArea: float // Factor of RBC area.
 
     standardDeviationMaxRatio: float // The standard deviation of the pixel values of a cell can't be greater than standardDeviationMaxRatio * global standard deviation
     minimumCellArea: float // Factor of RBC area.
index fd341ac..c987e63 100644 (file)
@@ -42,7 +42,8 @@ let doAnalysis (img: Image<Bgr, byte>) (name: string) (config: Config) : Cell li
 
     let filteredGreenFloat = filteredGreen.Convert<Gray, float32>() // Is it neccessary?
 
 
     let filteredGreenFloat = filteredGreen.Convert<Gray, float32>() // Is it neccessary?
 
-    let parasites, filteredGreenWhitoutInfection, filteredGreenWhitoutStain = ParasitesMarker2.find filteredGreen filteredGreenFloat config
+    let parasites, filteredGreenWhitoutInfection, filteredGreenWhitoutStain = ParasitesMarker.find filteredGreen filteredGreenFloat config
+    //let parasites, filteredGreenWhitoutInfection, filteredGreenWhitoutStain = ParasitesMarker.findMa greenFloat filteredGreenFloat config
     let filteredGreenWhitoutInfectionFloat = filteredGreenWhitoutInfection.Convert<Gray, float32>()
     let filteredGreenWhitoutStainFloat = filteredGreenWhitoutStain.Convert<Gray, float32>()
 
     let filteredGreenWhitoutInfectionFloat = filteredGreenWhitoutInfection.Convert<Gray, float32>()
     let filteredGreenWhitoutStainFloat = filteredGreenWhitoutStain.Convert<Gray, float32>()
 
index fe81290..3282961 100644 (file)
@@ -72,7 +72,6 @@
     <Compile Include="Config.fs" />
     <Compile Include="KMedians.fs" />
     <Compile Include="EEOver.fs" />
     <Compile Include="Config.fs" />
     <Compile Include="KMedians.fs" />
     <Compile Include="EEOver.fs" />
-    <Compile Include="ParasitesMarker2.fs" />
     <Compile Include="ParasitesMarker.fs" />
     <Compile Include="KdTree.fs" />
     <Compile Include="MatchingEllipses.fs" />
     <Compile Include="ParasitesMarker.fs" />
     <Compile Include="KdTree.fs" />
     <Compile Include="MatchingEllipses.fs" />
index d1a51fa..20dbf4c 100644 (file)
@@ -1,23 +1,27 @@
 module ParasitesMarker
 
 open System.Drawing
 module ParasitesMarker
 
 open System.Drawing
+open System.Linq
 
 open Emgu.CV
 open Emgu.CV.Structure
 
 open Emgu.CV
 open Emgu.CV.Structure
+open Utils
 
 type Result = {
     darkStain: Image<Gray, byte>
 
 type Result = {
     darkStain: Image<Gray, byte>
-    stain: Image<Gray, byte>
-    infection: Image<Gray, byte> }
+    infection: Image<Gray, byte>
+    stain: Image<Gray, byte> }
+
 
 // Create three binary markers :
 // * 'Dark stain' corresponds to the colored pixel, it's independent of the size of the areas.
 // * 'Stain' corresponds to the stain around the parasites.
 // * 'Infection' corresponds to the parasite. It shouldn't contain thrombocytes.
 
 // Create three binary markers :
 // * 'Dark stain' corresponds to the colored pixel, it's independent of the size of the areas.
 // * 'Stain' corresponds to the stain around the parasites.
 // * 'Infection' corresponds to the parasite. It shouldn't contain thrombocytes.
-(*let find (green: Image<Gray, float32>) (filteredGreen: Image<Gray, float32>) (kmediansResult: KMedians.Result) (config: Config.Config) : Result =
+let findMa (green: Image<Gray, float32>) (filteredGreen: Image<Gray, float32>) (config: Config.Config) : Result * Image<Gray, byte> * Image<Gray, byte> =
 
     // We use the filtered image to find the dark stain.
 
     // We use the filtered image to find the dark stain.
-    let { KMedians.fg = fg; KMedians.median_bg = median_bg; KMedians.median_fg = median_fg; KMedians.d_fg = d_fg } = kmediansResult
+    let kmediansResults = logTime "Finding fg/bg (k-medians)" (fun () -> KMedians.kmedians filteredGreen 1.0)
+    let { KMedians.fg = fg; KMedians.median_bg = median_bg; KMedians.median_fg = median_fg; KMedians.d_fg = d_fg } = kmediansResults
     let darkStain = d_fg.Cmp(median_bg * config.Parameters.darkStainLevel, CvEnum.CmpType.GreaterThan)
     darkStain._And(filteredGreen.Cmp(median_fg, CvEnum.CmpType.LessThan))
     darkStain._And(fg)
     let darkStain = d_fg.Cmp(median_bg * config.Parameters.darkStainLevel, CvEnum.CmpType.GreaterThan)
     darkStain._And(filteredGreen.Cmp(median_fg, CvEnum.CmpType.LessThan))
     darkStain._And(fg)
@@ -33,9 +37,50 @@ type Result = {
         smears._And(fg)
         smears
 
         smears._And(fg)
         smears
 
+    let tmp = filteredGreen.Convert<Gray, byte>()
+
     { darkStain = darkStain;
     { darkStain = darkStain;
-      stain = findSmears config.Parameters.stainSigma config.Parameters.stainLevel
-      infection = findSmears config.Parameters.infectionSigma config.Parameters.infectionLevel }*)
+      stain = findSmears 10. 0.9
+      infection = findSmears 2.2 0.87 },
+    tmp,
+    tmp
+
+
+// Create three binary markers :
+// * 'Dark stain' corresponds to the colored pixel, it's independent of the size of the areas.
+// * 'Stain' corresponds to the stain around the parasites.
+// * 'Infection' corresponds to the parasite. It shouldn't contain thrombocytes.
+let find (filteredGreen: Image<Gray, byte>) (filteredGreenFloat: Image<Gray, float32>) (config: Config.Config) : Result * Image<Gray, byte> * Image<Gray, byte> =
+
+    let filteredGreenWithoutInfection = filteredGreen.Copy()
+    ImgTools.areaClose filteredGreenWithoutInfection (int config.InfectionArea)
+
+    let filteredGreenWithoutStain = filteredGreenWithoutInfection.Copy()
+    ImgTools.areaClose filteredGreenWithoutStain (int config.StainArea)
+
+    // We use the filtered image to find the dark stain.
+    let kmediansResults = logTime "Finding fg/bg (k-medians)" (fun () -> KMedians.kmedians (filteredGreenWithoutInfection.Convert<Gray, float32>()) 1.0) // FIXME: avoid converting again this in MainAnalysis
+    let { KMedians.fg = fg; KMedians.median_bg = median_bg; KMedians.median_fg = median_fg; KMedians.d_fg = d_fg } = kmediansResults
+    let darkStain = d_fg.Cmp(median_bg * config.Parameters.darkStainLevel, CvEnum.CmpType.GreaterThan)
+    darkStain._And(filteredGreenWithoutInfection.Cmp(median_fg, CvEnum.CmpType.LessThan))
+
+    let marker (img: Image<Gray, byte>) (closed: Image<Gray, byte>) (level: float) : Image<Gray, byte> =
+        let diff = closed - (img * level)
+        diff._ThresholdBinary(Gray(0.0), Gray(255.))
+        diff
+
+    let infectionMarker = marker filteredGreen filteredGreenWithoutInfection config.Parameters.infectionLevel
+    let stainMarker = marker filteredGreenWithoutInfection filteredGreenWithoutStain config.Parameters.stainLevel
+
+    { darkStain = darkStain
+      infection = infectionMarker
+      stain = stainMarker },
+    filteredGreenWithoutInfection,
+    filteredGreenWithoutStain
+
+
+
+
 
 
 
 
 
 
diff --git a/Parasitemia/Parasitemia/ParasitesMarker2.fs b/Parasitemia/Parasitemia/ParasitesMarker2.fs
deleted file mode 100644 (file)
index 42645b4..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-module ParasitesMarker2
-
-open System.Drawing
-open System.Linq
-
-open Emgu.CV
-open Emgu.CV.Structure
-
-open Utils
-
-type Result = {
-    darkStain: Image<Gray, byte>
-    infection: Image<Gray, byte>
-    stain: Image<Gray, byte> }
-
-// Create three binary markers :
-// * 'Dark stain' corresponds to the colored pixel, it's independent of the size of the areas.
-// * 'Stain' corresponds to the stain around the parasites.
-// * 'Infection' corresponds to the parasite. It shouldn't contain thrombocytes.
-let find (filteredGreen: Image<Gray, byte>) (filteredGreenFloat: Image<Gray, float32>) (config: Config.Config) : Result * Image<Gray, byte> * Image<Gray, byte> =
-
-    let filteredGreenWithoutInfection = filteredGreen.Copy()
-    ImgTools.areaClose filteredGreenWithoutInfection (int config.InfectionArea)
-
-    let filteredGreenWithoutStain = filteredGreenWithoutInfection.Copy()
-    ImgTools.areaClose filteredGreenWithoutStain (int config.StainArea)
-
-    // We use the filtered image to find the dark stain.
-    let kmediansResults = logTime "Finding fg/bg (k-medians)" (fun () -> KMedians.kmedians (filteredGreenWithoutInfection.Convert<Gray, float32>()) 1.0) // FIXME: avoid converting again this in MainAnalysis
-    let { KMedians.fg = fg; KMedians.median_bg = median_bg; KMedians.median_fg = median_fg; KMedians.d_fg = d_fg } = kmediansResults
-    let darkStain = d_fg.Cmp(median_bg * config.Parameters.darkStainLevel, CvEnum.CmpType.GreaterThan)
-    darkStain._And(filteredGreenWithoutInfection.Cmp(median_fg, CvEnum.CmpType.LessThan))
-
-    let marker (img: Image<Gray, byte>) (closed: Image<Gray, byte>) (level: float) : Image<Gray, byte> =
-        let diff = closed - img
-
-        let min = ref [| 0. |]
-        let minLocation = ref <| [| Point() |]
-        let max = ref [| 0. |]
-        let maxLocation = ref <| [| Point() |]
-        diff.MinMax(min, max, minLocation, maxLocation)
-        let max = (!max).[0]
-
-        let threshold = 0.2 * max
-        let diff' = diff - threshold
-
-        let m = MathNet.Numerics.Statistics.StreamingStatistics.Mean(seq {
-                for m in ImgTools.findMaxima diff' do
-                    let p = m.First()
-                    yield diff'.Data.[p.Y, p.X, 0] |> float }) + threshold
-
-        let valueThreshold = m * level
-
-        diff._ThresholdBinary(Gray(valueThreshold), Gray(255.))
-        diff
-
-    let infectionMarker = marker filteredGreen filteredGreenWithoutInfection config.Parameters.infectionLevel
-    let stainMarker = marker filteredGreenWithoutInfection filteredGreenWithoutStain config.Parameters.stainLevel
-
-    { darkStain = darkStain
-      infection = infectionMarker
-      stain = stainMarker },
-    filteredGreenWithoutInfection,
-    filteredGreenWithoutStain
-
-
-
-
-
index 25c707d..528f2de 100644 (file)
@@ -73,11 +73,10 @@ let main args =
                 maxDarkStainRatio = 0.1
 
                 infectionArea = 0.012 // 1.2 %
                 maxDarkStainRatio = 0.1
 
                 infectionArea = 0.012 // 1.2 %
-                infectionLevel = 0.85
-                parasitePixelsRequired = 1
+                infectionLevel = 1.12 // Lower -> more sensitive.
 
 
-                stainArea = 0.08
-                stainLevel = 0.85
+                stainArea = 0.08 // 8 %
+                stainLevel = 1.1 // Lower -> more sensitive.
                 maxStainRatio = 0.12 // 12 %
 
                 standardDeviationMaxRatio = 0.55
                 maxStainRatio = 0.12 // 12 %
 
                 standardDeviationMaxRatio = 0.55