def do_hm(target_tile_path): # load tile for matching target_tile_name = target_tile_path.stem + target_tile_path.suffix try: target_tile = File(target_tile_path, mode='r') # this can take some time # use global to get the info, apologize to programming teachers global ref_tile global ky_lidar_fix_path # match histograms new_dist = hist_match(target_tile.intensity, ref_tile.intensity) # apply transformation new_tile_path = ky_lidar_fix_path / target_tile_name new_tile = File(new_tile_path, mode='w', header=target_tile.header) new_tile.points = target_tile.points new_tile.intensity = new_dist new_tile.close() return (True, new_tile_path) except: # if we can't load the file, that's a big problem, but it seems to happen # sometimes. return (False, target_tile_path)
def write_las_grid(self,filename, lb = -10, ub = 10, granularity = 0.1): out_file = File(filename, mode = "w", header = Header()) out_file.header.scale = (0.001,0.001,0.001) grid = self.get_3d_grid(lb, ub, granularity) out_file.x = grid[:,0]* 300 out_file.y = grid[:,1] * 300 out_file.z = grid[:,2] * 300 out_file.intensity = grid[:,2] * 300 return(out_file)
def write_las_grid(self, filename, lb=-10, ub=10, granularity=0.1): out_file = File(filename, mode="w", header=Header()) out_file.header.scale = (0.001, 0.001, 0.001) grid = self.get_3d_grid(lb, ub, granularity) out_file.x = grid[:, 0] * 300 out_file.y = grid[:, 1] * 300 out_file.z = grid[:, 2] * 300 out_file.intensity = grid[:, 2] * 300 return (out_file)
def write_LAS_intensity(pc_xyz, v, output_las_fn, input_las_fn, rescale='none'): import datetime from laspy.file import File from skimage import exposure import copy inFile = File(input_las_fn, mode='r') #normalize input and generate colors for height using colormap #stretch to 10-90th percentile #v_1090p = np.percentile(v, [10, 90]) #stretch to 2-98th percentile v_0298p = np.percentile(v, [2, 98]) if rescale == 'none': v_rescale = exposure.rescale_intensity(v, in_range=(v_0298p[0], v_0298p[1])) elif rescale == 'median': bounds = np.round(np.median(np.abs(v_0298p)), decimals=2) v_rescale = exposure.rescale_intensity(v, in_range=(-bounds, bounds)) v_rescale = v_rescale * (np.power(2, 16) - 1).astype('uint16') outFile = File(output_las_fn, mode='w', header=inFile.header) new_header = copy.copy(outFile.header) #setting some variables new_header.created_year = datetime.datetime.now().year new_header.created_day = datetime.datetime.now().timetuple().tm_yday new_header.x_max = pc_xyz[:, 0].max() new_header.x_min = pc_xyz[:, 0].min() new_header.y_max = pc_xyz[:, 1].max() new_header.y_min = pc_xyz[:, 1].min() new_header.z_max = pc_xyz[:, 2].max() new_header.z_min = pc_xyz[:, 2].min() new_header.point_records_count = pc_xyz.shape[0] new_header.point_return_count = 0 outFile.header.count = v.shape[0] new_header.scale = inFile.header.scale new_header.offset = inFile.header.offset outFile.X = (pc_xyz[:, 0] - inFile.header.offset[0]) / inFile.header.scale[0] outFile.Y = (pc_xyz[:, 1] - inFile.header.offset[1]) / inFile.header.scale[1] outFile.Z = (pc_xyz[:, 2] - inFile.header.offset[2]) / inFile.header.scale[2] outFile.intensity = v_rescale outFile.close()
min_x = np.min(in_pc_nparray[:, 0]) + shift max_x = np.max(in_pc_nparray[:, 0]) + shift step_x = resolution min_y = np.min(in_pc_nparray[:, 1]) + shift max_y = np.max(in_pc_nparray[:, 1]) + shift step_y = resolution bound_x = np.arange(min_x, max_x, step_x) bound_y = np.arange(min_y, max_y, step_y) target_x, target_y = np.meshgrid(bound_x, bound_y, indexing='ij') # export as XYZ pcloud x = np.ravel(target_x) y = np.ravel(target_y) z = np.ones(len(x)) false_intensity = np.zeros(len(x)) out_LAS = File(filename + "_target.las", mode="w", header=in_pc.header) out_LAS.x = x out_LAS.y = y out_LAS.z = z out_LAS.intensity = false_intensity out_LAS.close() end1 = time.time() difftime1 = end1 - start1 print(("create target point: %f sec") % (difftime1))
ky_lidar_raw_files_paths = list(ky_lidar_raw_files_path.glob("*.las")) # How best to choose the reference tile? Maybe just choose the first one for now? ref_tile_path = ky_lidar_raw_files_paths.pop(0) # I don't know of a good way to mark it so that it's visible later though... print(f"Reference tile: {ref_tile_path}") # Open ref tile, save it as-is in the new path ref_tile = File(ref_tile_path, mode='r') new_tile = File( ky_lidar_fix_path / (ref_tile_path.stem + ref_tile_path.suffix), mode='w', header=ref_tile.header) new_tile.intensity = ref_tile.intensity new_tile.close() # need a function to process a sample and save it back def do_hm(target_tile_path): # load tile for matching target_tile_name = target_tile_path.stem + target_tile_path.suffix try: target_tile = File(target_tile_path, mode='r') # this can take some time # use global to get the info, apologize to programming teachers global ref_tile global ky_lidar_fix_path # match histograms new_dist = hist_match(target_tile.intensity, ref_tile.intensity)
out_LAS.define_new_dimension(name="sum_eigenvalues" + "_" + str(k), data_type=9, description="Spatial feature") out_LAS.define_new_dimension(name="curvature" + "_" + str(k), data_type=9, description="Spatial feature") #out_LAS.define_new_dimension(name="classification"+"_"+str(k),data_type=9, description="reference") print(point_cloud.columns) out_LAS.x = point_cloud['x'] #point_cloud.drop('x') out_LAS.y = point_cloud['y'] out_LAS.z = point_cloud['z'] out_LAS.intensity = point_cloud['intensity'] out_LAS.return_num = point_cloud['return_number'] #print(point_cloud["number_of_returns"]) point_cloud["number_of_returns"] = point_cloud["number_of_returns"] #print(point_cloud["number_of_returns"]) out_LAS.num_returns = point_cloud['number_of_returns'] #Setting attributes Maybe do this with "try" ? setattr(out_LAS, 'delta_z' + "_" + str(k), point_cloud['delta_z']) #point_cloud.drop('delta_z') setattr(out_LAS, 'std_z' + "_" + str(k), point_cloud['std_z']) #point_cloud.drop('std_z') setattr(out_LAS, 'radius' + "_" + str(k), point_cloud['radius']) #point_cloud.drop('radius') setattr(out_LAS, 'density' + "_" + str(k), point_cloud['density']) #point_cloud.drop('density')