extract_expe_info_subject_zones.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. # main imports
  2. import sys, os, argparse
  3. import math
  4. import numpy as np
  5. import pickle
  6. import time
  7. # processing imports
  8. from PIL import Image
  9. import matplotlib.pyplot as plt
  10. import scipy.stats as stats
  11. # modules imports
  12. sys.path.insert(0, '') # trick to enable import of main folder module
  13. import custom_config as cfg
  14. import utils as utils_functions
  15. # variables
  16. data_expe_folder = cfg.data_expe_folder
  17. position_file_pattern = cfg.position_file_pattern
  18. click_line_pattern = cfg.click_line_pattern
  19. min_x = cfg.min_x_coordinate
  20. min_y = cfg.min_y_coordinate
  21. image_scene_size = cfg.image_scene_size
  22. scene_width, scene_height = image_scene_size
  23. def main():
  24. parser = argparse.ArgumentParser(description="Compute expe data into output file")
  25. parser.add_argument('--n', type=int, help="`n` first clicks", required=True)
  26. parser.add_argument('--folder', type=str, help="output folder expected", required=True)
  27. parser.add_argument('--reverse', type=int, help="reverse or not y axis clicks", default=False)
  28. args = parser.parse_args()
  29. p_n = args.n
  30. p_folder = args.folder
  31. p_reverse = bool(args.reverse)
  32. print(p_reverse)
  33. # list all folders
  34. subjects = os.listdir(data_expe_folder)
  35. print('Number of subjects', len(subjects))
  36. output_folder_path = os.path.join(cfg.media_data_folder, p_folder)
  37. if not os.path.exists(output_folder_path):
  38. os.makedirs(output_folder_path)
  39. # keep scene_data in memory
  40. scenes_data = {}
  41. for scene in cfg.scenes_names:
  42. zones_list = {}
  43. for zone_index in cfg.zones_indices:
  44. zones_list[zone_index] = {}
  45. # construct for each scene
  46. zones_list[zone_index]['x'] = []
  47. zones_list[zone_index]['y'] = []
  48. scenes_data[scene] = zones_list
  49. for _, subject in enumerate(subjects):
  50. subject_folder = os.path.join(data_expe_folder, subject)
  51. data_files = os.listdir(subject_folder)
  52. pos_file = [f for f in data_files if position_file_pattern in f][0]
  53. pos_filepath = os.path.join(subject_folder, pos_file)
  54. previous_path_scene = ""
  55. path_scene = ""
  56. new_scene = True
  57. number_of_scenes = 0
  58. scene_name = ""
  59. print('Extract images clicks of subject', subject)
  60. # open pos file and extract click information
  61. with open(pos_filepath, 'r') as f:
  62. # for each subject check `p_n` on each zone
  63. zones_filled = {}
  64. zones_clicks_of_subject = {}
  65. for zone_index in cfg.zones_indices:
  66. zones_filled[zone_index] = 0
  67. zones_clicks_of_subject[zone_index] = {}
  68. zones_clicks_of_subject[zone_index]['x'] = []
  69. zones_clicks_of_subject[zone_index]['y'] = []
  70. for line in f.readlines():
  71. if click_line_pattern in line and scene_name in cfg.scenes_names:
  72. x, y = utils_functions.extract_click_coordinate(line)
  73. p_x = x - min_x
  74. p_y = y - min_y
  75. # only accept valid coordinates (need to substract `x_min` and `y_min` before check)
  76. if utils_functions.check_coordinates(p_x, p_y):
  77. if p_reverse:
  78. # add reversed points here
  79. p_y = scene_height - p_y
  80. # get zone indice
  81. zone_index = utils_functions.get_zone_index(p_x, p_y)
  82. # check number of points saved for this specific zone
  83. # add only if wished
  84. if zones_filled[zone_index] < p_n:
  85. zones_clicks_of_subject[zone_index]['x'].append(p_x)
  86. zones_clicks_of_subject[zone_index]['y'].append(p_y)
  87. zones_filled[zone_index] += 1
  88. elif click_line_pattern not in line:
  89. path_scene = line
  90. if previous_path_scene != path_scene:
  91. previous_path_scene = path_scene
  92. new_scene = True
  93. scene_name = path_scene.split('/')[4]
  94. if scene_name in cfg.scenes_names:
  95. number_of_scenes += 1
  96. if previous_path_scene != "":
  97. subject_path = os.path.join(output_folder_path, subject)
  98. if not os.path.exists(subject_path):
  99. os.makedirs(subject_path)
  100. output_image_name = subject + '_' + scene_name + '_' + str(p_n) + '.png'
  101. img_path = os.path.join(subject_path, output_image_name)
  102. title = subject + ' - ' + scene_name + ' (' + str(p_n) + ' clicks)'
  103. x_points = []
  104. y_points = []
  105. for zone_index in cfg.zones_indices:
  106. # save image plot
  107. x_points = x_points + zones_clicks_of_subject[zone_index]['x']
  108. y_points = y_points + zones_clicks_of_subject[zone_index]['y']
  109. utils_functions.save_img_plot(scene_name, x_points, y_points, title, img_path)
  110. # save scene data
  111. for i in cfg.zones_indices:
  112. scenes_data[scene_name][i]['x'] = scenes_data[scene_name][i]['x'] + x_points
  113. scenes_data[scene_name][i]['y'] = scenes_data[scene_name][i]['y'] + y_points
  114. # reinit zones list
  115. for zone_index in cfg.zones_indices:
  116. zones_filled[zone_index] = 0
  117. zones_clicks_of_subject[zone_index] = {}
  118. zones_clicks_of_subject[zone_index]['x'] = []
  119. zones_clicks_of_subject[zone_index]['y'] = []
  120. else:
  121. new_scene = False
  122. all_path_folder = os.path.join(output_folder_path, cfg.all_subjects_data_folder)
  123. if not os.path.exists(all_path_folder):
  124. os.makedirs(all_path_folder)
  125. print('Merge images clicks of subjects into', all_path_folder)
  126. for k, v in scenes_data.items():
  127. current_x_points = []
  128. current_y_points = []
  129. for i in cfg.zones_indices:
  130. current_x_points = current_x_points + v[i]['x']
  131. current_y_points = current_y_points + v[i]['y']
  132. title = k + ' scene with all subjects (with ' + str(p_n) + ' clicks per subject)'
  133. img_filename = cfg.all_subjects_data_folder + '_' + k + '_' + str(p_n) + '.png'
  134. img_path = os.path.join(all_path_folder, img_filename)
  135. # save figure `all` subjects `p_n` clicks
  136. utils_functions.save_img_plot(k, current_x_points, current_y_points, title, img_path)
  137. print('Images are saved into', output_folder_path)
  138. if __name__== "__main__":
  139. main()