6 open FSharp.Collections.ParallelSeq
17 let doAnalysis (img
: Image<Bgr, byte
>) (name
: string) (config
: Config) (reportProgress
: (int -> unit) option) : Cell list =
18 let inline report
(percent
: int) =
19 match reportProgress
with
23 use green = img
.Item(1)
24 let greenFloat = green.Convert<Gray, float32
>()
25 let filteredGreen = gaussianFilter
greenFloat (float config.Parameters.preFilterSigma
)
27 logTime
"areaOpen 1" (fun () -> ImgTools.areaOpenF
filteredGreen config.Parameters.initialAreaOpen
)
30 let r1 = logTime
"Granulometry (morpho)" (fun() -> Granulometry.findRadiusByClosing
(filteredGreen.Convert<Gray, byte
>()) (10, 80) 0.5 |> float32
)
31 // let r2 = logTime "Granulometry (area)" (fun() -> Granulometry.findRadiusByAreaClosing filteredGreen (10, 80) |> float32)
32 // log (sprintf "r1: %A, r2: %A" r1 r2)
33 config.RBCRadius <- r1
36 let secondAreaOpen = int <| config.RBCArea * config.Parameters.ratioSecondAreaOpen
38 if secondAreaOpen > config.Parameters.initialAreaOpen
40 logTime
"areaOpen 2" (fun () -> ImgTools.areaOpenF
filteredGreen secondAreaOpen)
42 let parasites, filteredGreenWhitoutStain
= ParasitesMarker.find
filteredGreen config
43 //let parasites, filteredGreenWhitoutInfection, filteredGreenWhitoutStain = ParasitesMarker.findMa greenFloat filteredGreenFloat config
45 let edges, xGradient
, yGradient
= logTime
"Finding edges" (fun () -> ImgTools.findEdges
filteredGreenWhitoutStain)
46 logTime
"Removing small connected components from thinning" (fun () -> removeArea
edges (config.RBCRadius ** 2.f
/ 50.f
|> int))
48 let allEllipses, ellipses
= logTime
"Finding ellipses" (fun () ->
49 let matchingEllipses = Ellipse.find
edges xGradient yGradient
config
50 matchingEllipses.Ellipses, matchingEllipses.PrunedEllipses)
53 let cells = logTime
"Classifier" (fun () -> Classifier.findCells
ellipses parasites filteredGreenWhitoutStain config)
56 // Output pictures if debug flag is set.
57 match config.Debug with
59 let dirPath = System.IO.Path.Combine(output
, name
)
60 System.IO.Directory.CreateDirectory dirPath |> ignore
62 let buildFileName postfix
= System.IO.Path.Combine(dirPath, name
+ postfix
)
64 saveMat
(edges * 255.0) (buildFileName " - edges.png")
66 saveImg
parasites.darkStain
(buildFileName " - parasites - dark stain.png")
67 saveImg
parasites.stain
(buildFileName " - parasites - stain.png")
68 saveImg
parasites.infection
(buildFileName " - parasites - infection.png")
70 let imgAllEllipses = img
.Copy()
71 drawEllipses
imgAllEllipses allEllipses (Bgr(0.0, 240.0, 240.0)) 0.05
72 saveImg
imgAllEllipses (buildFileName " - ellipses - all.png")
74 let imgEllipses = filteredGreenWhitoutStain.Convert<Bgr, byte
>()
75 drawEllipses
imgEllipses ellipses (Bgr(0.0, 240.0, 240.0)) 1.0
76 saveImg
imgEllipses (buildFileName " - ellipses.png")
78 let imgCells = img
.Copy()
79 drawCells
imgCells false cells
80 saveImg
imgCells (buildFileName " - cells.png")
82 let imgCells' = img.Copy()
83 drawCells imgCells' true cells
84 saveImg
imgCells' (buildFileName " - cells - full.png")
86 let filteredGreenMaxima = gaussianFilter greenFloat config.Parameters.preFilterSigma
87 for m in ImgTools.findMaxima filteredGreenMaxima do
88 ImgTools.drawPoints filteredGreenMaxima m 255.f
89 saveImg filteredGreenMaxima (buildFileName " - filtered - maxima.png")
91 saveImg filteredGreen (buildFileName " - filtered.png")
92 saveImg filteredGreenWhitoutStain (buildFileName " - filtered closed stain.png")
93 //saveImg filteredGreenWhitoutInfection (buildFileName " - filtered closed infection.png")
95 saveImg green (buildFileName " - green.png")
97 use blue = img.Item(0)
98 saveImg blue (buildFileName " - blue.png")
100 use red = img.Item(2)
101 saveImg red (buildFileName " - red.png")
107 // ID * cell radius * cell list.
108 let doMultipleAnalysis (imgs: (string * Image<Bgr, byte>) list) (config : Config) (reportProgress: (int -> unit) option) : (string * float * Cell list) list =
109 let inline report (percent: int) =
110 match reportProgress with
111 | Some f -> f percent
114 let monitor = Object()
115 let mutable total = 0
116 let nbImgs = List.length imgs
117 let reportProgressImg =
119 lock monitor (fun () -> total <- total + progress)
120 report (total / nbImgs))
122 let nbConcurrentTaskLimit = 4
123 let n = Environment.ProcessorCount
126 |> PSeq.map (fun (id, img) ->
127 let localConfig = config.Copy()
128 let cells = doAnalysis img id localConfig (Some reportProgressImg)
129 id, float localConfig.RBCRadius, cells)
130 |> PSeq.withDegreeOfParallelism (if n > nbConcurrentTaskLimit then nbConcurrentTaskLimit else n)