To .NET 5 (lot of refactoring)
[master-thesis.git] / Parasitemia / ParasitemiaCore / ImgTools / ImgTools.fs
1 module ParasitemiaCore.ImgTools
2
3 open System.Drawing
4
5 open Emgu.CV
6 open Emgu.CV.Structure
7
8 /// <summary>
9 /// Normalize an image between 0 and 'upperLimit'.
10 /// FIXME: use to many memory.
11 /// </summary>
12 /// <param name="img"></param>
13 /// <param name="upperLimit"></param>
14 let normalize (img : Image<Gray, float32>) (upperLimit : float) : Image<Gray, float32> =
15 let min = ref [| 0.0 |]
16 let minLocation = ref <| [| Point () |]
17 let max = ref [| 0.0 |]
18 let maxLocation = ref <| [| Point () |]
19 img.MinMax (min, max, minLocation, maxLocation)
20 let normalized = (img - (!min).[0]) / ((!max).[0] - (!min).[0])
21 if upperLimit = 1.0 then
22 normalized
23 else
24 upperLimit * normalized
25
26 let mergeChannels (img : Image<Bgr, float32>) (rgbWeights : float * float * float) : Image<Gray, float32> =
27 match rgbWeights with
28 | 1., 0., 0. -> img.[2]
29 | 0., 1., 0. -> img.[1]
30 | 0., 0., 1. -> img.[0]
31 | redFactor, greenFactor, blueFactor ->
32 let result = new Image<Gray, float32> (img.Size)
33 CvInvoke.AddWeighted (result, 1., img.[2], redFactor, 0., result)
34 CvInvoke.AddWeighted (result, 1., img.[1], greenFactor, 0., result)
35 CvInvoke.AddWeighted (result, 1., img.[0], blueFactor, 0., result)
36 result
37
38 let mergeChannelsWithProjection (img : Image<Bgr, float32>) (v1r : float32, v1g : float32, v1b : float32) (v2r : float32, v2g : float32, v2b : float32) (upperLimit : float) : Image<Gray, float32> =
39 let vr, vg, vb = v2r - v1r, v2g - v1g, v2b - v1b
40 let vMagnitude = sqrt (vr ** 2.f + vg ** 2.f + vb ** 2.f)
41 let project (r : float32) (g : float32) (b : float32) = ((r - v1r) * vr + (g - v1g) * vg + (b - v1b) * vb) / vMagnitude
42 let result = new Image<Gray, float32> (img.Size)
43 // TODO: Essayer en bindant Data pour gagner du temps
44 for i = 0 to img.Height - 1 do
45 for j = 0 to img.Width - 1 do
46 result.Data.[i, j, 0] <- project img.Data.[i, j, 2] img.Data.[i, j, 1] img.Data.[i, j, 0]
47 normalize result upperLimit
48
49 // Normalize image values between 0uy and 255uy.
50 let normalizeAndConvert (img : Image<Gray, 'TDepth>) : Image<Gray, byte> =
51 (normalize (img.Convert<Gray, float32> ()) 255.).Convert<Gray, byte> ()
52
53 let gaussianFilter (img : Image<'TColor, 'TDepth>) (standardDeviation : float) : Image<'TColor, 'TDepth> =
54 let size = 2 * int (ceil (4.0 * standardDeviation)) + 1
55 img.SmoothGaussian (size, size, standardDeviation, standardDeviation)