1package imaging
2
3import (
4 "image"
5 "sync"
6)
7
8// Histogram returns a normalized histogram of an image.
9//
10// Resulting histogram is represented as an array of 256 floats, where
11// histogram[i] is a probability of a pixel being of a particular luminance i.
12func Histogram(img image.Image) [256]float64 {
13 var mu sync.Mutex
14 var histogram [256]float64
15 var total float64
16
17 src := newScanner(img)
18 if src.w == 0 || src.h == 0 {
19 return histogram
20 }
21
22 parallel(0, src.h, func(ys <-chan int) {
23 var tmpHistogram [256]float64
24 var tmpTotal float64
25 scanLine := make([]uint8, src.w*4)
26 for y := range ys {
27 src.scan(0, y, src.w, y+1, scanLine)
28 i := 0
29 for x := 0; x < src.w; x++ {
30 s := scanLine[i : i+3 : i+3]
31 r := s[0]
32 g := s[1]
33 b := s[2]
34 y := 0.299*float32(r) + 0.587*float32(g) + 0.114*float32(b)
35 tmpHistogram[int(y+0.5)]++
36 tmpTotal++
37 i += 4
38 }
39 }
40 mu.Lock()
41 for i := 0; i < 256; i++ {
42 histogram[i] += tmpHistogram[i]
43 }
44 total += tmpTotal
45 mu.Unlock()
46 })
47
48 for i := 0; i < 256; i++ {
49 histogram[i] = histogram[i] / total
50 }
51 return histogram
52}