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 getParams(self): """ """ indirs = self.configs["paths"]["input"] indir = indirs.split(":")[0] os.chdir(indir) infile = glob.glob("*.las")[0] data = File(infile, mode="r") self.header = data.header #print self.header self.dtype = data.points.dtype
def _update(self): f = FileLAS(self.filename_, mode='r') points = f.get_points() name = points.dtype.fields.keys() x = f.get_x_scaled() y = f.get_y_scaled() z = f.get_z_scaled() #Check is the LAS File contains red property if 'red' in points.dtype.fields[name[0]][0].fields.keys(): red = np.int32(255.0*f.red/65536.0) green = np.int32(255.0*f.green/65536.0) blue = np.int32(255.0*f.blue/65536.0) self.data_ = np.c_[x, y, z, red, green, blue] else: N = f.X.shape[0] color = 128*np.ones((N,), dtype=np.int32) self.data_ = np.c_[x, y, z, color, color, color]
def converti_las_asc(source,target): cell = 1.0 NODATA = 0 las = File(source, mode="r") min = las.header.min max = las.header.max xdist = max[0] - min[0] ydist = max[1] - min[1] cols = int(xdist) / cell rows = int(ydist) / cell cols += 1 rows += 1 count = np.zeros((rows, cols)).astype(np.float32) zsum = np.zeros((rows, cols)).astype(np.float32) ycell = -1 * cell projx = (las.x - min[0]) / cell projy = (las.y - min[1]) / cell ix = projx.astype(np.int32) iy = projy.astype(np.int32) # Loop through x,y,z arrays, add to grid shape, # and aggregate values for averaging for x, y, z in np.nditer([ix, iy, las.z]): count[y, x] += 1 zsum[y, x] += z # Change 0 values to 1 to avoid numpy warnings, # and NaN values in array nonzero = np.where(count > 0, count, 1) # Average our z values zavg = zsum / nonzero # Interpolate 0 values in array to avoid any # holes in the grid mean = np.ones((rows, cols)) * np.mean(zavg) left = np.roll(zavg, -1, 1) lavg = np.where(left > 0, left, mean) right = np.roll(zavg, 1, 1) ravg = np.where(right > 0, right, mean) interpolate = (lavg + ravg) / 2 fill = np.where(zavg > 0, zavg, interpolate) # Create our ASCII DEM header header = "ncols %s\n" % fill.shape[1] header += "nrows %s\n" % fill.shape[0] header += "xllcorner %s\n" % min[0] header += "yllcorner %s\n" % min[1] header += "cellsize %s\n" % cell header += "NODATA_value %s\n" % NODATA # Open the output file, add the header, save the array with open(target, "wb") as f: f.write(header) # The fmt string ensures we output floats # that have at least one number but only # two decimal places np.savetxt(f, fill, fmt="%1.2f")
def loadLAS2XYZ(filepath): ''' Function to load in console the pointcloud of a LAS file :param filepath: filepath of the LAS file :return: xyz array containing coordinate of the points ''' print('Start loading...') inFile = File(filepath, mode='r') coords = np.vstack((inFile.x, inFile.y, inFile.z)).transpose() print('Data loaded') return coords
def lidar(image): las = File(image, mode="r") for p in las: print(las.x, las.y, las.z) point = las.points print(point) print(las.header.min) print(las.header.max) print(las.x) print(las.X) print(las.Y)
def readlas(fname): from laspy.file import File from subprocess import call r = call(['laszip', fname]) if r: sys.exit('laszip ' + fname + ' failed') fn = '%s.las' % fname[:-4] f = File(fn) x = f.x y = f.y z = f.z l = f.classification f.close() r = call(['rm', fn]) if r: sys.exit('rm ' + fn + ' failed') return np.transpose((x, y, z, l))
def make_las_file(data, file_name=''): my_header = header.Header() outFile = File(file_name, mode='w', header=my_header) # outFile.header.offset = np.amin(data, axis=0)[0:3] outFile.header.scale = [1, 1, 1] outFile.x = data[:, 0] outFile.y = data[:, 1] outFile.z = data[:, 2] outFile.raw_classification = data[:, 3] outFile.close()
def read_laser(directory): # function to read '.las' files and print their size # input: file location and its name # output: .las file in numpy array laser_file = File(directory, mode='r') print('Number of points > ', len(laser_file.points)) print('Scale of axis > ', laser_file.header.scale) print('Offset of points > ', laser_file.header.offset) print('Each column is > ', laser_file.points.dtype) print('Number of columns is > ', len(laser_file.points.dtype[0])) return laser_file
def lasReader(filename): """ Read xyz points from single las file :param filename: path of single point cloud """ f = File(filename, mode='r') x_max, x_min = np.max(f.x), np.min(f.x) y_max, y_min = np.max(f.y), np.min(f.y) z_max, z_min = np.max(f.z), np.min(f.z) return np.transpose(np.asarray([f.x, f.y, f.z])), \ [(x_min, x_max), (y_min, y_max), (z_min, z_max)], f.header
def downsample(self, filepath, skipinterval, xbounds, ybounds): Xvalid = np.logical_and((np.min(xbounds) <= self.file.x), np.max(xbounds) >= self.file.x) Yvalid = np.logical_and((np.min(ybounds) <= self.file.y), np.max(ybounds) >= self.file.y) keep = np.where(np.logical_and(Xvalid, Yvalid)) points = self.points[keep] shuffleinds = np.random.shuffle(np.arange(points.shape[0])) points = np.array(points)[shuffleinds] points = np.squeeze(points[::skipinterval].transpose()) with File(filepath, mode='w', header=self.header) as output: output.points = points
def __init__(self, filepath: Filepath = None, build_tree=True): if filepath is not None: self.filepath = filepath self.file = File(self.filepath.filepath, mode="r") self.header = self.file.header self.points = np.vstack([self.file.x, self.file.y, self.file.z]).transpose() self.tree = sklearn.neighbors.KDTree(self.points[:, :2], leaf_size=2**4, metric='euclidean') self.datetime = filepath.datetime
def writeFile(directory,name,header,coords): """Write a laz file using laspy and numpy arrays""" output = File(directory + name, mode = "w", header=header) output.x = coords[0] output.y = coords[1] output.z = coords[2] output.close()
def write_las_file(self): """ Create and write a new lidar file with the desirable points """ if self.surfaces: self.out_full_path = os.path.join( self.out_dir, ('Surfaces_' + self.templates_dict['las'].format(self.name))) elif self.terrain: self.out_full_path = os.path.join( self.out_dir, ('Terrain_' + self.templates_dict['las'].format(self.name))) out_file = File(self.out_full_path, mode='w', header=self.in_file.header) if self.terrain: class_2_points, class_2_bool = self.get_points_by_class( self.class_flag) out_file.points = self.in_file.points[class_2_bool] elif self.surfaces: out_file.points = self.in_file.points[self.in_file.return_num == 1] out_file.close()
def read_las(infile, keys=None): try: from laspy.file import File except ImportError: print "Cannot read las files without laspy module" raise inFile = File(infile) datadict = {} datadict['coords'] = np.column_stack([ np.array(a, dtype=np.float32) for a in [inFile.x, inFile.y, inFile.z] ]) return datadict
def LasToCsv(lasFileName, shift=True): lasFile = File(lasFileName, mode='r') X = lasFile.X Y = lasFile.Y Z = lasFile.Z if shift: X = X - min(X) Y = Y - min(Y) Z = Z - min(Z) I = lasFile.intensity index = np.arange(X.shape[0]) data = np.stack((X, Y, Z, I, index), axis=1) np.savetxt(lasFileName + ".csv", data, fmt="%.3f,%.3f,%.3f,%d,%d")
def loadLAS2XYZAIR(filepath): ''' Function to load in console the pointcloud of a LAS file with points attributes :param filepath: filepath of the LAS file :return: xyz array containing coordinate of the points ''' print('Start loading...') inFile = File(filepath, mode='r') coords = np.vstack( (inFile.x, inFile.y, inFile.z, inFile.amplitude, inFile.Intensity, inFile.reflectance, inFile.num_returns)).transpose() print('Data loaded') return coords
def LAS2txt(filepath, newfile): ''' Function to convert a pointcloud save in LAS format into a .txt format :param filepath: filepath of the LAS file :param newfile: name of the new file :return: save data into a text file ''' inFile = File(filepath, mode='r') coords = np.vstack((inFile.x, inFile.y, inFile.z)).transpose() if newfile[-4] != '.txt': newfile = newfile + '.txt' np.savetxt(newfile, coords) print('File saved: ' + newfile)
def main(): input1 = "Data/MantecaFiltered/MantecaRailSlice.las" with File(input1, mode='r') as f: input_header = f.header to_plot = [] # list of VTK Point Clouds to plot points = subsample_frac_from_las_data(input1, .01) pc = create_vtkpc_from_array(points) to_plot.append(pc) create_point_cloud_plot_qt(to_plot, input_header=input_header, axes_on=True)
def get_first_returns_array(self): # Guardo el archivo para poder leerlo if self.partials_create: full_path = self.dirs.out_paths['las_surfaces'] self.dirs.create_dir(self.dirs.out_dirs['las']) else: full_path = self.dirs.temp_full_paths['las_surfaces'] self.dirs.create_dir(self.dirs.temp_dirs['temp_dir']) out_file = File(full_path, mode='w', header=self.in_file.header) out_file.points = self.in_file.points[ self.in_file.return_num == 1] out_file.close() #leo el archivo in_file = File(full_path, mode='r') scale = in_file.header.scale offset = in_file.header.offset x = in_file.X y = in_file.Y z = in_file.Z x_dimension = x * scale[0] + offset[0] y_dimension = y * scale[1] + offset[1] z_dimension = z * scale[-1] + offset[-1] size = x_dimension.shape[0] x_array = x_dimension.reshape(size, 1) y_array = y_dimension.reshape(size, 1) z_array = z_dimension # Cerrar archivo para poder eliminarlo in_file.close() if not self.partials_create: self.dirs.remove_temp_file(full_path) self.dirs.remove_temp_dir(self.dirs.temp_dirs['temp_dir']) xy_array = np.concatenate((x_array, y_array), axis=1) self.surfaces_arrays_list = [xy_array, z_array]
def save_cloud(inFile, dir_out, filename, classif, conf): # Problème dans les données, certaines labels sont à 0 label = inFile.classification ind = np.argwhere(label != 0) new_header = copy.copy(inFile.header) #Modification du point format id pour accéder au dimensions RGB new_header.data_format_id = 3 #Create outfile outFile = dir_out + filename.replace('.laz', '_classify' + '.laz') outCloud = File(outFile, mode="w", header=new_header, vlrs=inFile.header.vlrs) outCloud.define_new_dimension(name='classif', data_type=9, description="ntd") outCloud.define_new_dimension(name='conf', data_type=9, description="ntd") for dimension in inFile.point_format: if (dimension == inFile.point_format[13]): break dat = inFile.reader.get_dimension(dimension.name)[ind].reshape(-1) # dat = dat[ind] outCloud.writer.set_dimension(dimension.name, dat) multiscale_features_raw = pd.DataFrame() features_raw = np.hstack([classif.reshape(-1, 1), conf.reshape(-1, 1)]) features_raw = pd.DataFrame(features_raw) features_raw.columns = np.array(["classif", "conf"]) multiscale_features_raw = pd.concat( [multiscale_features_raw, features_raw], axis=1) outCloud.classif = multiscale_features_raw.as_matrix(['classif']).ravel() outCloud.conf = multiscale_features_raw.as_matrix(['conf']).ravel() outCloud.close()
def __init__(self, file, output_file, scale=1): inFile = File(file, mode="r") header_file = inFile.header self.x, self.y, self.z = inFile.x, inFile.y, inFile.z self.rn = inFile.return_num try: self.red, self.green, self.blue = inFile.red, inFile.green, inFile.blue print('LiDar file containing RGB channels') except: pass inFile.close() coords = np.vstack((self.z, self.y, self.x)).transpose() self.max_values = np.max(coords, axis=0).astype(int) self.min_values = np.min(coords, axis=0).astype(int) self.xr = np.array((1 / scale) * (coords[:, 2] - self.min_values[2]), dtype=np.int) self.yr = np.array((1 / scale) * (self.max_values[1] - coords[:, 1]), dtype=np.int) self.output_file = output_file self.scale = scale self.dimension = np.array( (1 / scale) * (self.max_values - self.min_values), dtype=np.int) self.n_points = len(self.xr) print('Metadata: ', header_file) print('Number of LiDar points: ', self.n_points) print('Maximum values in axis (z,y,x) are: ', self.max_values) print('Minimum values in axis (z,y,x) are: ', self.min_values) print('Cubic dimensions are: ', self.dimension)
def read_cloud(point_cloud_path): # Open point cloud and read its properties las_file = File(point_cloud_path, mode='r') header = (las_file.header.copy(), las_file.header.scale, las_file.header.offset, las_file.header.evlrs, las_file.header.vlrs) [x_scale, y_scale, z_scale] = las_file.header.scale [x_offset, y_offset, z_offset] = las_file.header.offset # Calculate the real coordinates x = las_file.X * x_scale + x_offset y = las_file.Y * y_scale + y_offset z = las_file.Z * z_scale + z_offset cloud = PointCloud.with_dimensions(x, y, z, las_file.Classification, las_file.red, las_file.green, las_file.blue) # Close the file las_file.close() # Return the result return header, cloud
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 __init__(self, filepath, skipinterval=1, buildTree=True): self.filepath = filepath.filepath self.file = File(self.filepath, mode="r") self.scale = self.file.header.scale[0] self.offset = self.file.header.offset[0] if buildTree: self.tree = KDTree( np.vstack([ self.file.x[::skipinterval], self.file.y[::skipinterval], self.file.z[::skipinterval] ]).transpose()) self.treeexis = True self.datetime = filepath.datetime
def __load_ply_file(self, filename, scale=1.0): import plyfile data = plyfile.PlyData.read(filename) self.points = pd.DataFrame() self.points['x'] = data.elements[0]['x'] self.points['y'] = data.elements[0]['y'] self.points['z'] = data.elements[0]['z'] self.points['user_data'] = np.array(data.elements[0]['confidence'] * 255.0, dtype=int) self.points['intensity'] = np.array(data.elements[0]['intensity'] * 255.0, dtype=int) self.points['class'] = np.zeros(len(self.points), dtype=int) self.showing = Mask(len(self.points), True) self.render(self.showing) with File(self.sample_las_file) as f: self.las_header = f.header.copy()
def load_data_memory(file): df = pd.DataFrame(np.empty(0, dtype=[('Xx',np.float),('Yy',np.float),('Zz',np.float),('intensity',np.int), ('raw_classification',np.int), ('gps_time',np.int32), ('elevation',np.float),('return',np.int),('X',np.int), ('Y',np.int), ('Z',np.int), ('hash',np.int), ('XN',np.float), ('YN',np.float), ('ZN',np.float) ])) las_data = File(full_path, mode='r') df['Xx'] = (las_data.x) df['Yy'] = (las_data.y) df['Zz'] = (las_data.z) df['intensity'] = (las_data.intensity) df['raw_classification'] = (las_data.raw_classification) df['gps_time'] = (las_data.gps_time) df['elevation'] = (las_data.user_data) / 10 df['returns'] = (las_data.return_num) # Density Density = len(df.index) / ((df.Xx.max() - df.Xx.min()) * (df.Yy.max() - df.Yy.min())) print(style.GREEN('Density :%f pts/m2'% Density)) grid_size = math.sqrt(NUM_POINT / Density) print('grid_size :%i m' % grid_size) # origine translation print('translation') df['X'] = df.Xx - df.Xx.min() df['Y'] = df.Yy - df.Yy.min() df['Z'] = df.Zz - df.Zz.min() # hash print('hash') df['mX'] = df.X // grid_size df.mX = df.mX.astype(int) df['mY'] = df.Y // grid_size df.mY = df.mY.astype(int) df['hash'] = df[['mX', 'mY']].apply(get_hash, axis=1) del df['mX'] del df['mY'] # normallisation print('normallisation') df['XN'] = (df.Xx - df.Xx.min()) / (df.Xx.max() - df.Xx.min()) df['YN'] = (df.Yy - df.Yy.min()) / (df.Yy.max() - df.Yy.min()) df['ZN'] = (df.Zz - df.Zz.min()) / (df.Zz.max() - df.Zz.min()) df['intensity'] = (df.intensity - df.intensity.min()) / (df.intensity.max() - df.intensity.min()) df['elevation'] = (df.elevation - df.elevation.min()) / (df.elevation.max() - df.elevation.min()) df['returns'] = (df.returns - df.returns.min()) / (df.returns.max() - df.returns.min()) df = df.sort_values(by=['hash']) return df
def get_bounds(arg): if isinstance(arg, str): ''' json = u""" { "pipeline": [ \"""" + arg + """\", { "type":"filters.stats", "dimensions":"X,Y,Z" } ] } pipeline = pdal.Pipeline(json) ''' f = File(arg, mode='r') min_values = f.header.min max_values = f.header.max return ((min_values[0], max_values[0]), (min_values[1], max_values[1])) else: json = u""" { "pipeline": [ { "type":"filters.stats", "dimensions":"X,Y,Z" } ] } """ pipeline = pdal.Pipeline(json, arrays=arg) pipeline.validate() pipeline.loglevel = 8 pipeline.execute() import json as j metadata = j.loads(pipeline.metadata) metadata['metadata']['filters.stats'][0]['bbox']['native']['bbox'][ 'minx'] return ((metadata['metadata']['filters.stats'][0]['bbox']['native'] ['bbox']['minx'], metadata['metadata']['filters.stats'][0] ['bbox']['native']['bbox']['maxx']), (metadata['metadata']['filters.stats'][0]['bbox']['native'] ['bbox']['miny'], metadata['metadata']['filters.stats'][0] ['bbox']['native']['bbox']['maxy']))
def __write_las_file(self, filename, points): if self.las_header is None: self.las_header = Header() self.las_header.x_offset, self.las_header.y_offset, self.las_header.z_offset = 0.0, 0.0, 0.0 self.las_header.x_scale, self.las_header.y_scale, self.las_header.z_scale = 0.0001, 0.0001, 0.0001 if self.las_header.data_format_id < 2: self.las_header.data_format_id = 2 with File(filename, self.las_header, mode='w') as f: f.x, f.y, f.z = points[['x', 'y', 'z']].values.T if 'r' in points: f.red, f.green, f.blue = points[['r', 'g', 'b']].values.T if 'class' in points: f.classification = points['class'].values if 'user_data' in points: f.user_data = points['user_data'].values if 'intensity' in points: f.intensity = points['intensity'].values
def load_las(path): input_las = File(path, mode='r') point_records = input_las.points.copy() las_scale_x = input_las.header.scale[0] las_offset_x = input_las.header.offset[0] las_scale_y = input_las.header.scale[1] las_offset_y = input_las.header.offset[1] las_scale_z = input_las.header.scale[2] las_offset_z = input_las.header.offset[2] # calculating coordinates p_x = np.array((point_records['point']['X'] * las_scale_x) + las_offset_x) p_y = np.array((point_records['point']['Y'] * las_scale_y) + las_offset_y) p_z = np.array((point_records['point']['Z'] * las_scale_z) + las_offset_z) points = np.vstack((p_x, p_y, p_z, input_las.red, input_las.green, input_las.blue)).T return points
def save_points_as_las(points, file_name, input_header): with File(file_name, mode='w', header=input_header) as f: # pdb.set_trace() # points = pc.getPoints() # print(points) allx = [] ally = [] allz = [] # for p in tqdm(points, total=points.GetNumberOfPoints(), desc="Saving"): for i in trange(len(points), desc="Saving"): p = points[i] # print(p) allx.append(p[0]) ally.append(p[1]) allz.append(p[2]) f.x = np.array(allx) f.y = np.array(ally) f.z = np.array(allz)
def __init__(self, filepath): #start = time.time() self.name = filepath self.file = File(filepath, mode="r") #self.filesize = getsizeof(self.file)/8 self.scale = self.file.header.scale[0] self.offset = self.file.header.offset[0] self.tree = KDTree( np.vstack([self.file.x, self.file.y, self.file.z]).transpose()) #self.tree.size = getsizeof(self.tree)/8 filename = splitext(basename(filepath))[0].replace("_", "") dateobj = [int(filename[i:i + 2]) for i in range(0, len(filename), 2) ] # year, month,day,hour,min,sec self.time = datetime.datetime(dateobj[0], dateobj[1], dateobj[2], dateobj[3], dateobj[4], dateobj[5], 0) #print("File Size: {}, KDTree Size: {}\n".format(self.filesize,self.treesize)) self.file = None
def read_file(file_path: FilePath) -> ArrayTuple: """Read .las file.""" file_path = Path(file_path) if file_path.suffix not in [k['format'] for k in extensions.values()]: raise NotImplementedError xyz = np.empty(0) rgb = np.empty(0) with File(str(file_path), mode='r') as f: xyz = np.array((f.x, f.y, f.z)).T try: if hasattr(f, 'red') and hasattr(f, 'green') and hasattr( f, 'blue'): rgb = np.array((f.red, f.green, f.blue)).T except LaspyException: pass return xyz, rgb
from laspy.file import File import copy inFile = File("autzen-dd.las", mode = "r") header = inFile.header points = copy.deepcopy(inFile.points) import numpy as np X = inFile.X Y = inFile.Y minx = np.min(X) miny = np.min(Y) maxx = np.max(X) maxy = np.max(Y) print minx, miny, maxx, maxy x = ((maxx - minx)/2.0 + minx) - 1.0/header.scale[0] y = (maxy - miny)/2.0 + miny print x, y points[0][0][0] = x print points[0][0][0] outfile = File("spurious.las", mode='w', header = header) outfile.points = points import pdb;pdb.set_trace()