f477cfe03bf9bc46ea9fc7ba189d0b321e2a13e8
[master-thesis.git] / Parasitemia / Parasitemia / Program.fs
1 module Parasitemia.Main
2
3 open System
4 open System.IO
5 open System.Windows
6 open System.Windows.Media
7 open System.Windows.Markup
8 open System.Windows.Shapes
9 open System.Windows.Controls
10 open System.Drawing
11 open System.Diagnostics
12 open System.Threading
13
14 open FSharp.Collections.ParallelSeq
15
16 open Emgu.CV
17 open Emgu.CV.Structure
18 open Emgu.CV.WPF
19
20 open Config
21
22 let display (window : Views.MainWindow) (img : IImage) =
23 let imgControl = window.Root.FindName("img") :?> Controls.Image
24 imgControl.Source <- BitmapSourceConvert.ToBitmapSource(img)
25
26 let log (window : Views.MainWindow) (mess : string) =
27 let txtLog = window.Root.FindName("txtLog") :?> Controls.TextBlock
28 txtLog.Text <- txtLog.Text + mess + "\n"
29
30
31 type Input =
32 | File of string
33 | Dir of string
34
35 type RunningMode =
36 | CmdLine of Input * string
37 | Window
38
39 type Arguments = RunningMode * bool
40
41 let parseArgs (args: string[]) : Arguments =
42
43 let output = Array.tryFindIndex ((=) "--output") args
44
45 let runningMode =
46 match Array.tryFindIndex ((=) "--folder") args, output with
47 | Some i, Some i_output when i < args.Length - 2 && i_output < args.Length - 2 ->
48 CmdLine ((Dir args.[i+1]), args.[i_output + 1])
49 | _ ->
50 match Array.tryFindIndex ((=) "--file") args, output with
51 | Some i, Some i_output when i < args.Length - 2 && i_output < args.Length - 2 ->
52 CmdLine ((File args.[i+1]), args.[i_output + 1])
53 |_ ->
54 Window
55
56 runningMode, Array.exists ((=) "--debug") args
57
58
59 [<EntryPoint>]
60 let main args =
61 match parseArgs args with
62 | mode, debug ->
63 let config =
64 Config(
65 {
66 initialAreaOpen = 2000
67
68 minRbcRadius = -0.32f
69 maxRbcRadius = 0.32f
70
71 preFilterSigma = 1.7 // 1.5
72
73 factorNbPick = 1.0
74
75 darkStainLevel = 0.25 // Lower -> more sensitive. 0.3. Careful about illumination on the borders.
76 maxDarkStainRatio = 0.1 // 10 %
77
78 infectionArea = 0.012f // 1.2 %
79 infectionLevel = 1.12 // Lower -> more sensitive.
80
81 stainArea = 0.08f // 8 %
82 stainLevel = 1.1 // Lower -> more sensitive.
83 maxStainRatio = 0.12 // 12 %
84
85 standardDeviationMaxRatio = 0.5 // 0.55
86 minimumCellArea = 0.5f })
87
88 match mode with
89 | CmdLine (input, output) ->
90 if debug
91 then
92 config.Debug <- DebugOn output
93
94 Directory.CreateDirectory output |> ignore
95
96 use logFile = new StreamWriter(new FileStream(Path.Combine(output, "log.txt"), FileMode.Append, FileAccess.Write))
97 Utils.log <- (fun m -> logFile.WriteLine(m))
98 Utils.log (sprintf "=== New run : %A %A ===" DateTime.Now (if debug then "[DEBUG]" else "[RELEASE]"))
99
100 let files = match input with
101 | File file -> [ file ]
102 | Dir dir -> Directory.EnumerateFiles dir |> List.ofSeq
103
104 use resultFile = new StreamWriter(new FileStream(Path.Combine(output, "results.txt"), FileMode.Append, FileAccess.Write))
105
106 //try
107 let images = seq { for file in files -> Path.GetFileNameWithoutExtension(FileInfo(file).Name), new Image<Bgr, byte>(file) }
108
109 let nbConcurrentTaskLimit = 4
110 let n = Environment.ProcessorCount
111
112 Utils.logTime "Whole analyze" (fun () ->
113 let results =
114 images
115 |> PSeq.map (fun (id, img) -> id, ImageAnalysis.doAnalysis img id (config.Copy()))
116 |> PSeq.withDegreeOfParallelism (if n > nbConcurrentTaskLimit then nbConcurrentTaskLimit else n)
117
118 for id, cells in results do
119 let total, infected = Utils.countCells cells
120 fprintf resultFile "File: %s %d %d %.2f\n" id total infected (100. * (float infected) / (float total)))
121
122 //Utils.log (sprintf "== File: %A" file)
123 //with
124 //| :? IOException as ex -> Utils.log (sprintf "Unable to open the image '%A': %A" file ex)
125 0
126
127 | Window ->
128 let app = new Application()
129 let mainWindow = Views.MainWindow()
130
131 if debug
132 then
133 config.Debug <- DebugOn "."
134
135 Utils.log <- (fun m -> log mainWindow m)
136
137 //display mainWindow img
138 mainWindow.Root.Show()
139 app.Run()