image_processing.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. from PIL import Image
  2. from matplotlib import cm
  3. import numpy as np
  4. import ipfml.metrics as metrics
  5. def fig2data(fig):
  6. """
  7. @brief Convert a Matplotlib figure to a 3D numpy array with RGB channels and return it
  8. @param fig a matplotlib figure
  9. @return a numpy 3D array of RGB values
  10. """
  11. # draw the renderer
  12. fig.canvas.draw()
  13. # Get the RGBA buffer from the figure
  14. w,h = fig.canvas.get_width_height()
  15. buf = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8)
  16. buf.shape = (w, h, 3)
  17. # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
  18. buf = np.roll(buf, 3, axis=2)
  19. return buf
  20. def fig2img(fig):
  21. """
  22. @brief Convert a Matplotlib figure to a PIL Image in RGB format and return it
  23. @param fig a matplotlib figure
  24. @return a Python Imaging Library (PIL) image : default size (480,640,3)
  25. """
  26. # put the figure pixmap into a numpy array
  27. buf = fig2data(fig)
  28. w, h, d = buf.shape
  29. return Image.frombytes("RGB", (w, h), buf.tostring())
  30. def get_LAB_L_SVD(image):
  31. """
  32. @brief Returns Singular values from LAB L Image information
  33. @param fig a matplotlib figure
  34. @return a Python Imaging Library (PIL) image : default size (480,640,3)
  35. Usage :
  36. >>> from PIL import Image
  37. >>> from ipfml import image_processing
  38. >>> img = Image.open('./images/test_img.png')
  39. >>> U, s, V = image_processing.get_LAB_L_SVD(img)
  40. >>> U.shape
  41. (200, 200)
  42. >>> len(s)
  43. 200
  44. >>> V.shape
  45. (200, 200)
  46. """
  47. L = metrics.get_LAB_L(image)
  48. return metrics.get_SVD(L)
  49. def get_LAB_L_SVD_s(image):
  50. """
  51. @brief Returns s (Singular values) SVD from L of LAB Image information
  52. @param PIL Image
  53. @return vector of singular values
  54. Usage :
  55. >>> from PIL import Image
  56. >>> from ipfml import image_processing
  57. >>> img = Image.open('./images/test_img.png')
  58. >>> s = image_processing.get_LAB_L_SVD_s(img)
  59. >>> len(s)
  60. 200
  61. """
  62. L = metrics.get_LAB_L(image)
  63. return metrics.get_SVD_s(L)
  64. def get_LAB_L_SVD_U(image):
  65. """
  66. @brief Returns U SVD from L of LAB Image information
  67. @param PIL Image
  68. @return vector of singular values
  69. Usage :
  70. >>> from PIL import Image
  71. >>> from ipfml import image_processing
  72. >>> img = Image.open('./images/test_img.png')
  73. >>> U = image_processing.get_LAB_L_SVD_U(img)
  74. >>> U.shape
  75. (200, 200)
  76. """
  77. L = metrics.get_LAB_L(image)
  78. return metrics.get_SVD_U(L)
  79. def get_LAB_L_SVD_V(image):
  80. """
  81. @brief Returns V SVD from L of LAB Image information
  82. @param PIL Image
  83. @return vector of singular values
  84. Usage :
  85. >>> from PIL import Image
  86. >>> from ipfml import image_processing
  87. >>> img = Image.open('./images/test_img.png')
  88. >>> V = image_processing.get_LAB_L_SVD_V(img)
  89. >>> V.shape
  90. (200, 200)
  91. """
  92. L = metrics.get_LAB_L(image)
  93. return metrics.get_SVD_V(L)
  94. def divide_in_blocks(image, block_size):
  95. '''
  96. @brief Divide image into equal size blocks
  97. @param img - PIL Image or numpy array
  98. @param block - tuple (width, height) representing the size of each dimension of the block
  99. @return list containing all PIL Image block (in RGB)
  100. Usage :
  101. >>> import numpy as np
  102. >>> from PIL import Image
  103. >>> from ipfml import image_processing
  104. >>> from ipfml import metrics
  105. >>> image_values = np.random.randint(255, size=(800, 800, 3))
  106. >>> blocks = divide_in_blocks(image_values, (20, 20))
  107. >>> len(blocks)
  108. 1600
  109. >>> blocks[0].width
  110. 20
  111. >>> blocks[0].height
  112. 20
  113. >>> img_l = Image.open('./images/test_img.png')
  114. >>> L = metrics.get_LAB_L(img_l)
  115. >>> blocks_L = divide_in_blocks(L, (100, 100))
  116. >>> len(blocks_L)
  117. 4
  118. >>> blocks_L[0].width
  119. 100
  120. '''
  121. blocks = []
  122. mode = 'RGB'
  123. # check input type (PIL Image or numpy array)
  124. if type(image) is Image:
  125. image_array = np.array(image)
  126. image_width = image.width
  127. image_height = image.height
  128. else:
  129. image_array = image
  130. if image.ndim != 3:
  131. mode = 'L'
  132. image_width, image_height = image.shape
  133. else:
  134. image_width, image_height, _ = image.shape
  135. # check size compatibility
  136. width, height = block_size
  137. if(image_width % width != 0):
  138. raise "Width size issue, block size not compatible"
  139. if(image_height % height != 0):
  140. raise "Height size issue, block size not compatible"
  141. nb_block_width = image_width / width
  142. nb_block_height = image_height / height
  143. for i in range(int(nb_block_width)):
  144. begin_x = i * width
  145. for j in range(int(nb_block_height)):
  146. begin_y = j * height
  147. # getting sub block information
  148. current_block = image_array[begin_x:(begin_x + width), begin_y:(begin_y + height)]
  149. blocks.append(Image.fromarray(current_block.astype('uint8'), mode))
  150. return blocks