data_attributes.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. # main imports
  2. import numpy as np
  3. import sys
  4. # image transform imports
  5. from PIL import Image
  6. from skimage import color
  7. from sklearn.decomposition import FastICA
  8. from sklearn.decomposition import IncrementalPCA
  9. from sklearn.decomposition import TruncatedSVD
  10. from numpy.linalg import svd as lin_svd
  11. from scipy.signal import medfilt2d, wiener, cwt
  12. import pywt
  13. import cv2
  14. from ipfml.processing import transform, compression, segmentation
  15. from ipfml.filters import noise as nf
  16. from ipfml import utils
  17. # modules and config imports
  18. sys.path.insert(0, '') # trick to enable import of main folder module
  19. import custom_config as cfg
  20. from modules.utils import data as dt
  21. def get_image_features(data_type, block):
  22. """
  23. Method which returns the data type expected
  24. """
  25. if data_type == 'lab':
  26. block_file_path = '/tmp/lab_img.png'
  27. block.save(block_file_path)
  28. data = transform.get_LAB_L_SVD_s(Image.open(block_file_path))
  29. if data_type == 'mscn':
  30. img_mscn_revisited = transform.rgb_to_mscn(block)
  31. # save tmp as img
  32. img_output = Image.fromarray(img_mscn_revisited.astype('uint8'), 'L')
  33. mscn_revisited_file_path = '/tmp/mscn_revisited_img.png'
  34. img_output.save(mscn_revisited_file_path)
  35. img_block = Image.open(mscn_revisited_file_path)
  36. # extract from temp image
  37. data = compression.get_SVD_s(img_block)
  38. """if data_type == 'mscn':
  39. img_gray = np.array(color.rgb2gray(np.asarray(block))*255, 'uint8')
  40. img_mscn = transform.calculate_mscn_coefficients(img_gray, 7)
  41. img_mscn_norm = transform.normalize_2D_arr(img_mscn)
  42. img_mscn_gray = np.array(img_mscn_norm*255, 'uint8')
  43. data = compression.get_SVD_s(img_mscn_gray)
  44. """
  45. if data_type == 'low_bits_6':
  46. low_bits_6 = transform.rgb_to_LAB_L_low_bits(block, 6)
  47. data = compression.get_SVD_s(low_bits_6)
  48. if data_type == 'low_bits_5':
  49. low_bits_5 = transform.rgb_to_LAB_L_low_bits(block, 5)
  50. data = compression.get_SVD_s(low_bits_5)
  51. if data_type == 'low_bits_4':
  52. low_bits_4 = transform.rgb_to_LAB_L_low_bits(block, 4)
  53. data = compression.get_SVD_s(low_bits_4)
  54. if data_type == 'low_bits_3':
  55. low_bits_3 = transform.rgb_to_LAB_L_low_bits(block, 3)
  56. data = compression.get_SVD_s(low_bits_3)
  57. if data_type == 'low_bits_2':
  58. low_bits_2 = transform.rgb_to_LAB_L_low_bits(block, 2)
  59. data = compression.get_SVD_s(low_bits_2)
  60. if data_type == 'low_bits_4_shifted_2':
  61. data = compression.get_SVD_s(transform.rgb_to_LAB_L_bits(block, (3, 6)))
  62. if data_type == 'sub_blocks_stats':
  63. block = np.asarray(block)
  64. width, height, _= block.shape
  65. sub_width, sub_height = int(width / 4), int(height / 4)
  66. sub_blocks = segmentation.divide_in_blocks(block, (sub_width, sub_height))
  67. data = []
  68. for sub_b in sub_blocks:
  69. # by default use the whole lab L canal
  70. l_svd_data = np.array(transform.get_LAB_L_SVD_s(sub_b))
  71. # get information we want from svd
  72. data.append(np.mean(l_svd_data))
  73. data.append(np.median(l_svd_data))
  74. data.append(np.percentile(l_svd_data, 25))
  75. data.append(np.percentile(l_svd_data, 75))
  76. data.append(np.var(l_svd_data))
  77. area_under_curve = utils.integral_area_trapz(l_svd_data, dx=100)
  78. data.append(area_under_curve)
  79. # convert into numpy array after computing all stats
  80. data = np.asarray(data)
  81. if data_type == 'sub_blocks_stats_reduced':
  82. block = np.asarray(block)
  83. width, height, _= block.shape
  84. sub_width, sub_height = int(width / 4), int(height / 4)
  85. sub_blocks = segmentation.divide_in_blocks(block, (sub_width, sub_height))
  86. data = []
  87. for sub_b in sub_blocks:
  88. # by default use the whole lab L canal
  89. l_svd_data = np.array(transform.get_LAB_L_SVD_s(sub_b))
  90. # get information we want from svd
  91. data.append(np.mean(l_svd_data))
  92. data.append(np.median(l_svd_data))
  93. data.append(np.percentile(l_svd_data, 25))
  94. data.append(np.percentile(l_svd_data, 75))
  95. data.append(np.var(l_svd_data))
  96. # convert into numpy array after computing all stats
  97. data = np.asarray(data)
  98. if data_type == 'sub_blocks_area':
  99. block = np.asarray(block)
  100. width, height, _= block.shape
  101. sub_width, sub_height = int(width / 8), int(height / 8)
  102. sub_blocks = segmentation.divide_in_blocks(block, (sub_width, sub_height))
  103. data = []
  104. for sub_b in sub_blocks:
  105. # by default use the whole lab L canal
  106. l_svd_data = np.array(transform.get_LAB_L_SVD_s(sub_b))
  107. area_under_curve = utils.integral_area_trapz(l_svd_data, dx=50)
  108. data.append(area_under_curve)
  109. # convert into numpy array after computing all stats
  110. data = np.asarray(data)
  111. if data_type == 'sub_blocks_area_normed':
  112. block = np.asarray(block)
  113. width, height, _= block.shape
  114. sub_width, sub_height = int(width / 8), int(height / 8)
  115. sub_blocks = segmentation.divide_in_blocks(block, (sub_width, sub_height))
  116. data = []
  117. for sub_b in sub_blocks:
  118. # by default use the whole lab L canal
  119. l_svd_data = np.array(transform.get_LAB_L_SVD_s(sub_b))
  120. l_svd_data = utils.normalize_arr(l_svd_data)
  121. area_under_curve = utils.integral_area_trapz(l_svd_data, dx=50)
  122. data.append(area_under_curve)
  123. # convert into numpy array after computing all stats
  124. data = np.asarray(data)
  125. if data_type == 'mscn_var_4':
  126. data = _get_mscn_variance(block, (100, 100))
  127. if data_type == 'mscn_var_16':
  128. data = _get_mscn_variance(block, (50, 50))
  129. if data_type == 'mscn_var_64':
  130. data = _get_mscn_variance(block, (25, 25))
  131. if data_type == 'mscn_var_16_max':
  132. data = _get_mscn_variance(block, (50, 50))
  133. data = np.asarray(data)
  134. size = int(len(data) / 4)
  135. indices = data.argsort()[-size:][::-1]
  136. data = data[indices]
  137. if data_type == 'mscn_var_64_max':
  138. data = _get_mscn_variance(block, (25, 25))
  139. data = np.asarray(data)
  140. size = int(len(data) / 4)
  141. indices = data.argsort()[-size:][::-1]
  142. data = data[indices]
  143. if data_type == 'ica_diff':
  144. current_image = transform.get_LAB_L(block)
  145. ica = FastICA(n_components=50)
  146. ica.fit(current_image)
  147. image_ica = ica.fit_transform(current_image)
  148. image_restored = ica.inverse_transform(image_ica)
  149. final_image = utils.normalize_2D_arr(image_restored)
  150. final_image = np.array(final_image * 255, 'uint8')
  151. sv_values = utils.normalize_arr(compression.get_SVD_s(current_image))
  152. ica_sv_values = utils.normalize_arr(compression.get_SVD_s(final_image))
  153. data = abs(np.array(sv_values) - np.array(ica_sv_values))
  154. if data_type == 'svd_trunc_diff':
  155. current_image = transform.get_LAB_L(block)
  156. svd = TruncatedSVD(n_components=30, n_iter=100, random_state=42)
  157. transformed_image = svd.fit_transform(current_image)
  158. restored_image = svd.inverse_transform(transformed_image)
  159. reduced_image = (current_image - restored_image)
  160. U, s, V = compression.get_SVD(reduced_image)
  161. data = s
  162. if data_type == 'ipca_diff':
  163. current_image = transform.get_LAB_L(block)
  164. transformer = IncrementalPCA(n_components=20, batch_size=25)
  165. transformed_image = transformer.fit_transform(current_image)
  166. restored_image = transformer.inverse_transform(transformed_image)
  167. reduced_image = (current_image - restored_image)
  168. U, s, V = compression.get_SVD(reduced_image)
  169. data = s
  170. if data_type == 'svd_reconstruct':
  171. reconstructed_interval = (90, 200)
  172. begin, end = reconstructed_interval
  173. lab_img = transform.get_LAB_L(block)
  174. lab_img = np.array(lab_img, 'uint8')
  175. U, s, V = lin_svd(lab_img, full_matrices=True)
  176. smat = np.zeros((end-begin, end-begin), dtype=complex)
  177. smat[:, :] = np.diag(s[begin:end])
  178. output_img = np.dot(U[:, begin:end], np.dot(smat, V[begin:end, :]))
  179. output_img = np.array(output_img, 'uint8')
  180. data = compression.get_SVD_s(output_img)
  181. if 'sv_std_filters' in data_type:
  182. # convert into lab by default to apply filters
  183. lab_img = transform.get_LAB_L(block)
  184. arr = np.array(lab_img)
  185. images = []
  186. # Apply list of filter on arr
  187. images.append(medfilt2d(arr, [3, 3]))
  188. images.append(medfilt2d(arr, [5, 5]))
  189. images.append(wiener(arr, [3, 3]))
  190. images.append(wiener(arr, [5, 5]))
  191. # By default computation of current block image
  192. s_arr = compression.get_SVD_s(arr)
  193. sv_vector = [s_arr]
  194. # for each new image apply SVD and get SV
  195. for img in images:
  196. s = compression.get_SVD_s(img)
  197. sv_vector.append(s)
  198. sv_array = np.array(sv_vector)
  199. _, len = sv_array.shape
  200. sv_std = []
  201. # normalize each SV vectors and compute standard deviation for each sub vectors
  202. for i in range(len):
  203. sv_array[:, i] = utils.normalize_arr(sv_array[:, i])
  204. sv_std.append(np.std(sv_array[:, i]))
  205. indices = []
  206. if 'lowest' in data_type:
  207. indices = utils.get_indices_of_lowest_values(sv_std, 200)
  208. if 'highest' in data_type:
  209. indices = utils.get_indices_of_highest_values(sv_std, 200)
  210. # data are arranged following std trend computed
  211. data = s_arr[indices]
  212. # with the use of wavelet
  213. if 'wave_sv_std_filters' in data_type:
  214. # convert into lab by default to apply filters
  215. lab_img = transform.get_LAB_L(block)
  216. arr = np.array(lab_img)
  217. images = []
  218. # Apply list of filter on arr
  219. images.append(medfilt2d(arr, [3, 3]))
  220. # By default computation of current block image
  221. s_arr = compression.get_SVD_s(arr)
  222. sv_vector = [s_arr]
  223. # for each new image apply SVD and get SV
  224. for img in images:
  225. s = compression.get_SVD_s(img)
  226. sv_vector.append(s)
  227. sv_array = np.array(sv_vector)
  228. _, len = sv_array.shape
  229. sv_std = []
  230. # normalize each SV vectors and compute standard deviation for each sub vectors
  231. for i in range(len):
  232. sv_array[:, i] = utils.normalize_arr(sv_array[:, i])
  233. sv_std.append(np.std(sv_array[:, i]))
  234. indices = []
  235. if 'lowest' in data_type:
  236. indices = utils.get_indices_of_lowest_values(sv_std, 200)
  237. if 'highest' in data_type:
  238. indices = utils.get_indices_of_highest_values(sv_std, 200)
  239. # data are arranged following std trend computed
  240. data = s_arr[indices]
  241. # with the use of wavelet
  242. if 'sv_std_filters_full' in data_type:
  243. # convert into lab by default to apply filters
  244. lab_img = transform.get_LAB_L(block)
  245. arr = np.array(lab_img)
  246. images = []
  247. # Apply list of filter on arr
  248. kernel = np.ones((3,3),np.float32)/9
  249. images.append(cv2.filter2D(arr,-1,kernel))
  250. kernel = np.ones((5,5),np.float32)/25
  251. images.append(cv2.filter2D(arr,-1,kernel))
  252. images.append(cv2.GaussianBlur(arr, (3, 3), 0.5))
  253. images.append(cv2.GaussianBlur(arr, (3, 3), 1))
  254. images.append(cv2.GaussianBlur(arr, (3, 3), 1.5))
  255. images.append(cv2.GaussianBlur(arr, (5, 5), 0.5))
  256. images.append(cv2.GaussianBlur(arr, (5, 5), 1))
  257. images.append(cv2.GaussianBlur(arr, (5, 5), 1.5))
  258. images.append(medfilt2d(arr, [3, 3]))
  259. images.append(medfilt2d(arr, [5, 5]))
  260. images.append(wiener(arr, [3, 3]))
  261. images.append(wiener(arr, [5, 5]))
  262. wave = w2d(arr, 'db1', 2)
  263. images.append(np.array(wave, 'float64'))
  264. # By default computation of current block image
  265. s_arr = compression.get_SVD_s(arr)
  266. sv_vector = [s_arr]
  267. # for each new image apply SVD and get SV
  268. for img in images:
  269. s = compression.get_SVD_s(img)
  270. sv_vector.append(s)
  271. sv_array = np.array(sv_vector)
  272. _, length = sv_array.shape
  273. sv_std = []
  274. # normalize each SV vectors and compute standard deviation for each sub vectors
  275. for i in range(length):
  276. sv_array[:, i] = utils.normalize_arr(sv_array[:, i])
  277. sv_std.append(np.std(sv_array[:, i]))
  278. indices = []
  279. if 'lowest' in data_type:
  280. indices = utils.get_indices_of_lowest_values(sv_std, 200)
  281. if 'highest' in data_type:
  282. indices = utils.get_indices_of_highest_values(sv_std, 200)
  283. # data are arranged following std trend computed
  284. data = s_arr[indices]
  285. if 'sv_entropy_std_filters' in data_type:
  286. lab_img = transform.get_LAB_L(block)
  287. arr = np.array(lab_img)
  288. images = []
  289. kernel = np.ones((3,3),np.float32)/9
  290. images.append(cv2.filter2D(arr,-1,kernel))
  291. kernel = np.ones((5,5),np.float32)/25
  292. images.append(cv2.filter2D(arr,-1,kernel))
  293. images.append(cv2.GaussianBlur(arr, (3, 3), 0.5))
  294. images.append(cv2.GaussianBlur(arr, (3, 3), 1))
  295. images.append(cv2.GaussianBlur(arr, (3, 3), 1.5))
  296. images.append(cv2.GaussianBlur(arr, (5, 5), 0.5))
  297. images.append(cv2.GaussianBlur(arr, (5, 5), 1))
  298. images.append(cv2.GaussianBlur(arr, (5, 5), 1.5))
  299. images.append(medfilt2d(arr, [3, 3]))
  300. images.append(medfilt2d(arr, [5, 5]))
  301. images.append(wiener(arr, [3, 3]))
  302. images.append(wiener(arr, [5, 5]))
  303. wave = w2d(arr, 'db1', 2)
  304. images.append(np.array(wave, 'float64'))
  305. sv_vector = []
  306. sv_entropy_list = []
  307. # for each new image apply SVD and get SV
  308. for img in images:
  309. s = compression.get_SVD_s(img)
  310. sv_vector.append(s)
  311. sv_entropy = [utils.get_entropy_contribution_of_i(s, id_sv) for id_sv, sv in enumerate(s)]
  312. sv_entropy_list.append(sv_entropy)
  313. sv_std = []
  314. sv_array = np.array(sv_vector)
  315. _, length = sv_array.shape
  316. # normalize each SV vectors and compute standard deviation for each sub vectors
  317. for i in range(length):
  318. sv_array[:, i] = utils.normalize_arr(sv_array[:, i])
  319. sv_std.append(np.std(sv_array[:, i]))
  320. indices = []
  321. if 'lowest' in data_type:
  322. indices = utils.get_indices_of_lowest_values(sv_std, 200)
  323. if 'highest' in data_type:
  324. indices = utils.get_indices_of_highest_values(sv_std, 200)
  325. # data are arranged following std trend computed
  326. s_arr = compression.get_SVD_s(arr)
  327. data = s_arr[indices]
  328. return data
  329. def get_noise_result(_image, _n, _noise_choice, _identical=False, _p=None):
  330. """Return image with applied noise using choice
  331. Args:
  332. image: image to convert
  333. _n: importance of noise expected [1, 999]
  334. _noise_choice: choise of noise filter to apply
  335. _identical: specify if the distribution is the same or not for each chanel
  336. _p: optional parameter for salt_pepper noise
  337. Returns:
  338. Noisy image with noise filter applied
  339. """
  340. noise_method = None
  341. function_name = _noise_choice + '_noise'
  342. try:
  343. noise_method = getattr(nf, function_name)
  344. except AttributeError:
  345. raise NotImplementedError("Noise filter `{}` not implement `{}`".format(nf.__name__, function_name))
  346. if _p:
  347. if _noise_choice != 'salt_pepper':
  348. raise ValueError("p parameter is only used for salt pepper noise...")
  349. return noise_method(_image, _n, identical=_identical, p=_p)
  350. else:
  351. return noise_method(_image, _n, identical=_identical)
  352. # others functions
  353. def w2d(arr, mode='haar', level=1):
  354. #convert to float
  355. imArray = arr
  356. np.divide(imArray, 255)
  357. # compute coefficients
  358. coeffs=pywt.wavedec2(imArray, mode, level=level)
  359. #Process Coefficients
  360. coeffs_H=list(coeffs)
  361. coeffs_H[0] *= 0
  362. # reconstruction
  363. imArray_H = pywt.waverec2(coeffs_H, mode)
  364. imArray_H *= 255
  365. imArray_H = np.uint8(imArray_H)
  366. return imArray_H
  367. def _get_mscn_variance(block, sub_block_size=(50, 50)):
  368. blocks = segmentation.divide_in_blocks(block, sub_block_size)
  369. data = []
  370. for block in blocks:
  371. mscn_coefficients = transform.get_mscn_coefficients(block)
  372. flat_coeff = mscn_coefficients.flatten()
  373. data.append(np.var(flat_coeff))
  374. return np.sort(data)