def frame_count(data_exif, img_start, img_end=-1, idx_continue=0, output_folder="test_output/"): """ For each sample in data exif a plot is generated showing the frame number of the animation :param data_exif: Dictionary with exif data from the input images :param img_start: First image to be processed. Index from data_exif :param img_end: Last image to be processed. Index from data_exif. Set to negative to process all data in data_exif :param idx_continue: Index to continue exporting data. The fcn will start at this idx, use in case an Exception raises to start from the last run iteration and not have to export already processed images :param output_folder: Folder where images will be stored """ # Port from an older matlab script # ---------- Sanitize inputs and initialize variables ---------- if img_end < 0: img_end = len(data_exif['timestampMs']) idx_continue = idx_continue + img_start helpers.ensure_directory(output_folder) mapplotAnimationHelpers.sync_helper_file(img_start, img_end, data_exif['filename'], output_folder) time_start = time.perf_counter() for i in range(idx_continue, img_end): time_start_it = time.perf_counter() # ---------- Set iteration values ---------- idx_animation = i - img_start + 1 datetime_target = data_exif['timestampMs_localtime'][i] fig, ax = plt.subplots(nrows=1, ncols=1) fig.set_size_inches(10, 2) ax.text(1, 0.2, "%d/%d" % (idx_animation, img_end-img_start), color='White', fontsize=75, horizontalalignment='right') ax.set_facecolor((0, 0 ,0)) plt.savefig(output_folder + str(idx_animation) + ".png") # plt.show() fig.clf() plt.close('all') mapplotAnimationHelpers.print_console( idx_animation, img_start, img_end, time_start, time_start_it, data_exif['filename'][i])
def centered_on_location(data_exif, data_precise, img_start, img_end=-1, idx_continue=0, output_folder="test_output/"): """ For each sample in data exif an image is generated centering the map view in the closest precise sample (by time) :param data_exif: Dictionary with exif data from the input images :param data_precise: Dictionary with the data used to draw the trayectory. Use google location if possible :param img_start: First image to be processed. Index from data_exif :param img_end: Last image to be processed. Index from data_exif. Set to negative to process all data in data_exif :param idx_continue: Index to continue exporting data. The fcn will start at this idx, use in case an Exception raises to start from the last run iteration and not have to export already processed images :param output_folder: Folder where images will be stored """ # ---------- Sanitize inputs and initialize variables ---------- if img_end < 0: img_end = len(data_exif['timestampMs']) idx_continue = idx_continue + img_start helpers.ensure_directory(output_folder) mapplotAnimationHelpers.sync_helper_file(img_start, img_end, data_exif['filename'], output_folder) # custom_obj_map = mapplot.MapPlot() custom_obj_map = mapplot.MapPlot(maxtiles=17) custom_obj_map.expect_const_area = True # To reduce the number of map fetchs idx_precise_first = get_index_close_to_timestamp( data_precise, data_exif['timestampMs'][img_start]) # ---------- Process loop ---------- time_start = time.perf_counter() for i in range(idx_continue, img_end): time_start_it = time.perf_counter() # ---------- Set iteration values ---------- idx_animation = i - img_start + 1 datetime_target = data_exif['timestampMs'][i] dt_local_day_start_in_utc = ( data_exif['timestampMs_localtime'][i].replace( hour=0, minute=0, second=0)) - timedelta(hours=data_exif['timezoneH']) idx_exif = i idx_precise = get_index_close_to_timestamp(data_precise, datetime_target) idx_precise_day_start = get_index_previous_timestamp( data_precise, dt_local_day_start_in_utc, idx_precise, idx_precise_first) # ---------- Generate map and draw on it ---------- margin = 0.01 custom_obj_map.set_map_around_point( data_precise['latitude'][idx_precise], data_precise['longitude'][idx_precise], margin) custom_obj_map.draw_list( data_precise['latitude'][idx_precise_first:idx_precise_day_start + 1], data_precise['longitude'][idx_precise_first:idx_precise_day_start + 1], lineop_in='-', c_in='#9a0200', ms_in=10, mew_in=1, lw_in=2) custom_obj_map.draw_list( data_precise['latitude'][idx_precise_day_start:idx_precise + 1], data_precise['longitude'][idx_precise_day_start:idx_precise + 1], lineop_in='-', c_in='r', ms_in=10, mew_in=1, lw_in=2) custom_obj_map.draw_single_marker( data_precise['latitude'][idx_precise], data_precise['longitude'][idx_precise], s_in=90, c_in='r', marker_in='o', zorder_in=100, edgecolors_in='k') # moss green (#658b38) if data_exif['has_gps'][idx_exif]: custom_obj_map.draw_single_marker(data_exif['latitude'][idx_exif], data_exif['longitude'][idx_exif], s_in=120, c_in='#03719c', marker_in='o', zorder_in=110, edgecolors_in='k') # ---------- Export map and clear iteration variables ---------- custom_obj_map.save_plot(output_folder + str(idx_animation) + ".png") custom_obj_map.clear() # ---------- Console output ---------- mapplotAnimationHelpers.print_console(idx_animation, img_start, img_end, time_start, time_start_it, data_exif['filename'][idx_exif]) custom_obj_map.print_stats() print("---- · ----")
def region_expanding_by_last_n_pics(data_exif, data_precise, img_start, img_end=-1, idx_continue=0, n_pics=7, output_folder="test_output/"): """ For each sample in data exif an image is generated showing the last N samples in the map. The region expands to fit all N samples. :param data_exif: Dictionary with exif data from the input images :param data_precise: Dictionary with the data used to draw the trayectory. Use google location if possible :param img_start: First image to be processed. Index from data_exif :param img_end: Last image to be processed. Index from data_exif. Set to negative to process all data in data_exif :param idx_continue: Index to continue exporting data. The fcn will start at this idx, use in case an Exception raises to start from the last run iteration and not have to export already processed images :param output_folder: Folder where images will be stored """ # ---------- Sanitize inputs and initialize variables ---------- if img_end < 0: img_end = len(data_exif['timestampMs']) idx_continue = idx_continue + img_start if n_pics < 2: n_pics = 2 helpers.ensure_directory(output_folder) mapplotAnimationHelpers.sync_helper_file(img_start, img_end, data_exif['filename'], output_folder) custom_obj_map = mapplot.MapPlot() idx_precise_first = get_index_close_to_timestamp( data_precise, data_exif['timestampMs'][img_start]) # ---------- Process loop ---------- time_start = time.perf_counter() for i in range(idx_continue, img_end): time_start_it = time.perf_counter() # ---------- Set iteration values ---------- idx_animation = i - img_start + 1 datetime_target = data_exif['timestampMs'][i] dt_local_day_start_in_utc = ( data_exif['timestampMs_localtime'][i].replace( hour=0, minute=0, second=0)) - timedelta(hours=data_exif['timezoneH']) idx_exif = i idx_precise = get_index_close_to_timestamp(data_precise, datetime_target) idx_precise_day_start = get_index_previous_timestamp( data_precise, dt_local_day_start_in_utc, idx_precise, idx_precise_first) # ---------- Generate map and draw on it ---------- margin = 0.005 idx_prev = idx_precise_first if idx_animation == 1: region_lat_min = data_precise['latitude'][ idx_precise_first] - margin region_lon_min = data_precise['longitude'][ idx_precise_first] - margin region_lat_max = data_precise['latitude'][ idx_precise_first] + margin region_lon_max = data_precise['longitude'][ idx_precise_first] + margin elif idx_animation <= n_pics: region_lat_min = min( data_precise['latitude'][idx_precise_first:idx_precise + 1]) region_lon_min = min( data_precise['longitude'][idx_precise_first:idx_precise + 1]) region_lat_max = max( data_precise['latitude'][idx_precise_first:idx_precise + 1]) region_lon_max = max( data_precise['longitude'][idx_precise_first:idx_precise + 1]) else: idx_prev = get_index_close_to_timestamp( data_precise, data_exif['timestampMs'][i - n_pics]) region_lat_min = min( data_precise['latitude'][idx_prev:idx_precise + 1]) region_lon_min = min( data_precise['longitude'][idx_prev:idx_precise + 1]) region_lat_max = max( data_precise['latitude'][idx_prev:idx_precise + 1]) region_lon_max = max( data_precise['longitude'][idx_prev:idx_precise + 1]) # Map will automatically download if the new region is smaller custom_obj_map.set_map_region_square(region_lat_min, region_lon_min, region_lat_max, region_lon_max, margin) custom_obj_map.draw_list( data_precise['latitude'][idx_precise_first:idx_precise_day_start + 1], data_precise['longitude'][idx_precise_first:idx_precise_day_start + 1], lineop_in='-', c_in='#9a0200', ms_in=10, mew_in=1, lw_in=2) custom_obj_map.draw_list( data_precise['latitude'][idx_precise_day_start:idx_precise + 1], data_precise['longitude'][idx_precise_day_start:idx_precise + 1], lineop_in='-', c_in='r', ms_in=10, mew_in=1, lw_in=2) custom_obj_map.draw_single_marker( data_precise['latitude'][idx_precise], data_precise['longitude'][idx_precise], s_in=100, c_in='r', marker_in='o', zorder_in=110, edgecolors_in='k') # moss green (#658b38) # Print degrading circles fixme mark_s_max = 180 for j in range(n_pics): mark_s_max = mark_s_max / 1.5 if data_exif['has_gps'][idx_exif - j]: custom_obj_map.draw_single_marker( data_exif['latitude'][idx_exif - j], data_exif['longitude'][idx_exif - j], s_in=mark_s_max, c_in='#03719c', marker_in='o', zorder_in=100, edgecolors_in='k') # ---------- Export map and clear iteration variables ---------- custom_obj_map.save_plot(output_folder + str(idx_animation) + ".png") custom_obj_map.clear() # ---------- Console output ---------- mapplotAnimationHelpers.print_console(idx_animation, img_start, img_end, time_start, time_start_it, data_exif['filename'][idx_exif]) custom_obj_map.print_stats() print("---- · ----")
import src.extraAnimationPresets as extraAnimationPresets # ---------- 1. Input variables ---------- # Remember that photos must be already ordered chronologically project_name = "Example" pics_folder = "C:/User/Raw/Photos" # Can be full path "C:/.../.../..." timezone_hour_diff = 1 # Won't sync properly photos from different timezones force_regenerate = False # To create again the csv from images and history location use_location_history = True # Set to True if location history is available. Set to False to use exif data location_history_path = "location history.json" # Can be full path # Proceed to step 3 to configure what plots are generated # ---------- 2. Data Loading ---------- aux_folder = project_name + "/auxiliar/" helpers.ensure_directory(aux_folder) if not os.path.isfile(aux_folder + "exif.csv") or force_regenerate: extractExif.extract_exif_folder(pics_folder, aux_folder) dict_exif = extractExif.load_exif_data(aux_folder, timezone_hour_diff, autofix=False) if use_location_history: if not os.path.isfile(aux_folder + "location_history.csv") or force_regenerate: extractGoogleLocation.extract_from_location_history( location_history_path, aux_folder, dict_exif['timestampMs'][0], dict_exif['timestampMs'][-1]) dict_Loc_History = extractGoogleLocation.load_location_history_data( aux_folder)
def clocks(data_exif, img_start, img_end=-1, idx_continue=0, output_folder="test_output/"): """ For each sample in data exif a plot is generated showing an analog and digital clock with the local time and date :param data_exif: Dictionary with exif data from the input images :param img_start: First image to be processed. Index from data_exif :param img_end: Last image to be processed. Index from data_exif. Set to negative to process all data in data_exif :param idx_continue: Index to continue exporting data. The fcn will start at this idx, use in case an Exception raises to start from the last run iteration and not have to export already processed images :param output_folder: Folder where images will be stored """ # Port from an older matlab script # ---------- Sanitize inputs and initialize variables ---------- if img_end < 0: img_end = len(data_exif['timestampMs']) idx_continue = idx_continue + img_start helpers.ensure_directory(output_folder) mapplotAnimationHelpers.sync_helper_file(img_start, img_end, data_exif['filename'], output_folder) th = [x * (math.pi/50) for x in range(0, 100)] xunit = [] yunit = [] for i in range(len(th)): xunit.append(math.cos(th[i])) yunit.append(math.sin(th[i])) agujaH_l = 0.5 agujaM_l = 0.85 time_start = time.perf_counter() for i in range(idx_continue, img_end): time_start_it = time.perf_counter() # ---------- Set iteration values ---------- idx_animation = i - img_start + 1 datetime_target = data_exif['timestampMs_localtime'][i] hour = datetime_target.hour minute = datetime_target.minute agujaHx = [0, agujaH_l * math.cos(-(hour * math.pi / 6) + (math.pi / 2))] agujaHy = [0, agujaH_l * math.sin(-(hour * math.pi / 6) + (math.pi / 2))] agujaMx = [0, agujaM_l * math.cos(-(minute * math.pi / 30) + (math.pi / 2))] agujaMy = [0, agujaM_l * math.sin(-(minute * math.pi / 30) + (math.pi / 2))] fig, ax = plt.subplots(nrows=1, ncols=1) # fig.set_size_inches(9, 5) fig.set_size_inches(15, 5) ax.plot(xunit, yunit, lw=8, color='White'); ax.plot(agujaHx, agujaHy, lw=8, color='White'); ax.plot(agujaMx, agujaMy, lw=8, color='White'); ax.text(1.3, 0.4, datetime_target.strftime("%H:%M"), color='White', fontsize=75) # ax.text(1.2, -0.65, datetime_target.strftime("%d/%m"), color='White', fontsize=75) ax.text(3.4, 0.4, datetime_target.strftime("%d/%m"), color='White', fontsize=75) ax.set_facecolor((0, 0 ,0)) ax.axis("equal") ax.axis([-1.3, 5.5, -1.2, 1.2]); plt.savefig(output_folder + str(idx_animation) + ".png") # plt.show() fig.clf() plt.close('all') mapplotAnimationHelpers.print_console( idx_animation, img_start, img_end, time_start, time_start_it, data_exif['filename'][i])
def timeline(data_exif, img_start, img_end=-1, idx_continue=0, output_folder="test_output/"): """ For each sample in data exif a plot is generated showing the local time of capture of all the images of the day up to the current sample timedate :param data_exif: Dictionary with exif data from the input images :param img_start: First image to be processed. Index from data_exif :param img_end: Last image to be processed. Index from data_exif. Set to negative to process all data in data_exif :param idx_continue: Index to continue exporting data. The fcn will start at this idx, use in case an Exception raises to start from the last run iteration and not have to export already processed images :param output_folder: Folder where images will be stored """ # ---------- Sanitize inputs and initialize variables ---------- if img_end < 0: img_end = len(data_exif['timestampMs']) idx_continue = idx_continue + img_start helpers.ensure_directory(output_folder) mapplotAnimationHelpers.sync_helper_file(img_start, img_end, data_exif['filename'], output_folder) time_start = time.perf_counter() for i in range(idx_continue, img_end): time_start_it = time.perf_counter() # ---------- Set iteration values ---------- idx_animation = i - img_start + 1 list_aux_x = [] list_aux_y = [] target_found = False idx_limit = img_start idx_loop = i dt_local_day_start = data_exif['timestampMs_localtime'][i].replace(hour=0, minute=0, second=0) while not target_found: if idx_loop >= idx_limit: if data_exif['timestampMs_localtime'][idx_loop] <= dt_local_day_start: target_found = True else: secs_since_day_start = data_exif['timestampMs_localtime'][idx_loop].hour*3600 + \ data_exif['timestampMs_localtime'][idx_loop].minute*60 + \ data_exif['timestampMs_localtime'][idx_loop].second list_aux_x.append(secs_since_day_start) list_aux_y.append(1) else: # No more valid samples to analyze target_found = True idx_loop -= 1 list_ref_x = [0] list_ref_y = [0.9] for j in range(25): list_ref_x.append(j*3600) list_ref_y.append(0.9) fig, ax = plt.subplots(nrows=1, ncols=1) fig.set_size_inches(8, 1.5) ax.scatter(list_ref_x, list_ref_y, 180, color='#0485d1', marker='|'); ax.scatter(list_ref_x[0], list_ref_y[0], 200, color='White', marker='|'); ax.scatter(list_ref_x[13], list_ref_y[13], 200, color='White', marker='|'); ax.scatter(list_ref_x[-1], list_ref_y[-1], 200, color='White', marker='|'); ax.scatter(list_aux_x, list_aux_y, 180, color='White', marker='|'); ax.scatter(list_aux_x[0], list_aux_y[0], 180, color='Red', marker='|'); ax.text(list_ref_x[0], list_ref_y[0] - 0.6, "0", color='White', fontsize=18, horizontalalignment='center') ax.text(list_ref_x[13], list_ref_y[13] - 0.6, "12", color='White', fontsize=18, horizontalalignment='center') ax.text(list_ref_x[-1], list_ref_y[-1] - 0.6, "24", color='White', fontsize=18, horizontalalignment='center') for i in range(3,24,3): if i == 12: continue ax.text(list_ref_x[i+1], list_ref_y[i+1] - 0.6, "%d" % (i), color='#0485d1', fontsize=16, horizontalalignment='center') ax.set_facecolor((0, 0 ,0)) # ax.axis("equal") ax.axis([-3600, 86400.0+3600, 0, 2]); plt.savefig(output_folder + str(idx_animation) + ".png") # plt.show() fig.clf() plt.close('all') mapplotAnimationHelpers.print_console( idx_animation, img_start, img_end, time_start, time_start_it, data_exif['filename'][i])