metrics.py 8.4 KB

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