processing.py 7.0 KB

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