data_attributes.py 16 KB

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