git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/imaging/histogram.go (about) 1 package imaging 2 3 import ( 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. 12 func 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 }