1
module Parasitemia.Main
7 open FSharp.Collections.ParallelSeq
10 open Emgu.CV.Structure
19 | CmdLine of Input * string
22 type Arguments = RunningMode * bool
24 let parseArgs (args
: string[]) : Arguments =
26 let output = Array.tryFindIndex
((=) "--output") args
29 match Array.tryFindIndex
((=) "--folder") args
, output with
30 | Some i
, Some i_output when i
< args
.Length - 2 && i_output < args
.Length - 2 ->
31 CmdLine ((Dir args
.[i
+1]), args
.[i_output + 1])
33 match Array.tryFindIndex
((=) "--file") args
, output with
34 | Some i
, Some i_output when i
< args
.Length - 2 && i_output < args
.Length - 2 ->
35 CmdLine ((File args.[i
+1]), args.[i_output + 1])
39 runningMode, Array.exists
((=) "--debug") args
45 match parseArgs args with
50 initialAreaOpen
= 2000
55 preFilterSigma
= 1.7 // 1.5
59 darkStainLevel
= 0.25 // Lower -> more sensitive. 0.3. Careful about illumination on the borders.
60 maxDarkStainRatio
= 0.1 // 10 %
62 infectionArea
= 0.012f // 1.2 %
63 infectionLevel
= 1.12 // Lower -> more sensitive.
65 stainArea
= 0.08f // 8 %
66 stainLevel
= 1.1 // Lower -> more sensitive.
67 maxStainRatio
= 0.12 // 12 %
69 standardDeviationMaxRatio
= 0.5 // 0.55
70 minimumCellArea
= 0.5f })
73 | CmdLine (input
, output) ->
76 config.Debug <- DebugOn output
78 Directory.CreateDirectory output |> ignore
80 use logFile = new StreamWriter(new FileStream(Path.Combine(output, "log.txt"), FileMode.Append, FileAccess.Write))
81 Utils.log
<- (fun m
-> logFile.WriteLine(m
))
82 Utils.log
(sprintf
"=== New run : %A %A ===" DateTime.Now (if debug
then "[DEBUG]" else "[RELEASE]"))
84 let files = match input
with
85 | File file
-> [ file
]
86 | Dir dir
-> Directory.EnumerateFiles dir |> List.ofSeq
88 use resultFile = new StreamWriter(new FileStream(Path.Combine(output, "results.txt"), FileMode.Append, FileAccess.Write))
91 let images = seq
{ for file
in files -> Path.GetFileNameWithoutExtension(FileInfo(file
).Name), new Image<Bgr, byte
>(file
) }
93 let nbConcurrentTaskLimit = 4
94 let n = Environment.ProcessorCount
96 Utils.logTime
"Whole analyze" (fun () ->
99 |> PSeq.map
(fun (id
, img
) -> id
, ImageAnalysis.doAnalysis
img id
(config.Copy()))
100 |> PSeq.withDegreeOfParallelism
(if n > nbConcurrentTaskLimit then nbConcurrentTaskLimit else n)
102 for id
, cells
in results do
103 let total, infected
= Utils.countCells
cells
104 fprintf
resultFile "File: %s %d %d %.2f\n" id
total infected (100. * (float infected) / (float total)))
106 //Utils.log (sprintf "== File: %A" file)
108 //| :? IOException as ex -> Utils.log (sprintf "Unable to open the image '%A': %A" file ex)
112 (*let display (window : Views.MainWindow) (img : IImage) =
113 let imgControl = window.Root.FindName("img") :?> Controls.Image
114 imgControl.Source <- BitmapSourceConvert.ToBitmapSource(img)
116 let log (window : Views.MainWindow) (mess : string) =
117 let txtLog = window.Root.FindName("txtLog") :?> Controls.TextBlock
118 txtLog.Text <- txtLog.Text + mess + "\n"*)
120 if debug
then config.Debug <- DebugOn "."