ImageStat.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #
  2. # The Python Imaging Library.
  3. # $Id$
  4. #
  5. # global image statistics
  6. #
  7. # History:
  8. # 1996-04-05 fl Created
  9. # 1997-05-21 fl Added mask; added rms, var, stddev attributes
  10. # 1997-08-05 fl Added median
  11. # 1998-07-05 hk Fixed integer overflow error
  12. #
  13. # Notes:
  14. # This class shows how to implement delayed evaluation of attributes.
  15. # To get a certain value, simply access the corresponding attribute.
  16. # The __getattr__ dispatcher takes care of the rest.
  17. #
  18. # Copyright (c) Secret Labs AB 1997.
  19. # Copyright (c) Fredrik Lundh 1996-97.
  20. #
  21. # See the README file for information on usage and redistribution.
  22. #
  23. from __future__ import annotations
  24. import math
  25. class Stat:
  26. def __init__(self, image_or_list, mask=None):
  27. try:
  28. if mask:
  29. self.h = image_or_list.histogram(mask)
  30. else:
  31. self.h = image_or_list.histogram()
  32. except AttributeError:
  33. self.h = image_or_list # assume it to be a histogram list
  34. if not isinstance(self.h, list):
  35. msg = "first argument must be image or list"
  36. raise TypeError(msg)
  37. self.bands = list(range(len(self.h) // 256))
  38. def __getattr__(self, id):
  39. """Calculate missing attribute"""
  40. if id[:4] == "_get":
  41. raise AttributeError(id)
  42. # calculate missing attribute
  43. v = getattr(self, "_get" + id)()
  44. setattr(self, id, v)
  45. return v
  46. def _getextrema(self):
  47. """Get min/max values for each band in the image"""
  48. def minmax(histogram):
  49. res_min, res_max = 255, 0
  50. for i in range(256):
  51. if histogram[i]:
  52. res_min = i
  53. break
  54. for i in range(255, -1, -1):
  55. if histogram[i]:
  56. res_max = i
  57. break
  58. return res_min, res_max
  59. return [minmax(self.h[i:]) for i in range(0, len(self.h), 256)]
  60. def _getcount(self):
  61. """Get total number of pixels in each layer"""
  62. return [sum(self.h[i : i + 256]) for i in range(0, len(self.h), 256)]
  63. def _getsum(self):
  64. """Get sum of all pixels in each layer"""
  65. v = []
  66. for i in range(0, len(self.h), 256):
  67. layer_sum = 0.0
  68. for j in range(256):
  69. layer_sum += j * self.h[i + j]
  70. v.append(layer_sum)
  71. return v
  72. def _getsum2(self):
  73. """Get squared sum of all pixels in each layer"""
  74. v = []
  75. for i in range(0, len(self.h), 256):
  76. sum2 = 0.0
  77. for j in range(256):
  78. sum2 += (j**2) * float(self.h[i + j])
  79. v.append(sum2)
  80. return v
  81. def _getmean(self):
  82. """Get average pixel level for each layer"""
  83. return [self.sum[i] / self.count[i] for i in self.bands]
  84. def _getmedian(self):
  85. """Get median pixel level for each layer"""
  86. v = []
  87. for i in self.bands:
  88. s = 0
  89. half = self.count[i] // 2
  90. b = i * 256
  91. for j in range(256):
  92. s = s + self.h[b + j]
  93. if s > half:
  94. break
  95. v.append(j)
  96. return v
  97. def _getrms(self):
  98. """Get RMS for each layer"""
  99. return [math.sqrt(self.sum2[i] / self.count[i]) for i in self.bands]
  100. def _getvar(self):
  101. """Get variance for each layer"""
  102. return [
  103. (self.sum2[i] - (self.sum[i] ** 2.0) / self.count[i]) / self.count[i]
  104. for i in self.bands
  105. ]
  106. def _getstddev(self):
  107. """Get standard deviation for each layer"""
  108. return [math.sqrt(self.var[i]) for i in self.bands]
  109. Global = Stat # compatibility