let report (percent: int) : unit option =
reportWithVal percent ()
- let inline buildLogWithName (text: string) = sprintf "(%s) %s" name text
+ let inline buildLogWithName (text: string) = sprintf "№ %s: %s" name text
let logWithName mess = Log.User(buildLogWithName mess)
let inline logTimeWithName (text: string) (f: unit -> 'a option) : 'a option = Log.LogWithTime((buildLogWithName text), Severity.USER, f)
+ // Monadic construction to be able to abort the progress when running.
maybe {
do! report 0
use img_float = img.Convert<Bgr, float32>()
- use img_RBC = img_float.[1] // mergeChannelsWithProjection img_float config.Parameters.averageColor_RBC config.Parameters.averageColor_BG 255.
+ use img_RBC = img_float.[1] // Green.
use img_RBC_filtered = gaussianFilter img_RBC config.LPFStandardDeviationRBC
- use img_parasites = img_float.[2] // mergeChannelsWithProjection img_float config.Parameters.averageColor_Parasite config.Parameters.averageColor_RBC 255.
+ use img_parasites = img_float.[2] // Red.
use img_parasites_filtered = gaussianFilter img_parasites config.LPFStandardDeviationParasite
logWithName (sprintf "Nominal erythrocyte diameter: %A" config.RBCRadiusByResolution)
let range =
let delta = config.Parameters.granulometryRange * config.RBCRadiusByResolution.Pixel
int <| config.RBCRadiusByResolution.Pixel - delta, int <| config.RBCRadiusByResolution.Pixel + delta
+
let! radius = logTimeWithName "Granulometry (area)" (fun() -> reportWithVal 10 (Granulometry.findRadiusByAreaClosing img_RBC_filtered range |> float32))
+ //let! radius = logTimeWithName "Granulometry (morpho)" (fun() -> reportWithVal 10 (Granulometry.findRadiusByClosing img_RBC_filtered range 1. true |> float32))
config.SetRBCRadius <| radius
logWithName (sprintf "Found erythrocyte diameter: %A" config.RBCRadius)
let! prunedEllipses = logTimeWithName "Ellipses pruning" (fun () -> reportWithVal 80 (matchingEllipses.PrunedEllipses))
- let! cells = logTimeWithName "Classifier" (fun () -> reportWithVal 100 (Classifier.findCells prunedEllipses parasites img_RBC_filtered config))
+ let! cells = logTimeWithName "Classifier" (fun () -> reportWithVal 100 (Classifier.findCells prunedEllipses parasites img.Width img.Height config))
logWithName "Analysis finished"
IO.saveImg parasites.parasite (buildFileName " - parasites - stain.png")
IO.saveImg parasites.nucleus (buildFileName " - parasites - infection.png")
- let imgAllEllipses = img.Copy()
- Drawing.drawEllipses imgAllEllipses matchingEllipses.Ellipses (Bgr(255.0, 255.0, 255.0)) 0.04
+ let imgAllEllipses = img_RBC_filtered.Copy()
+ Drawing.drawEllipses imgAllEllipses matchingEllipses.Ellipses (Gray(200.0)) 0.04
IO.saveImg imgAllEllipses (buildFileName " - ellipses - all.png")
let imgEllipses = img_RBC_filtered.Convert<Bgr, byte>()
Drawing.drawCells imgCells' true cells
IO.saveImg imgCells' (buildFileName " - cells - full.png")
- let filteredGreenMaxima = gaussianFilter img_RBC config.LPFStandardDeviationRBC
- for m in findMaxima filteredGreenMaxima do
- Drawing.drawPoints filteredGreenMaxima m 255.f
- IO.saveImg filteredGreenMaxima (buildFileName " - filtered - maxima.png")
+ let filteredRBCMaxima = gaussianFilter img_RBC config.LPFStandardDeviationRBC
+ for m in findMaxima filteredRBCMaxima do
+ Drawing.drawPoints filteredRBCMaxima m 255.f
+ IO.saveImg filteredRBCMaxima (buildFileName " - filtered - maxima.png")
IO.saveImg imgWhitoutParasite (buildFileName " - filtered closed stain.png")
IO.saveImg imgWithoutNucleus (buildFileName " - filtered closed infection.png")
imgs
|> PSeq.choose (
fun (id, config, img) ->
- match doAnalysis img id config (Some (fun p -> reportProgressImg id p)) with
- | Some result -> Some (id, result)
- | None -> None)
+ try
+ match doAnalysis img id config (Some (fun p -> reportProgressImg id p)) with
+ | Some result -> Some (id, result)
+ | None -> None
+ with
+ | ex ->
+ Log.Error("Analysis {0} failed: {1}", id, ex)
+ None)
|> PSeq.withDegreeOfParallelism n
|> PSeq.toList