Fix an out-of-bound array access.
[master-thesis.git] / Parasitemia / Parasitemia / Program.fs
index b44c65f..d7348cf 100644 (file)
@@ -1,5 +1,6 @@
 module Parasitemia.Main
 
+open System
 open System.IO
 open System.Windows
 open System.Windows.Media
@@ -15,58 +16,114 @@ open Emgu.CV.WPF
 
 open Config
 
-let display (window : Views.MainWindow) (img : IImage) = 
+let display (window : Views.MainWindow) (img : IImage) =
    let imgControl = window.Root.FindName("img") :?> Controls.Image
    imgControl.Source <- BitmapSourceConvert.ToBitmapSource(img)
 
 let log (window : Views.MainWindow) (mess : string) =
    let txtLog = window.Root.FindName("txtLog") :?> Controls.TextBlock
    txtLog.Text <- txtLog.Text + mess + "\n"
-   
-[<System.STAThreadAttribute>]
-do
-    Utils.dprintfn "OpenCV test"
-
-    let app = new Application()
-    let mainWindow = Views.MainWindow()
-
-    Utils.log <- (fun m -> log mainWindow m)
-
-    let config = {
-        scale = 1.0
-
-        doGSigma1 = 1.5
-        doGSigma2 = 20.0
-        doGLowFreqPercentageReduction = 0.9
-
-        darkStainLevel = 0.839     
-        
-        stainSigma = 10.0
-        stainLevel = 0.9
-        stainSpreadRequired = 3.0
-    
-        infectionSigma = 2.0
-        infectionLevel = 0.762
-        infectionPixelsRequired = 1 }
-   
-    ///// ELLIPSES /////
-    //use img = new Image<Bgr, byte>("../../../../src/Tests_hough/images/1508133543-7-4-120-0001.png")
-    //use img = new Image<Bgr, byte>("../../../../src/Tests_hough/images/rbc_single.png")
-    //use img = new Image<Bgr, byte>("../../../../src/Tests_hough/images/rbc_single_oblong_4.png")
-    //use img = new Image<Bgr, byte>("../../../../src/Tests_hough/images/strange_rbc_1.png")
-    //use img = new Image<Bgr, byte>("../../../../src/Tests_hough/images/rbc_single_blurred.png")   
-    use img = new Image<Bgr, byte>("../../../../src/Tests_hough/images/lot.png")
-
-
-    ///// PARASITES /////
-    //use img = new Image<Bgr, byte>("../../../../src/Parasites/images/1.png")
-    
-//    KdTree.test3 ()
-//    Utils.dprintfn "area: %A" area
-
-    let result = Utils.logTime "Total" (fun () ->
-        ImageAnalysis.doAnalysis img config )
-    
-    display mainWindow img
-    mainWindow.Root.Show()
-    app.Run() |> ignore
+
+
+type Input =
+    | File of string
+    | Dir of string
+
+type RunningMode =
+    | CmdLine of Input * string
+    | Window
+
+type Arguments = RunningMode * bool
+
+let parseArgs (args: string[]) : Arguments =
+
+    let output = Array.tryFindIndex ((=) "--output") args
+
+    let runningMode =
+        match Array.tryFindIndex ((=) "--folder") args, output with
+        | Some i, Some i_output when i < args.Length - 2 && i_output < args.Length - 2 ->
+            CmdLine ((Dir args.[i+1]), args.[i_output + 1])
+        | _ ->
+            match Array.tryFindIndex ((=) "--file") args, output with
+            | Some i, Some i_output when i < args.Length - 2 && i_output < args.Length - 2 ->
+                CmdLine ((File args.[i+1]), args.[i_output + 1])
+            |_ ->
+                Window
+
+    runningMode, Array.exists ((=) "--debug") args
+
+
+[<EntryPoint>]
+let main args =
+    match parseArgs args with
+    | mode, debug ->
+        let scale = 1.
+        let config = {
+            debug = if debug then DebugOn "." else DebugOff
+
+            scale = scale
+
+            // RBC size range in px at scale = 1.0.
+            minRBCSize = 20.
+            maxRBCSize = 40.
+
+            doGSigma1 = 1.5
+            doGSigma2 = 20.
+            doGLowFreqPercentageReduction = 0.75
+
+            factorNbPick = 2.0
+            factorWindowSize = 1.6
+
+            darkStainLevel = 0.4 // Lower -> more sensitive.
+
+            stainSigma = 10.
+            stainLevel = 0.9
+            stainSpreadRequired = 3.0
+
+            infectionSigma = 2.2
+            infectionLevel = 0.85
+            infectionPixelsRequired = 1
+
+            percentageOfFgValidCell = 0.4
+
+            MaxDarkStainRatio = 0.1
+
+            minimumCellArea = 1200. * scale ** 2. |> int
+            maxOffcenter = 0.5 }
+
+        match mode with
+        | CmdLine (input, output) ->
+            let config = { config with debug = DebugOn output }
+
+            Directory.CreateDirectory output |> ignore
+
+            use logFile = new StreamWriter(new FileStream(Path.Combine(output, "log.txt"), FileMode.Append, FileAccess.Write))
+            Utils.log <- (fun m -> logFile.WriteLine(m))
+            Utils.log (sprintf "=== New run : %A ===" DateTime.Now)
+
+            let files = match input with
+                        | File file -> [ file ]
+                        | Dir dir -> Directory.EnumerateFiles dir |> List.ofSeq
+
+            use resultFile = new StreamWriter(new FileStream(Path.Combine(output, "results.txt"), FileMode.Append, FileAccess.Write))
+
+            for file in files do
+                try
+                    use img = new Image<Bgr, byte>(file)
+                    Utils.log (sprintf "== File: %A" file)
+                    let cells = Utils.logTime "Whole analyze" (fun () -> ImageAnalysis.doAnalysis img (FileInfo(file).Name) config)
+                    let total, infected = Utils.countCells cells
+                    fprintf resultFile "File: %s %d %d %.2f\n" file total infected (100. * (float infected) / (float total))
+                with
+                | :? IOException as ex -> Utils.log (sprintf "Unable to open the image '%A': %A" file ex)
+            0
+
+        | Window ->
+            let app = new Application()
+            let mainWindow = Views.MainWindow()
+
+            Utils.log <- (fun m -> log mainWindow m)
+
+            //display mainWindow img
+            mainWindow.Root.Show()
+            app.Run()