metrics.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. # module file which contains all image metrics used in project
  2. from numpy.linalg import svd
  3. from scipy import misc
  4. import numpy as np
  5. from sklearn import preprocessing
  6. from skimage import io, color
  7. import cv2
  8. def get_SVD(image):
  9. """Transforms Image using SVD compression
  10. Args:
  11. image: image to convert into SVD compression
  12. Return:
  13. U, s, V obtained from SVD compression
  14. Usage:
  15. >>> from PIL import Image
  16. >>> from ipfml import metrics
  17. >>> img = Image.open('./images/test_img.png')
  18. >>> U, s, V = metrics.get_SVD(img)
  19. >>> U.shape
  20. (200, 200, 3)
  21. >>> len(s)
  22. 200
  23. >>> V.shape
  24. (200, 3, 3)
  25. """
  26. return svd(image, full_matrices=False)
  27. def get_SVD_s(image):
  28. """Transforms Image into SVD and returns only 's' part
  29. Args:
  30. image: image to convert
  31. Returns:
  32. vector of singular values obtained from SVD compression
  33. Usage:
  34. >>> from PIL import Image
  35. >>> from ipfml import metrics
  36. >>> img = Image.open('./images/test_img.png')
  37. >>> s = metrics.get_SVD_s(img)
  38. >>> len(s)
  39. 200
  40. """
  41. U, s, V = svd(image, full_matrices=False)
  42. return s
  43. def get_SVD_U(image):
  44. """Transforms Image into SVD and returns only 'U' part
  45. Args:
  46. image: image to convert
  47. Returns:
  48. U matrix from SVD compression
  49. Usage:
  50. >>> from PIL import Image
  51. >>> from ipfml import metrics
  52. >>> img = Image.open('./images/test_img.png')
  53. >>> U = metrics.get_SVD_U(img)
  54. >>> U.shape
  55. (200, 200, 3)
  56. """
  57. U, s, V = svd(image, full_matrices=False)
  58. return U
  59. def get_SVD_V(image):
  60. """Transforms Image into SVD and returns only 'V' part
  61. Args:
  62. image: image to convert
  63. Returns:
  64. V matrix obtained from SVD compression
  65. Usage :
  66. >>> from PIL import Image
  67. >>> from ipfml import metrics
  68. >>> img = Image.open('./images/test_img.png')
  69. >>> V = metrics.get_SVD_V(img)
  70. >>> V.shape
  71. (200, 3, 3)
  72. """
  73. U, s, V = svd(image, full_matrices=False)
  74. return V
  75. def get_LAB(image):
  76. """Transforms RGB Image into Lab
  77. Args:
  78. image: image to convert
  79. Returns:
  80. Lab information
  81. Usage:
  82. >>> from PIL import Image
  83. >>> from ipfml import metrics
  84. >>> img = Image.open('./images/test_img.png')
  85. >>> Lab = metrics.get_LAB(img)
  86. >>> Lab.shape
  87. (200, 200, 3)
  88. """
  89. return color.rgb2lab(image)
  90. def get_LAB_L(image):
  91. """Transforms RGB Image into Lab and returns L
  92. Args:
  93. image: image to convert
  94. Returns:
  95. The L chanel from Lab information
  96. >>> from PIL import Image
  97. >>> from ipfml import metrics
  98. >>> img = Image.open('./images/test_img.png')
  99. >>> L = metrics.get_LAB_L(img)
  100. >>> L.shape
  101. (200, 200)
  102. """
  103. lab = get_LAB(image)
  104. return lab[:, :, 0]
  105. def get_LAB_a(image):
  106. """Transforms RGB Image into LAB and returns a
  107. Args:
  108. image: image to convert
  109. Returns:
  110. The a chanel from Lab information
  111. Usage:
  112. >>> from PIL import Image
  113. >>> from ipfml import metrics
  114. >>> img = Image.open('./images/test_img.png')
  115. >>> a = metrics.get_LAB_a(img)
  116. >>> a.shape
  117. (200, 200)
  118. """
  119. lab = get_LAB(image)
  120. return lab[:, :, 1]
  121. def get_LAB_b(image):
  122. """Transforms RGB Image into LAB and returns b
  123. Args:
  124. image: image to convert
  125. Returns:
  126. The b chanel from Lab information
  127. Usage :
  128. >>> from PIL import Image
  129. >>> from ipfml import metrics
  130. >>> img = Image.open('./images/test_img.png')
  131. >>> b = metrics.get_LAB_b(img)
  132. >>> b.shape
  133. (200, 200)
  134. """
  135. lab = get_LAB(image)
  136. return lab[:, :, 2]
  137. def get_XYZ(image):
  138. """Transforms RGB Image into XYZ
  139. Args:
  140. image: image to convert
  141. Returns:
  142. XYZ information obtained from transformation
  143. Usage:
  144. >>> from PIL import Image
  145. >>> from ipfml import metrics
  146. >>> img = Image.open('./images/test_img.png')
  147. >>> metrics.get_XYZ(img).shape
  148. (200, 200, 3)
  149. """
  150. return color.rgb2xyz(image)
  151. def get_XYZ_X(image):
  152. """Transforms RGB Image into XYZ and returns X
  153. Args:
  154. image: image to convert
  155. Returns:
  156. The X chanel from XYZ information
  157. Usage:
  158. >>> from PIL import Image
  159. >>> from ipfml import metrics
  160. >>> img = Image.open('./images/test_img.png')
  161. >>> x = metrics.get_XYZ_X(img)
  162. >>> x.shape
  163. (200, 200)
  164. """
  165. xyz = color.rgb2xyz(image)
  166. return xyz[:, :, 0]
  167. def get_XYZ_Y(image):
  168. """Transforms RGB Image into XYZ and returns Y
  169. Args:
  170. image: image to convert
  171. Returns:
  172. The Y chanel from XYZ information
  173. Usage:
  174. >>> from PIL import Image
  175. >>> from ipfml import metrics
  176. >>> img = Image.open('./images/test_img.png')
  177. >>> y = metrics.get_XYZ_Y(img)
  178. >>> y.shape
  179. (200, 200)
  180. """
  181. xyz = color.rgb2xyz(image)
  182. return xyz[:, :, 1]
  183. def get_XYZ_Z(image):
  184. """Transforms RGB Image into XYZ and returns Z
  185. Args:
  186. image: image to convert
  187. Returns:
  188. The Z chanel from XYZ information
  189. Raises:
  190. ValueError: If `nb_bits` has unexpected value. `nb_bits` needs to be in interval [1, 8].
  191. Usage:
  192. >>> from PIL import Image
  193. >>> from ipfml import metrics
  194. >>> img = Image.open('./images/test_img.png')
  195. >>> z = metrics.get_XYZ_Z(img)
  196. >>> z.shape
  197. (200, 200)
  198. """
  199. xyz = color.rgb2xyz(image)
  200. return xyz[:, :, 2]
  201. def get_low_bits_img(image, nb_bits=4):
  202. """Returns Image or Numpy array with data information reduced using only low bits
  203. Args:
  204. image: image to convert
  205. nb_bits: optional parameter which indicates the number of bits to keep
  206. Returns:
  207. Numpy array with reduced values
  208. Usage:
  209. >>> from PIL import Image
  210. >>> from ipfml import metrics
  211. >>> img = Image.open('./images/test_img.png')
  212. >>> low_bits_img = metrics.get_low_bits_img(img, 5)
  213. >>> low_bits_img.shape
  214. (200, 200, 3)
  215. """
  216. if nb_bits <= 0:
  217. raise ValueError(
  218. "unexpected value of number of bits to keep. @nb_bits needs to be positive and greater than 0."
  219. )
  220. if nb_bits > 8:
  221. raise ValueError(
  222. "Unexpected value of number of bits to keep. @nb_bits needs to be in interval [1, 8]."
  223. )
  224. img_arr = np.array(image)
  225. bits_values = sum([pow(2, i - 1) for i in range(1, nb_bits + 1)])
  226. return img_arr & bits_values
  227. def get_bits_img(image, interval):
  228. """Returns only bits specified into the interval
  229. Args:
  230. image: image to convert using this interval of bits value to keep
  231. interval: (begin, end) of bits values
  232. Returns:
  233. Numpy array with reduced values
  234. Raises:
  235. ValueError: If min value from interval is not >= 1.
  236. ValueError: If max value from interval is not <= 8.
  237. ValueError: If min value from interval >= max value.
  238. Usage:
  239. >>> from PIL import Image
  240. >>> from ipfml import metrics
  241. >>> img = Image.open('./images/test_img.png')
  242. >>> bits_img = metrics.get_bits_img(img, (2, 5))
  243. >>> bits_img.shape
  244. (200, 200, 3)
  245. """
  246. img_arr = np.array(image)
  247. begin, end = interval
  248. if begin < 1:
  249. raise ValueError(
  250. "Unexpected value of interval. Interval min value needs to be >= 1."
  251. )
  252. if end > 8:
  253. raise ValueError(
  254. "Unexpected value of interval. Interval min value needs to be <= 8."
  255. )
  256. if begin >= end:
  257. raise ValueError("Unexpected interval values order.")
  258. bits_values = sum([pow(2, i - 1) for i in range(begin, end + 1)])
  259. return img_arr & bits_values
  260. def gray_to_mscn(image):
  261. """Convert Grayscale Image into Mean Subtracted Contrast Normalized (MSCN)
  262. Args:
  263. image: grayscale image
  264. Returns:
  265. MSCN matrix obtained from transformation
  266. Usage:
  267. >>> from PIL import Image
  268. >>> from ipfml import processing
  269. >>> img = Image.open('./images/test_img.png')
  270. >>> img_mscn = processing.rgb_to_mscn(img)
  271. >>> img_mscn.shape
  272. (200, 200)
  273. """
  274. s = 7 / 6
  275. blurred = cv2.GaussianBlur(image, (7, 7),
  276. s) # apply gaussian blur to the image
  277. blurred_sq = blurred * blurred
  278. sigma = cv2.GaussianBlur(image * image, (7, 7), s)
  279. sigma = abs(sigma - blurred_sq)**0.5
  280. sigma = sigma + 1.0 / 255 # avoid DivideByZero Exception
  281. mscn = (image - blurred) / sigma # MSCN(i, j) image
  282. return mscn