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