processing.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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 normalize_arr(arr):
  140. '''Normalize data of 1D array shape
  141. Args:
  142. arr: array data of 1D shape
  143. Returns:
  144. Normalized 1D array
  145. Example:
  146. >>> from ipfml import processing
  147. >>> import numpy as np
  148. >>> arr = np.arange(11)
  149. >>> arr_normalized = processing.normalize_arr(arr)
  150. >>> arr_normalized[1]
  151. 0.1
  152. '''
  153. output_arr = []
  154. max_value = max(arr)
  155. min_value = min(arr)
  156. for v in arr:
  157. output_arr.append((v - min_value) / (max_value - min_value))
  158. return output_arr
  159. def normalize_arr_with_range(arr, min, max):
  160. '''Normalize data of 1D array shape
  161. Args:
  162. arr: array data of 1D shape
  163. Returns:
  164. Normalized 1D Numpy array
  165. Example:
  166. >>> from ipfml import processing
  167. >>> import numpy as np
  168. >>> arr = np.arange(11)
  169. >>> arr_normalized = processing.normalize_arr_with_range(arr, 0, 20)
  170. >>> arr_normalized[1]
  171. 0.05
  172. '''
  173. output_arr = []
  174. for v in arr:
  175. output_arr.append((v - min) / (max - min))
  176. return output_arr
  177. def normalize_2D_arr(arr):
  178. """Return array normalize from its min and max values
  179. Args:
  180. arr: 2D Numpy array
  181. Returns:
  182. Normalized 2D Numpy array
  183. Example:
  184. >>> from PIL import Image
  185. >>> from ipfml import processing
  186. >>> img = Image.open('./images/test_img.png')
  187. >>> img_mscn = processing.rgb_to_mscn(img)
  188. >>> img_normalized = processing.normalize_2D_arr(img_mscn)
  189. >>> img_normalized.shape
  190. (200, 200)
  191. """
  192. # getting min and max value from 2D array
  193. max_value = arr.max(axis=1).max()
  194. min_value = arr.min(axis=1).min()
  195. # normalize each row
  196. output_array = []
  197. width, height = arr.shape
  198. for row_index in range(0, height):
  199. values = arr[row_index, :]
  200. output_array.append(
  201. normalize_arr_with_range(values, min_value, max_value))
  202. return np.asarray(output_array)
  203. def rgb_to_mscn(image):
  204. """Convert RGB Image into Mean Subtracted Contrast Normalized (MSCN)
  205. Args:
  206. image: 3D RGB image Numpy array or PIL RGB image
  207. Returns:
  208. 2D Numpy array with MSCN information
  209. Example:
  210. >>> from PIL import Image
  211. >>> from ipfml import processing
  212. >>> img = Image.open('./images/test_img.png')
  213. >>> img_mscn = processing.rgb_to_mscn(img)
  214. >>> img_mscn.shape
  215. (200, 200)
  216. """
  217. # check if PIL image or not
  218. img_arr = np.array(image)
  219. # convert rgb image to gray
  220. im = np.array(color.rgb2gray(img_arr) * 255, 'uint8')
  221. return metrics.gray_to_mscn(im)
  222. def rgb_to_grey_low_bits(image, nb_bits=4):
  223. """Convert RGB Image into grey image using only 4 low bits values
  224. Args:
  225. image: 3D RGB image Numpy array or PIL RGB image
  226. nb_bits: optional parameter which indicates the number of bits to keep (default 4)
  227. Returns:
  228. 2D Numpy array with low bits information kept
  229. Example:
  230. >>> from PIL import Image
  231. >>> from ipfml import processing
  232. >>> img = Image.open('./images/test_img.png')
  233. >>> low_bits_grey_img = processing.rgb_to_grey_low_bits(img, 5)
  234. >>> low_bits_grey_img.shape
  235. (200, 200)
  236. """
  237. img_arr = np.array(image)
  238. grey_block = np.array(color.rgb2gray(img_arr) * 255, 'uint8')
  239. return metrics.get_low_bits_img(grey_block, nb_bits)
  240. def rgb_to_LAB_L_low_bits(image, nb_bits=4):
  241. """Convert RGB Image into Lab L channel image using only 4 low bits values
  242. Args:
  243. image: 3D RGB image Numpy array or PIL RGB image
  244. nb_bits: optional parameter which indicates the number of bits to keep (default 4)
  245. Returns:
  246. 2D Numpy array with low bits information kept
  247. Example:
  248. >>> from PIL import Image
  249. >>> from ipfml import processing
  250. >>> img = Image.open('./images/test_img.png')
  251. >>> low_bits_Lab_l_img = processing.rgb_to_LAB_L_low_bits(img, 5)
  252. >>> low_bits_Lab_l_img.shape
  253. (200, 200)
  254. """
  255. L_block = np.asarray(metrics.get_LAB_L(image), 'uint8')
  256. return metrics.get_low_bits_img(L_block, nb_bits)
  257. def rgb_to_LAB_L_bits(image, interval):
  258. """Returns only bits from LAB L canal specified into the interval
  259. Args:
  260. image: image to convert using this interval of bits value to keep
  261. interval: (begin, end) of bits values
  262. Returns:
  263. 2D Numpy array with reduced values
  264. >>> from PIL import Image
  265. >>> from ipfml import processing
  266. >>> img = Image.open('./images/test_img.png')
  267. >>> bits_Lab_l_img = processing.rgb_to_LAB_L_bits(img, (2, 6))
  268. >>> bits_Lab_l_img.shape
  269. (200, 200)
  270. """
  271. L_block = np.asarray(metrics.get_LAB_L(image), 'uint8')
  272. return metrics.get_bits_img(L_block, interval)