module Parasitemia.Main open System open System.IO open System.Windows open System.Windows.Media open System.Windows.Markup open System.Windows.Shapes open System.Windows.Controls open System.Drawing open System.Diagnostics open Emgu.CV open Emgu.CV.Structure open Emgu.CV.WPF open Config 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" 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 [] 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 darkStainLevel = 0.5 stainSigma = 10. stainLevel = 0.9 stainSpreadRequired = 3.0 infectionSigma = 2.2 infectionLevel = 0.85 infectionPixelsRequired = 1 percentageOfFgValidCell = 0.4 MaxDarkStainRatio = 0.1 minimumCellArea = 600. * 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(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 | _ 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()