To .NET 5 (lot of refactoring)
[master-thesis.git] / Parasitemia / ParasitemiaCore / ParasitesMarker.fs
1 module ParasitemiaCore.ParasitesMarker
2
3 open System.Drawing
4 open System.Linq
5
6 open Emgu.CV
7 open Emgu.CV.Structure
8
9 open Utils
10 open Histogram
11 open Otsu
12 open Morpho
13
14 type Result =
15 {
16 darkStain : Image<Gray, byte> // Colored pixel, it's independent of the size of the areas. It corresponds to white cells, schizontes, gametocytes, throphozoites.
17 nucleus : Image<Gray, byte> // Parasite nucleus. It may contain some debris. It shouldn't contain thrombocytes or larger elements.
18 parasite : Image<Gray, byte> // The whole parasites.
19 }
20
21 let find (img : Image<Gray, float32>) (config : Config.Config) : Result * Image<Gray, float32> * Image<Gray, float32> =
22
23 let imgWithoutNucleus = img.Copy ()
24 areaCloseF imgWithoutNucleus (roundInt config.RBCRadius.NucleusArea)
25
26 let darkStain =
27 // We use the filtered image to find the dark stain.
28 let _, mean_fg, mean_bg =
29 let hist = histogramImg imgWithoutNucleus 300
30 otsu hist
31 imgWithoutNucleus.Cmp (float mean_fg - config.Parameters.darkStainLevel * float (mean_bg - mean_fg), CvEnum.CmpType.LessThan)
32
33 let marker (img : Image<Gray, float32>) (closed : Image<Gray, float32>) (level : float) : Image<Gray, byte> =
34 let diff = img.Copy ()
35 diff._Mul level
36 CvInvoke.Subtract (closed, diff, diff)
37 diff._ThresholdBinary (Gray 0.0, Gray 255.)
38 diff.Convert<Gray, byte> ()
39
40 // Nucleus.
41 let nucleusMarker = marker img imgWithoutNucleus (1. / config.Parameters.infectionSensitivity)
42
43 // Cytoplasm.
44 let imgWithoutParasite = img.CopyBlank ()
45 let kernelSize =
46 let size = roundInt config.RBCRadius.CytoplasmSize
47 if size % 2 = 0 then size + 1 else size
48 use kernel =
49 if kernelSize <= 3 then
50 CvInvoke.GetStructuringElement (CvEnum.ElementShape.Rectangle, Size (3, 3), Point (-1, -1))
51 else
52 CvInvoke.GetStructuringElement (CvEnum.ElementShape.Ellipse, Size (kernelSize, kernelSize), Point (-1, -1))
53
54 CvInvoke.MorphologyEx (img, imgWithoutParasite, CvEnum.MorphOp.Close, kernel, Point(-1, -1), 1, CvEnum.BorderType.Replicate, MCvScalar())
55 let parasiteMarker = marker img imgWithoutParasite (1. / config.Parameters.cytoplasmSensitivity)
56
57 {
58 darkStain = darkStain
59 nucleus = nucleusMarker
60 parasite = parasiteMarker
61 },
62 imgWithoutParasite,
63 imgWithoutNucleus
64
65