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