data_attributes.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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_svd_data(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. _, len = sv_array.shape
  272. sv_std = []
  273. # normalize each SV vectors and compute standard deviation for each sub vectors
  274. for i in range(len):
  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 'filters_statistics' in data_type:
  285. img_width, img_height = 200, 200
  286. lab_img = transform.get_LAB_L(block)
  287. arr = np.array(lab_img)
  288. # compute all filters statistics
  289. def get_stats(arr, I_filter):
  290. e1 = np.abs(arr - I_filter)
  291. L = np.array(e1)
  292. mu0 = np.mean(L)
  293. A = L - mu0
  294. H = A * A
  295. E = np.sum(H) / (img_width * img_height)
  296. P = np.sqrt(E)
  297. return mu0, P
  298. stats = []
  299. kernel = np.ones((3,3),np.float32)/9
  300. stats.append(get_stats(arr, cv2.filter2D(arr,-1,kernel)))
  301. kernel = np.ones((5,5),np.float32)/25
  302. stats.append(get_stats(arr, cv2.filter2D(arr,-1,kernel)))
  303. stats.append(get_stats(arr, cv2.GaussianBlur(arr, (3, 3), 0.5)))
  304. stats.append(get_stats(arr, cv2.GaussianBlur(arr, (3, 3), 1)))
  305. stats.append(get_stats(arr, cv2.GaussianBlur(arr, (3, 3), 1.5)))
  306. stats.append(get_stats(arr, cv2.GaussianBlur(arr, (5, 5), 0.5)))
  307. stats.append(get_stats(arr, cv2.GaussianBlur(arr, (5, 5), 1)))
  308. stats.append(get_stats(arr, cv2.GaussianBlur(arr, (5, 5), 1.5)))
  309. stats.append(get_stats(arr, medfilt2d(arr, [3, 3])))
  310. stats.append(get_stats(arr, medfilt2d(arr, [5, 5])))
  311. stats.append(get_stats(arr, wiener(arr, [3, 3])))
  312. stats.append(get_stats(arr, wiener(arr, [5, 5])))
  313. wave = w2d(arr, 'db1', 2)
  314. stats.append(get_stats(arr, np.array(wave, 'float64')))
  315. data = []
  316. for stat in stats:
  317. data.append(stat[0])
  318. for stat in stats:
  319. data.append(stat[1])
  320. data = np.array(data)
  321. return data
  322. def w2d(arr, mode='haar', level=1):
  323. #convert to float
  324. imArray = arr
  325. np.divide(imArray, 255)
  326. # compute coefficients
  327. coeffs=pywt.wavedec2(imArray, mode, level=level)
  328. #Process Coefficients
  329. coeffs_H=list(coeffs)
  330. coeffs_H[0] *= 0
  331. # reconstruction
  332. imArray_H = pywt.waverec2(coeffs_H, mode)
  333. imArray_H *= 255
  334. imArray_H = np.uint8(imArray_H)
  335. return imArray_H
  336. def _get_mscn_variance(block, sub_block_size=(50, 50)):
  337. blocks = segmentation.divide_in_blocks(block, sub_block_size)
  338. data = []
  339. for block in blocks:
  340. mscn_coefficients = transform.get_mscn_coefficients(block)
  341. flat_coeff = mscn_coefficients.flatten()
  342. data.append(np.var(flat_coeff))
  343. return np.sort(data)