module ParasitemiaCore.Histogram open System open System.Drawing open Emgu.CV open Emgu.CV.Structure type Histogram = { data : int[] total : int // Number of elements. sum : int // Sum of all intensity. min : float32 max : float32 } let histogramImg (img : Image) (nbSamples : int) : Histogram = let imgData = img.Data let min, max = let min = ref [| 0.0 |] let minLocation = ref <| [| Point () |] let max = ref [| 0.0 |] let maxLocation = ref <| [| Point () |] img.MinMax (min, max, minLocation, maxLocation) float32 (!min).[0], float32 (!max).[0] let inline bin (x : float32) : int = let p = int ((x - min) / (max - min) * float32 nbSamples) if p >= nbSamples then nbSamples - 1 else p let data = Array.zeroCreate nbSamples for i = 0 to img.Height - 1 do for j = 0 to img.Width - 1 do let p = bin imgData.[i, j, 0] data.[p] <- data.[p] + 1 { data = data; total = img.Height * img.Width; sum = Array.sum data; min = min; max = max } let histogramMat (mat : Matrix) (nbSamples : int) : Histogram = let matData = mat.Data let min, max = let min = ref 0.0 let minLocation = ref <| Point () let max = ref 0.0 let maxLocation = ref <| Point () mat.MinMax (min, max, minLocation, maxLocation) float32 !min, float32 !max let inline bin (x : float32) : int = let p = int ((x - min) / (max - min) * float32 nbSamples) if p >= nbSamples then nbSamples - 1 else p let data = Array.zeroCreate nbSamples for i = 0 to mat.Height - 1 do for j = 0 to mat.Width - 1 do let p = bin matData.[i, j] data.[p] <- data.[p] + 1 { data = data; total = mat.Height * mat.Width; sum = Array.sum data; min = min; max = max } let histogram (values : float32 seq) (nbSamples : int) : Histogram = let mutable min = Single.MaxValue let mutable max = Single.MinValue let mutable n = 0 for v in values do n <- n + 1 if v < min then min <- v if v > max then max <- v let inline bin (x : float32) : int = let p = int ((x - min) / (max - min) * float32 nbSamples) if p >= nbSamples then nbSamples - 1 else p let data = Array.zeroCreate nbSamples for v in values do let p = bin v data.[p] <- data.[p] + 1 { data = data; total = n; sum = Array.sum data; min = min; max = max }