processing.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. from PIL import Image
  2. from matplotlib import cm
  3. import random
  4. from skimage import color
  5. import numpy as np
  6. import ipfml.metrics as metrics
  7. import cv2
  8. from scipy import signal
  9. def get_LAB_L_SVD(image):
  10. """Returns Singular values from LAB L Image information
  11. Args:
  12. image: PIL Image or Numpy array
  13. Returns:
  14. U, s, V information obtained from SVD compression using Lab
  15. Example:
  16. >>> from PIL import Image
  17. >>> from ipfml import processing
  18. >>> img = Image.open('./images/test_img.png')
  19. >>> U, s, V = processing.get_LAB_L_SVD(img)
  20. >>> U.shape
  21. (200, 200)
  22. >>> len(s)
  23. 200
  24. >>> V.shape
  25. (200, 200)
  26. """
  27. L = metrics.get_LAB_L(image)
  28. return metrics.get_SVD(L)
  29. def get_LAB_L_SVD_s(image):
  30. """Returns s (Singular values) SVD from L of LAB Image information
  31. Args:
  32. image: PIL Image or Numpy array
  33. Returns:
  34. vector of singular values
  35. Example:
  36. >>> from PIL import Image
  37. >>> from ipfml import processing
  38. >>> img = Image.open('./images/test_img.png')
  39. >>> s = processing.get_LAB_L_SVD_s(img)
  40. >>> len(s)
  41. 200
  42. """
  43. L = metrics.get_LAB_L(image)
  44. return metrics.get_SVD_s(L)
  45. def get_LAB_L_SVD_U(image):
  46. """Returns U SVD from L of LAB Image information
  47. Args:
  48. image: PIL Image or Numpy array
  49. Returns:
  50. U matrix of SVD compression
  51. Example:
  52. >>> from PIL import Image
  53. >>> from ipfml import processing
  54. >>> img = Image.open('./images/test_img.png')
  55. >>> U = processing.get_LAB_L_SVD_U(img)
  56. >>> U.shape
  57. (200, 200)
  58. """
  59. L = metrics.get_LAB_L(image)
  60. return metrics.get_SVD_U(L)
  61. def get_LAB_L_SVD_V(image):
  62. """Returns V SVD from L of LAB Image information
  63. Args:
  64. image: PIL Image or Numpy array
  65. Returns:
  66. V matrix of SVD compression
  67. Example:
  68. >>> from PIL import Image
  69. >>> from ipfml import processing
  70. >>> img = Image.open('./images/test_img.png')
  71. >>> V = processing.get_LAB_L_SVD_V(img)
  72. >>> V.shape
  73. (200, 200)
  74. """
  75. L = metrics.get_LAB_L(image)
  76. return metrics.get_SVD_V(L)
  77. def divide_in_blocks(image, block_size, pil=True):
  78. '''Divide image into equal size blocks
  79. Args:
  80. image: PIL Image or Numpy array
  81. block: tuple (width, height) representing the size of each dimension of the block
  82. pil: block type returned (default True)
  83. Returns:
  84. list containing all 2D Numpy blocks (in RGB or not)
  85. Raises:
  86. ValueError: If `image_width` or `image_heigt` are not compatible to produce correct block sizes
  87. Example:
  88. >>> import numpy as np
  89. >>> from PIL import Image
  90. >>> from ipfml import processing
  91. >>> from ipfml import metrics
  92. >>> image_values = np.random.randint(255, size=(800, 800, 3))
  93. >>> blocks = divide_in_blocks(image_values, (20, 20))
  94. >>> len(blocks)
  95. 1600
  96. >>> blocks[0].width
  97. 20
  98. >>> blocks[0].height
  99. 20
  100. >>> img_l = Image.open('./images/test_img.png')
  101. >>> L = metrics.get_LAB_L(img_l)
  102. >>> blocks_L = divide_in_blocks(L, (100, 100))
  103. >>> len(blocks_L)
  104. 4
  105. >>> blocks_L[0].width
  106. 100
  107. '''
  108. blocks = []
  109. mode = 'RGB'
  110. # convert in Numpy array
  111. image_array = np.array(image)
  112. # check dimension of input image
  113. if image_array.ndim != 3:
  114. mode = 'L'
  115. image_width, image_height = image_array.shape
  116. else:
  117. image_width, image_height, _ = image_array.shape
  118. # check size compatibility
  119. width, height = block_size
  120. if (image_width % width != 0):
  121. raise ValueError("Width size issue, block size not compatible")
  122. if (image_height % height != 0):
  123. raise ValueError("Height size issue, block size not compatible")
  124. nb_block_width = image_width / width
  125. nb_block_height = image_height / height
  126. for i in range(int(nb_block_width)):
  127. begin_x = i * width
  128. for j in range(int(nb_block_height)):
  129. begin_y = j * height
  130. # getting sub block information
  131. current_block = image_array[begin_x:(begin_x + width), begin_y:(
  132. begin_y + height)]
  133. if pil:
  134. blocks.append(
  135. Image.fromarray(current_block.astype('uint8'), mode))
  136. else:
  137. blocks.append(current_block)
  138. return blocks
  139. def rgb_to_mscn(image):
  140. """Convert RGB Image into Mean Subtracted Contrast Normalized (MSCN)
  141. Args:
  142. image: 3D RGB image Numpy array or PIL RGB image
  143. Returns:
  144. 2D Numpy array with MSCN information
  145. Example:
  146. >>> from PIL import Image
  147. >>> from ipfml import processing
  148. >>> img = Image.open('./images/test_img.png')
  149. >>> img_mscn = processing.rgb_to_mscn(img)
  150. >>> img_mscn.shape
  151. (200, 200)
  152. """
  153. # check if PIL image or not
  154. img_arr = np.array(image)
  155. # convert rgb image to gray
  156. im = np.array(color.rgb2gray(img_arr) * 255, 'uint8')
  157. return metrics.gray_to_mscn(im)
  158. def rgb_to_grey_low_bits(image, nb_bits=4):
  159. """Convert RGB Image into grey image using only 4 low bits values
  160. Args:
  161. image: 3D RGB image Numpy array or PIL RGB image
  162. nb_bits: optional parameter which indicates the number of bits to keep (default 4)
  163. Returns:
  164. 2D Numpy array with low bits information kept
  165. Example:
  166. >>> from PIL import Image
  167. >>> from ipfml import processing
  168. >>> img = Image.open('./images/test_img.png')
  169. >>> low_bits_grey_img = processing.rgb_to_grey_low_bits(img, 5)
  170. >>> low_bits_grey_img.shape
  171. (200, 200)
  172. """
  173. img_arr = np.array(image)
  174. grey_block = np.array(color.rgb2gray(img_arr) * 255, 'uint8')
  175. return metrics.get_low_bits_img(grey_block, nb_bits)
  176. def rgb_to_LAB_L_low_bits(image, nb_bits=4):
  177. """Convert RGB Image into Lab L channel image using only 4 low bits values
  178. Args:
  179. image: 3D RGB image Numpy array or PIL RGB image
  180. nb_bits: optional parameter which indicates the number of bits to keep (default 4)
  181. Returns:
  182. 2D Numpy array with low bits information kept
  183. Example:
  184. >>> from PIL import Image
  185. >>> from ipfml import processing
  186. >>> img = Image.open('./images/test_img.png')
  187. >>> low_bits_Lab_l_img = processing.rgb_to_LAB_L_low_bits(img, 5)
  188. >>> low_bits_Lab_l_img.shape
  189. (200, 200)
  190. """
  191. L_block = np.asarray(metrics.get_LAB_L(image), 'uint8')
  192. return metrics.get_low_bits_img(L_block, nb_bits)
  193. def rgb_to_LAB_L_bits(image, interval):
  194. """Returns only bits from LAB L canal specified into the interval
  195. Args:
  196. image: image to convert using this interval of bits value to keep
  197. interval: (begin, end) of bits values
  198. Returns:
  199. 2D Numpy array with reduced values
  200. >>> from PIL import Image
  201. >>> from ipfml import processing
  202. >>> img = Image.open('./images/test_img.png')
  203. >>> bits_Lab_l_img = processing.rgb_to_LAB_L_bits(img, (2, 6))
  204. >>> bits_Lab_l_img.shape
  205. (200, 200)
  206. """
  207. L_block = np.asarray(metrics.get_LAB_L(image), 'uint8')
  208. return metrics.get_bits_img(L_block, interval)