histogram.go 1.1 KB

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