def change_vertical_orientation(dictionary): # import required submodules of georef_webcam import modules.aux_functions as aux_func ##### create and select options, how to edit the vertical looking direction choices_list = ['keep current pitch angle', 'edit pitch angle', 'change height difference between target and camera', 'edit absolute target height', 'edit target offset above ground'] choice = aux_func.select_choices(choices_list)[0] ##### execute choice if(choice == 'keep current pitch angle'): dictionary = calc_vertical_params(dictionary, pitch = False) elif(choice == 'edit pitch angle'): dictionary['var_add'] = add2dict(dictionary['var_add'], ['pitch_angle_deg'], overwrite = True) dictionary = calc_vertical_params(dictionary, pitch = False) elif(choice == 'change height difference between target and camera'): dictionary['var_add'] = add2dict(dictionary['var_add'], ['height_diff_target_cam'], overwrite=True) dictionary = calc_vertical_params(dictionary, height_diff = False) elif(choice == 'edit absolute target height'): dictionary['var_add'] = add2dict(dictionary['var_add'], ['target_DEMCRS_Z'], overwrite=True) dictionary = calc_vertical_params(dictionary, z = False) elif(choice == 'edit target offset above ground'): dictionary = calc_vertical_params(dictionary, pitch = False) dictionary = add2dict(dictionary, ['target_offset'], overwrite=True) dictionary = calc_vertical_params(dictionary, offset = False) # return new dictionary to main procedure return dictionary
def define_vertical_orientation(dictionary, bool_target): # import required submodules of georef_webcam import modules.aux_functions as aux_func ##### create options, how to generate pitch angle, transverse looking angle choices_list = [] if (bool_target): dictionary['target_offset'] = dictionary['camera_offset'] choices_list.extend( ['reuse or adjust camera offset above ground for target']) choices_list.extend([ 'use horizontal pitch angle (pitch = 0°)', 'insert another pitch angle', 'insert height difference between target and camera', 'use target offset above ground', 'use absolute target height' ]) ##### select choice print("Please define yaw/transverse looking angle...") print( "This angle defines, whether the camera is looking horizontally, upwards or downwards." ) print("Several options to calculate yaw exist:") choice = aux_func.select_choices(choices_list)[0] ##### execute choice if (choice == 'reuse or adjust camera offset above ground for target'): dictionary = add2dict(dictionary, ['target_offset'], overwrite=True) dictionary = calc_vertical_params(dictionary, offset=False) elif (choice == 'use horizontal pitch angle (pitch = 0°)'): dictionary['var_add']['pitch_angle_deg'] = 0 dictionary = calc_vertical_params(dictionary, pitch=False) elif (choice == 'insert another pitch angle'): dictionary['var_add']['pitch_angle_deg'] = input( "Please insert pitch angle [°]: \n") dictionary = calc_vertical_params(dictionary, pitch=False) elif (choice == 'insert height difference between target and camera'): print("distance from camera to target is: " + str(dictionary['var_add']['distance'])) dictionary['var_add']['height_diff_target_cam'] = input( "Please insert the height difference between target and camera in m: \n" ) dictionary = calc_vertical_params(dictionary, height_diff=False) elif (choice == 'use target offset above ground'): calc_height_or_offset(dictionary, name='target', offset_or_height=1) dictionary = calc_vertical_params(dictionary, offset=False) elif (choice == 'use absolute target height'): calc_height_or_offset(dictionary, name='target', offset_or_height=2) dictionary = calc_vertical_params(dictionary, offset=False) # return new dictionary to main procedure return dictionary
def georef_webcam(in_dir, out_dir, name_of_run="test_run", view=True, gcp=False, results=False): # import required libraries and submodules of georef_webcam import modules.aux_functions as aux_func import procedures.collect_projection_parameters as collect_params import procedures.edit_projection_parameters as edit_params import procedures.write_PRACTISE_inputfile as prac_input import procedures.execute_PRACTISE as exe_prac import procedures.results as proj_results import json, sys ##### create or read dictionary with projection parameters if (aux_func.check_input( "Do you want to create a new set of projection parameters?")): dict_file = collect_params.create_dict(in_dir, out_dir, name_of_run) else: print("Find existing json dataset...") json_file = aux_func.select_file(in_dir, 'json', name='dict') with open(json_file) as read_file: dict_file = json.load(read_file) dict_file['path'] = out_dir if results: print('Calculate results') proj_results.calc_result(dict_file, name_of_run) print('Producing of results sucessfully finished') print('End of programm') sys.exit() ##### possibility to edit projection parameters if (aux_func.check_input("Do you want to edit the projection parameters?") ): dict_file, name_of_run = edit_params.edit_parameters( dict_file, in_dir, name_of_run) out_dir = dict_file['path'] # path to store PRACTISE output ############### start PRACTISE projection calculation ##################### while True: ##### write parameters from dict into PRACTISE input file prac_input_file = prac_input.create_input(dict_file, name_of_run) ##### call PRACTISE and calculate the prepared projection exe_prac.run_PRACTISE(prac_input_file, name_of_run, out_dir, gcp) ##### show octave image file with projection result of PRACTISE if view: proj_results.show_result(out_dir, name_of_run) ##### extract optimized projection parameters of GCP optimization and store them in json-file (optional) old_dict = False if not (dict_file['gcp_file'] == None): print( "Projection parameters have been optimized with GCP optimisation" ) if (aux_func.check_input( "Do you want to extract optimized projection parameters and store them in a dict file?" )): old_dict = dict_file dict_file, name_of_run = proj_results.extract_params( dict_file, name_of_run, in_dir) # decide, how to continue print("Projection has been executed. \nWhat do you want to do next?") next_step = aux_func.select_choices([ 'end procedure', 'edit projection input parameters and repeat projection procedure', 'produce georef_webcam output' ])[0] ##### option 1: edit projection parameters and rerun projection procedure in PRACTISE if (next_step == 'edit projection input parameters and repeat projection procedure' ): if old_dict: print("Which parameters do you want to edit?") edit_file = aux_func.select_choices( ['optimized parameters', 'original parameters'])[0] if (edit_file == 'original parameters'): dict_file = old_dict dict_file, name_of_run_new = edit_params.edit_parameters( dict_file, in_dir, name_of_run) if not aux_func.check_input( "Do you want to rerun projection with adjusted parameters?" ): break out_dir = dict_file['path'] # path to store PRACTISE output ##### option 2: end program directly elif (next_step == 'end procedure'): break ##### option 3: produce georef_webcam output (coordinate rasters, mask, projected image) elif (next_step == 'produce georef_webcam output'): proj_results.calc_result(dict_file, name_of_run) print('Producing of results sucessfully finished') break print('End of programm')
def calc_result(input_dict, run_name): # import required libraries and submodules of georef_webcam import os, shutil import numpy as np import modules.aux_functions as aux_func import modules.aux_results as aux_res # create directory for georef_webcam results output_dir = os.path.join(input_dict['path'], 'georef_result', run_name) if not os.path.exists(output_dir): os.makedirs(output_dir) # select octave file, which contains PRACTISE georeferencing results result_file = aux_res.select_PRACTISE_files(input_dict['path'], run_name, '_proj.mat') ############### Extract information from PRACTISE output ################## print("Extract information from PRACTISE output...") # read mat-file with open(result_file, 'r') as output: result_output = output.readlines() # get number of columns and no of rows of image rows = int(result_output[109]) cols = int(result_output[114]) # get position in image of all projected DEM points img_col = aux_res.get_data_from_PRACTISE(result_output, 167) img_row = aux_res.get_data_from_PRACTISE(result_output, 168) points = [(int(img_row[pt]), int(img_col[pt])) for pt in range(len(img_col))] # create interpolation grid interpolation_grid = np.mgrid[0:rows, 0:cols] ############### calculate results ######################################### ##### decide, which results should be produced print("Which results should be produced?") selected_results = aux_func.select_choices([ 'rasters with easting and northing coordinate + mask', '+ altitude raster', '+ distance to camera', '+ projected image', 'all results' ], True) ##### interpolate coordinate rasters print('Start interpolation of coordinates rasters ...') # select interpolation style: nearest neighbor or bilinear print( 'How do you want to interpolate the coordinate rasters? Nearest neighbor or Bilinear?' ) interpolate = aux_func.select_choices(['nearest', 'linear'])[0] # interpolate coordinate (E & N) rasters east_raster = aux_res.interpolate_raster(aux_res.get_data_from_PRACTISE( result_output, 135), points, interpolation_grid, output_dir, "east_raster.tif", interpolation_type=interpolate) north_raster = aux_res.interpolate_raster(aux_res.get_data_from_PRACTISE( result_output, 136), points, interpolation_grid, output_dir, "north_raster.tif", interpolation_type=interpolate) # interpolate altitude raster (optional) if (set(['+ altitude raster', 'all results']).intersection(selected_results)): alt_raster = aux_res.interpolate_raster(aux_res.get_data_from_PRACTISE( result_output, 137), points, interpolation_grid, output_dir, "alt_raster.tif", interpolation_type=interpolate) del alt_raster ##### copy image to output directory and save directory to dem for prj information shutil.copy2(input_dict['image_file'], output_dir) with open(os.path.join(output_dir, 'dem_file.txt'), 'w') as dem_file: dem_file.write(input_dict['dem_file']) ##### generate mask to filter areas above skyline # calculate distance to DEM points in image plane to get skyline dist_pts_raster = aux_res.calculate_distance_raster( points, interpolation_grid, output_dir) # create mask aux_res.create_mask(dist_pts_raster, output_dir) ##### calculate distance to camera (optional) # edges in panoramic view can be derived from that if (set(['+ distance to camera', 'all results']).intersection(selected_results)): pos_E = aux_res.get_data_from_PRACTISE(result_output, 5) pos_N = aux_res.get_data_from_PRACTISE(result_output, 6) cam_pos = (pos_E[0], pos_N[0]) dist_raster = np.sqrt((east_raster - cam_pos[0])**2 + (north_raster - cam_pos[1])**2) aux_res.write_array_as_geotiff(dist_raster, output_dir, "dist_raster.tif") ##### project image to map if (set(['+ projected image', 'all results']).intersection(selected_results)): aux_res.call_project_image(input_dict, output_dir)
def edit_parameters(input_dict, in_dir, name_of_run): # import required libraries and submodules of georef_webcam import json, os import modules.aux_functions as aux_func import modules.aux_collect_params as aux_collect # decide, which parameters should be changed edit_all = False print("Which input parameters should be changed?") edit_choices = aux_func.select_choices([ 'input files (e.g. image, dem, gcp)', 'camera position', 'camera orientation', 'sensor parameters', 'further projection parameters (roll angle & buffer range)', 'gcp optimisation boundaries (add or change)', 'all of them' ], True) if ('all of them' in edit_choices): edit_all = True ############### edit input files (DEM, image, gcp file) ################### if ('input files (e.g. image, dem, gcp)' in edit_choices) or edit_all: input_dict = aux_collect.add2dict( input_dict, ['dem_file', 'image_file', 'gcp_file'], overwrite=True) ############### edit camera position ###################################### ##### edit camera coordinate location if ('camera position' in edit_choices) or edit_all: print("In which CRS do you want to change the camera position?") CRS_choices = aux_func.select_choices(['original CRS', 'DEM CRS'])[0] # either in original input CRS if (CRS_choices == 'original CRS'): input_dict['var_add'] = aux_collect.define_position( input_dict['var_add'], edit=True) coordinates_cam = aux_collect.coordinates_2dem_crs( input_dict['var_add'], input_dict['dem_file']) d_x = float(coordinates_cam[0]) - float( input_dict['camera_DEMCRS_E']) d_y = float(coordinates_cam[1]) - float( input_dict['camera_DEMCRS_N']) input_dict['camera_DEMCRS_E'] = coordinates_cam[0] input_dict['camera_DEMCRS_N'] = coordinates_cam[1] # or in CRS of DEM data else: coordinates_cam_old = (input_dict['camera_DEMCRS_E'], input_dict['camera_DEMCRS_N']) input_dict = aux_collect.add2dict( input_dict, ['camera_DEMCRS_E', 'camera_DEMCRS_N'], overwrite=True) d_x = float(input_dict['camera_DEMCRS_E']) - float( coordinates_cam_old[0]) d_y = float(input_dict['camera_DEMCRS_N']) - float( coordinates_cam_old[1]) input_dict = aux_collect.coordinates_from_dem_crs_to_original_crs( input_dict) # adjust target coordinate location accordingly input_dict['target_DEMCRS_E'] = input_dict['target_DEMCRS_E'] + d_x input_dict['target_DEMCRS_N'] = input_dict['target_DEMCRS_N'] + d_y input_dict = aux_collect.coordinates_from_dem_crs_to_original_crs( input_dict, name='target') ##### edit camera height or offset print("How do you want to adjust camera height?") height_choices = aux_func.select_choices([ 'keep original offset above ground', 'keep original absolute height', 'Insert new value' ])[0] if (height_choices == 'keep original offset above ground'): input_dict = aux_collect.calc_height_or_offset(input_dict, offset_or_height=1, edit=True) elif (height_choices == 'keep original absolute height'): input_dict = aux_collect.calc_height_or_offset(input_dict, offset_or_height=2, edit=True) else: input_dict = aux_collect.calc_height_or_offset(input_dict, overwrite=True) input_dict = aux_collect.calc_vertical_params(input_dict, pitch=False, height_diff=False) ############### edit camera orientation ################################### if ('camera orientation' in edit_choices) or edit_all: ##### edit horizontal orientation (Yaw angle or target coordinate location) print("How do you want to adjust camera orientation angles?") print("Yaw Angle / Horizontal Looking Direction:") yaw_choices = aux_func.select_choices( ['no change', 'change yaw angle', 'change target position'])[0] # edit yaw angle if (yaw_choices == 'change yaw angle'): input_dict['var_add'] = aux_collect.add2dict(input_dict['var_add'], ['yaw_angle_deg'], overwrite=True) dx, dy = aux_collect.calc_target_from_lookdir( float(input_dict['var_add']['yaw_angle_deg']), distance=input_dict['var_add']['distance']) input_dict['target_DEMCRS_E'] = float( input_dict['camera_DEMCRS_E']) + dx input_dict['target_DEMCRS_N'] = float( input_dict['camera_DEMCRS_N']) + dy input_dict = aux_collect.coordinates_from_dem_crs_to_original_crs( input_dict, name='target') # edit target position if (yaw_choices == 'change target position'): print("In which CRS do you want to change the target position?") CRS_choices = aux_func.select_choices(['original CRS', 'DEM CRS'])[0] # either in original input CRS if (CRS_choices == 'original CRS'): input_dict['var_add'] = aux_collect.define_position( input_dict['var_add'], name='target', edit=True) coordinates_tar = aux_collect.coordinates_2dem_crs( input_dict['var_add'], input_dict['dem_file'], name='target') input_dict['target_DEMCRS_E'] = coordinates_tar[0] input_dict['target_DEMCRS_N'] = coordinates_tar[1] # or in CRS of DEM data else: input_dict = aux_collect.add2dict( input_dict, ['target_DEMCRS_E', 'target_DEMCRS_N'], overwrite=True) input_dict = aux_collect.coordinates_from_dem_crs_to_original_crs( input_dict, name='target') input_dict['var_add'][ 'yaw_angle_deg'] = aux_collect.calc_orientation(input_dict) # aux: recalc distance input_dict['var_add']['distance'] = aux_collect.get_distance_tc( input_dict) ##### edit vertical orientation of the camera using pitch angle, height difference or height of target point print("Pitch Angle / Vertical Looking Direction:") print("How do you want to adjust this orientation angle?") input_dict = aux_collect.change_vertical_orientation(input_dict) ############### edit sensor parameters #################################### if ('sensor parameters' in edit_choices) or edit_all: input_dict = aux_collect.add2dict( input_dict, ['sensor_width_mm', 'sensor_height_mm', 'focalLen_mm'], overwrite=True) ############### edit roll angle and buffer range ########################## if ('further projection parameters (roll angle & buffer range)' in edit_choices) or edit_all: input_dict = aux_collect.add2dict( input_dict, ['roll_angle_deg', 'buffer_around_camera_m'], overwrite=True) ############### add or edit gcp optimisation boundaries ################### if ('gcp optimisation boundaries (add or change)' in edit_choices) or edit_all: if not 'opt_boundaries' in input_dict['var_add']: input_dict['var_add'][ 'opt_boundaries'] = aux_collect.set_optimisation_boundaries() print('optimisation boundaries have been added') print('Optimization Boundaries:') aux_collect.print_dict(input_dict['var_add']['opt_boundaries']) edit = aux_func.check_input("Do you want to edit them?") else: print('Optimization Boundaries:') aux_collect.print_dict(input_dict['var_add']['opt_boundaries']) edit = True if edit: input_dict['var_add'][ 'opt_boundaries'] = aux_collect.set_optimisation_boundaries( input_dict['var_add']['opt_boundaries']) ############### write edited dict to new json file (optional) ############# if aux_func.check_input( "Do you want to save edited dictionary as new json-file?"): name_of_run = input('Old filename: ' + name_of_run + ' \nPlease enter a new filename: \n') ##### write resulting dict to json file print('\n\nCollected parameters are stored in json file:') print(os.path.join(in_dir, name_of_run + ".json")) jsonfile = json.dumps(input_dict) f = open(os.path.join(in_dir, name_of_run + ".json"), "w") f.write(jsonfile) f.close() # return edited dict and new name of run to main procedure return input_dict, name_of_run
def create_dict(in_dir, out_dir, name_of_run): # import required libraries and submodules of georef_webcam import collections, json, os import modules.aux_functions as aux_func import modules.aux_collect_params as aux_collect ##### create dictionary with parameters required for PRACTISE var_mand = [ 'path', 'image_file', 'dem_file', 'gcp_file', 'camera_DEMCRS_E', 'camera_DEMCRS_N', 'camera_offset', 'target_DEMCRS_E', 'target_DEMCRS_N', 'target_offset', 'roll_angle_deg', 'focalLen_mm', 'sensor_width_mm', 'sensor_height_mm', 'buffer_around_camera_m', 'var_add' ] input_dict = collections.OrderedDict((k, None) for k in var_mand) input_dict['var_add'] = collections.OrderedDict() ##### add existing default values sensor_parameters = [ 'sensor_width_mm', 'sensor_height_mm', 'focalLen_mm', 'roll_angle_deg', 'buffer_around_camera_m', 'camera_offset', 'target_offset' ] sensor_default = [22.3, 14.9, 14.0, 0.0, 100.0, 0, 0] input_dict = aux_collect.add2dict(input_dict, sensor_parameters, sensor_default) ############### define directories to output & input ###################### # path to store PRACTISE output input_dict['path'] = out_dir # select image file, which should be projected image_ending = input( "Which file extension does the image have? (write extension without .) \n" ) input_dict['image_file'] = aux_func.select_file(in_dir, image_ending, name='image') print('Selected image: ', input_dict['image_file']) # select DEM used for projection dem_ending = input( "Which file extension does the DEM raster have? (write extension without .) \n" ) input_dict['dem_file'] = aux_collect.select_dem_file(in_dir, dem_ending) print('Selected DEM file: ', input_dict['dem_file']) ############### define camera location #################################### # coordinates of camera position input_dict['var_add'] = aux_collect.define_position(input_dict['var_add']) coordinates_cam = aux_collect.coordinates_2dem_crs(input_dict['var_add'], input_dict['dem_file']) input_dict['camera_DEMCRS_E'] = coordinates_cam[0] input_dict['camera_DEMCRS_N'] = coordinates_cam[1] # camera height or offset input_dict = aux_collect.calc_height_or_offset(input_dict) ############### define camera orientation ################################# if (aux_func.check_input( "Do you want to insert target point coordinates (y) or use orientation angle (n) instead?" )): ##### target point approach target = True input_dict['var_add'] = aux_collect.define_position( input_dict['var_add'], name='target') coordinates_tar = aux_collect.coordinates_2dem_crs( input_dict['var_add'], input_dict['dem_file'], name='target') input_dict['target_DEMCRS_E'] = coordinates_tar[0] input_dict['target_DEMCRS_N'] = coordinates_tar[1] input_dict['var_add']['yaw_angle_deg'] = aux_collect.calc_orientation( input_dict) else: ##### orientation angle approach input_dict = aux_collect.orientation_angle(input_dict) input_dict = aux_collect.coordinates_from_dem_crs_to_original_crs( input_dict, name='target', epsg=True) target = False # aux: calculate distance between camera and target input_dict['var_add']['distance'] = aux_collect.get_distance_tc(input_dict) ##### define vertical oriantation of the camera using pitch angle, height difference or height of target point input_dict = aux_collect.define_vertical_orientation(input_dict, target) ############### edit or add further parameters if wanted ################## ##### roll angle, camera system parameters and buffer range print('Further variables have been predefined, but can be adjusted now.') print('(The predefined value of each parameter is showm behind it.)\n') choice_list = ['edit none of them'] choice_list.extend( aux_collect.print_dict(input_dict, [ 'roll_angle_deg', 'sensor_width_mm', 'sensor_height_mm', 'focalLen_mm', 'buffer_around_camera_m' ], do_return=True)) additional_params = aux_func.select_choices(choice_list, multiple_choice=True) if not (additional_params[0] == 'edit none of them'): additional_params = [x.split(':')[0] for x in additional_params] ##### edit roll angle, if wanted if ('roll_angle_deg' in additional_params): print("\n\nAdjust roll angle...") input_dict = aux_collect.add2dict(input_dict, ['roll_angle_deg'], overwrite=True) ##### define camera system parameters cam_param = set(['sensor_width_mm', 'sensor_height_mm', 'focalLen_mm']).intersection(additional_params) if cam_param: print("\n\nAdjust camera system parameters... ") input_dict = aux_collect.add2dict(input_dict, cam_param, overwrite=True) ##### adjust buffer if ('buffer_around_camera_m' in additional_params): print( "\n\nAdjust remaining projection parameter (buffer)... \nDefault value:" ) input_dict = aux_collect.add2dict(input_dict, ['buffer_around_camera_m'], overwrite=True) ############### add GCP file for projection optimisation if available ##### if (aux_func.check_input( "Do you have GCPs available to run the DDS optimisation in PRACTISE?" )): # select gcp file input_dict['gcp_file'] = aux_func.select_file(in_dir, 'gcp.txt', name='GCP') # add and adjust optimization boundaries, if wanted input_dict['var_add'][ 'opt_boundaries'] = aux_collect.set_optimisation_boundaries() print('Optimization Boundaries:') aux_collect.print_dict(input_dict['var_add']['opt_boundaries']) if (aux_func.check_input( "Do you want to adjust the optimisation boudaries?")): input_dict['var_add'][ 'opt_boundaries'] = aux_collect.set_optimisation_boundaries( input_dict['var_add']['opt_boundaries']) ############### write resulting dict to json file ######################### print('\n\nCollected parameters are stored in json file:') print(os.path.join(in_dir, name_of_run + ".json")) jsonfile = json.dumps(input_dict) f = open(os.path.join(in_dir, name_of_run + ".json"), "w") f.write(jsonfile) f.close() # return dictionary to main procedure return input_dict