def save(self, output_file, class_file=''): if output_file.endswith('.txt'): if (not class_file and self.c.any()): np.savetxt( output_file, np.stack([self.x, self.y, self.z, self.i, self.r, self.c], axis=1), fmt='%.2f,%.2f,%.2f,%d,%d,%d') else: np.savetxt(output_file, np.stack([self.x, self.y, self.z, self.i, self.r], axis=1), fmt='%.2f,%.2f,%.2f,%d,%d') if class_file: self.save_classifications_txt(class_file) elif output_file.endswith('.las') or output_file.endswith('.laz'): lfile = LasFile(output_file, mode='w', header=LasHeader(x_scale=0.01, y_scale=0.01, z_scale=0.01)) lfile.X = self.x / 0.01 lfile.Y = self.y / 0.01 lfile.Z = self.z / 0.01 lfile.Intensity = self.i lfile.flag_byte = self.r lfile.Classification = self.c lfile.close() else: raise ValueError('Unknown file type extension: ' + output_file)
def save_las(xyzc, header, path): # header = Header() outfile = File(path, mode="w", header=header) outfile.X = xyzc[:, 0] outfile.Y = xyzc[:, 1] outfile.Z = xyzc[:, 2] outfile.Classification = xyzc[:, 3].astype(np.uint8) outfile.close()
def write_LAS(pc_xyz, v, output_las_fn, input_las_fn, cmap=cm.terrain, 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)) colormap_terrain = cmap rgb = colormap_terrain(v_rescale) #remove last column - alpha value rgb = (rgb[:, :3] * (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.Red = rgb[:, 0] outFile.Green = rgb[:, 1] outFile.Blue = rgb[:, 2] outFile.close()
def write_cloud(header, point_cloud, output_point_cloud_path, write_extra_dimensions=False): (h, scale, offset, evlrs, vlrs) = header # Open output file output_las_file = File(output_point_cloud_path, mode='w', header=h, evlrs=evlrs, vlrs=vlrs) if write_extra_dimensions: # Create new dimensions for name, dimension in point_cloud.extra_dimensions_metadata.items(): output_las_file.define_new_dimension( name=name, data_type=dimension.get_las_type(), description="Dimension added by Ground Extend") # Assign dimension values for dimension_name, values in point_cloud.extra_dimensions.items(): setattr(output_las_file, dimension_name, values) # Adapt points to scale and offset [x_scale, y_scale, z_scale] = scale [x_offset, y_offset, z_offset] = offset [x, y] = np.hsplit(point_cloud.xy, 2) output_las_file.X = (x.ravel() - x_offset) / x_scale output_las_file.Y = (y.ravel() - y_offset) / y_scale output_las_file.Z = (point_cloud.z - z_offset) / z_scale # Set color [red, green, blue] = np.hsplit(point_cloud.rgb, 3) output_las_file.red = red.ravel() output_las_file.green = green.ravel() output_las_file.blue = blue.ravel() # Set classification output_las_file.Classification = point_cloud.classification.astype( np.uint8) # Set header output_las_file.header.scale = scale output_las_file.header.offset = offset # Close files output_las_file.close()
def write_las(self, file_name: str, alt_header: File = None): """ Writes the current points in a las format Header used will be the same as the one provided during loading otherwise given. """ f = File(file_name, mode='w', header=alt_header if alt_header else self.header) data = self.data(transformed=False) f.X = data[:, 0] f.Y = data[:, 1] f.Z = data[:, 2] f.Red = data[:, 3] f.Green = data[:, 4] f.Blue = data[:, 5] f.close()
methodpointx = [] methodpointy = [] methodpointz = [] for point in methodpoints: methodpointx.append(point[0]) methodpointy.append(point[1]) methodpointz.append(point[2]) print newoutput_file = File('method.las', mode="w", header=inFile.header) newoutput_file.X = methodpointx newoutput_file.Y = methodpointy newoutput_file.Z = methodpointz newoutput_file.close() inFile.close() ####################### convertLasZip('out.las', 'out.laz') convertLasZip('method.las', 'method.laz') uploadToS3('out.laz', 'jippe-greyhound-to-las-test-dense', 'potree_original.laz') uploadToS3('method.laz', 'jippe-greyhound-to-las-test-dense', 'potree_method.laz') removeFile('out.las') removeFile('out.laz')
goodpointx = [] goodpointy = [] goodpointz = [] for point in allpoints: if viewfrustum.isVisible([point[0], point[1], point[2]]): goodpointx.append(point[0]) goodpointy.append(point[1]) goodpointz.append(point[2]) print 'There are %s points in the view frustum' % len(goodpointx) output_file = File('frustumfile.las', mode = "w", header = inFile.header) output_file.X = goodpointx output_file.Y = goodpointy output_file.Z = goodpointz allpoints = [] for i in range(len(goodpointx)): templist = [] templist.append(goodpointx[i]) templist.append(goodpointy[i]) templist.append(goodpointz[i]) allpoints.append((templist)) ######################### # Method implementation # ######################### distdict = {}
def implementation(camera_url): ### Preparation url = camera_url parsed = urlparse.urlparse(url) params = urlparse.parse_qsl(parsed.query) dict_params = dict(params) # what is in dict_params: # ps = point size # pa = point size attenuation (closer to you appear larger) # ca = camera rotation xy (z-axis) # ce = camera rotation yz (x-axis) # cd = camera distance to target # s = server # r = resource # ze = Z-exaggeration # c0s = imagery # ct = camera target resource = dict_params['r'] camera_target = ast.literal_eval(dict_params['ct']) camera_rotation_z = ast.literal_eval(dict_params['ca']) camera_rotation_x = ast.literal_eval(dict_params['ce']) camera_distance = ast.literal_eval(dict_params['cd']) print('Angle_z: {}'.format(camera_rotation_z)) print('Angle_x: {}'.format(camera_rotation_x)) print('Distance: {}'.format(camera_distance)) print('Target: {}'.format(camera_target)) return filenameList = [] filenameDict = {} densityDict = {} bboxDict = {} ### Retrieve points from webserver downloadFromS3('jippe-home', 'POTREE_reads.txt', 'urls.txt') potreefile = open('urls.txt', 'r') for j, line in enumerate(potreefile): # extract params from READ request url = line parsed = urlparse.urlparse(url) params = urlparse.parse_qsl(parsed.query) dict_params = dict(params) # what is in dict_params? # depthBegin = starting depth # scale = dataset scale # depthEnd = end depth # compress = stored as LAZ (True) or LAS (False) # bounds = bbox # offset = offset from main dataset (AHN2) # to make box an actual list: # import ast # ast.literal_eval(dict_params['bounds']) box = ast.literal_eval(dict_params['bounds']) depthBegin = int(dict_params['depthBegin']) depthEnd = int(dict_params['depthEnd']) dataset_offset = ast.literal_eval(dict_params['offset']) adjusted_camera_target = tuple( c_i - d_i for c_i, d_i in zip(camera_target, dataset_offset)) if depthEnd - depthBegin != 1: startDepth = depthEnd # make sure all octree levers are 4 numbers filler = '0' * (4 - len(str(depthEnd))) depth = filler + str(depthEnd) # create filename with depth '0000' appended to front filename = '%soriginalfile%s.las' % (depth, j) filenameList.append(filename) # make filenamedict for merging with lasmerge if depth in filenameDict: appendfilename = filename + ' ' filenameDict[depth] += appendfilename else: appendfilename = ' ' + filename + ' ' filenameDict[depth] = appendfilename # retrieve from Greyhound webserver BASE = getGreyhoundServer() allinfo = info(BASE, resource) dtype = buildNumpyDescription(allinfo['schema']) data = readdata(BASE, resource, box, depthBegin, depthEnd) writeLASfile(dtype, data, filename) potreefile.close() # find camera offset camera_offset_command = "".join( ('lasinfo -i ', filenameList[0], ' -nv -nmm -nco -o outputfile.txt')) os.system(camera_offset_command) with open('outputfile.txt') as f: for line in f: if line[:14] == ' offset x y z': print(line) newline = line.split() camera_offset_params = float(newline[4]), float( newline[5]), float(newline[6]) # Create a filename list with sorted filenameDict values levelfilenameList = [] for key in filenameDict: levelfilenameList.append("".join((key, '.las'))) levelfilenameList.sort() print(filenameList) # For each 'level' create 1 file for key in filenameDict: filenames = filenameDict[key] outname = "".join((key, '.las')) mergefiles = 'lasmerge -i ' + filenames + ' -o ' + outname os.system(mergefiles) # Cleanup for filename in filenameList: try: removeFile(filename) except OSError as e: print(e) print '%s does not exist' % filename # Create one single file mergefiles = 'lasmerge -i *.las -o out.las' os.system(mergefiles) for filename in levelfilenameList: try: removeFile(filename) except OSError as e: print(e) print('{} does not exist'.format(filename)) ### Find formula for gradual density descent. This is implemented ### in more detail in other files in this folder. If needed copy ### the basics from there and continue. ######################### # Method implementation # ######################### inFile = openLasFile('out.las') numpoints = len(inFile.points) print 'There are %s points in the original file' % numpoints goodpoints = np.vstack((inFile.x, inFile.y, inFile.z)).transpose() allpoints = [] for i in range(len(goodpoints)): templist = [] templist.append(goodpoints[i][0]) templist.append(goodpoints[i][1]) templist.append(goodpoints[i][2]) allpoints.append(tuple(templist)) used = [False] * len(allpoints) kdtree = scipy.spatial.KDTree(allpoints) methodpoints = set([]) starttime1 = time.time() percentage = 0 for j, point in enumerate(allpoints): if used[j] == True: continue # !!!This needs some serious reworking!!! (see comment down below) # We can assume the camera parameters needed are just the camera_origin, this is because the # speck.ly query itsself has already made the distinguishment what is inside and outside of the # view frustrum. Knowing this it should be an operation using both the known angles and the # distance from the target that give us the location; simple stuff def find_vector(alpha, beta): """ Alpha is the angle from Y to Z Beta is the angle from X to Z """ a, b = math.radians(alpha), math.radians(beta) x = -1 * math.sin(a) * math.cos(b) y = -1 * math.cos(a) * math.cos(b) z = math.sin(b) return (x, y, z) print('Calculating camera_parameters') camera_vector = find_vector(camera_angle_y, camera_angle_x) print('Camera vector: {}'.format(camera_vector)) camera_vector_distance = tuple(x * camera_distance for x in camera_vector) print('Camera vector distance: {}'.format(camera_vector_distance)) print('Calculated using:') print('Angle_x: {}'.format(camera_angle_x)) print('Angle_y: {}'.format(camera_angle_y)) print('Distance: {}'.format(camera_distance)) print('Target: {}'.format(adjusted_camera_target)) camera_origin = adjusted_camera_target distancevector = (point[0] - camera_origin[0], point[1] - camera_origin[1], point[2] - camera_origin[2]) distance = (distancevector[0]**2 + distancevector[1]**2 + distancevector[2]**2)**0.5 # implement exponential function here # This should later be the density function nn = kdtree.query_ball_point(point, distance**0.2) appendvar = True for i in nn: if allpoints[i] in methodpoints: appendvar = False break if appendvar == True: methodpoints.add(point) for i in nn: used[i] = True newpercentage = int(j / float(numpoints) * 100) if newpercentage > percentage: percentage = newpercentage if percentage == 1 or percentage % 10 == 0: print "Work in progress, %d%% done" % percentage endtime1 = time.time() timetaken1 = endtime1 - starttime1 print 'There are %s points in the view frustum after vario-scale method application' % len( methodpoints) print 'This took %s seconds to calculate' % timetaken1 methodpointx = [] methodpointy = [] methodpointz = [] for point in methodpoints: methodpointx.append(point[0]) methodpointy.append(point[1]) methodpointz.append(point[2]) print newoutput_file = File('method.las', mode="w", header=inFile.header) newoutput_file.X = methodpointx newoutput_file.Y = methodpointy newoutput_file.Z = methodpointz newoutput_file.close() inFile.close() ####################### convertLasZip('out.las', 'out.laz') convertLasZip('method.las', 'method.laz') uploadToS3('out.laz', 'jippe-greyhound-to-las-test-dense', "".join( ('plasio_', resource, '_potree_original.laz'))) uploadToS3('method.laz', 'jippe-greyhound-to-las-test-dense', "".join( ('plasio_', resoure, '_potree_method.laz'))) removeFile('out.las') removeFile('out.laz') removeFile('method.las') removeFile('method.laz') removeFile('urls.txt') removeFile('outputfile.txt')
def base_method(self, file_name): """" Base method implementation """ ######################### # Method implementation # ######################### inFile = openLasFile(filename) numpoints = len(inFile.points) print 'There are %s points in the original file' % numpoints goodpoints = np.vstack((inFile.x, inFile.y, inFile.z)).transpose() allpoints = [] for i in range(len(goodpoints)): templist = [] templist.append(goodpoints[i][0]) templist.append(goodpoints[i][1]) templist.append(goodpoints[i][2]) allpoints.append(tuple(templist)) used = [False] * len(allpoints) kdtree = scipy.spatial.KDTree(allpoints) methodpoints = set([]) starttime1 = time.time() percentage = 0 for j, point in enumerate(allpoints): if used[j] == True: continue distancevector = (point[0] - self.camera_origin[0], point[1] - self.camera_origin[1], point[2] - self.camera_origin[2]) distance = (distancevector[0]**2 + distancevector[1]**2 + distancevector[2]**2)**0.5 # implement logarithmic(e) function here nn = kdtree.query_ball_point(point, np.log(distance * 0.5)) appendvar = True for i in nn: if allpoints[i] in methodpoints: appendvar = False break if appendvar == True: methodpoints.add(point) for i in nn: used[i] = True newpercentage = int(j / float(numpoints) * 100) if newpercentage > percentage: percentage = newpercentage print "Work in progress, %d%% done" % percentage endtime1 = time.time() timetaken1 = endtime1 - starttime1 print 'There are %s points in the view frustum after vario-scale method application' % len( methodpoints) print 'This took %s seconds to calculate' % timetaken1 methodpointx = [] methodpointy = [] methodpointz = [] for point in methodpoints: methodpointx.append(point[0]) methodpointy.append(point[1]) methodpointz.append(point[2]) newoutput_file = File('method.las', mode="w", header=inFile.header) newoutput_file.X = methodpointx newoutput_file.Y = methodpointy newoutput_file.Z = methodpointz newoutput_file.close() inFile.close() ####################### convertLasZip(filename, 'out.laz') convertLasZip('method.las', 'method.laz') uploadToS3('out.laz', 'jippe-greyhound-to-las-test-dense', 'potree_original.laz') uploadToS3('method.laz', 'jippe-greyhound-to-las-test-dense', 'potree_method.laz') removeFile(filename) removeFile('out.laz') removeFile('method.las') removeFile('method.laz')
goodpointy = [] goodpointz = [] for point in allpoints: if viewfrustum.isVisible([point[0], point[1], point[2]]): goodpointx.append(point[0]) goodpointy.append(point[1]) goodpointz.append(point[2]) print 'There are %s points in the view frustum' % len(goodpointx) output_file = File('frustumfile.las', mode = "w", header = inFile.header) output_file.X = goodpointx output_file.Y = goodpointy output_file.Z = goodpointz inFile.close() output_file.close() convertLasZip('originalfile.las', 'originalfile.laz') convertLasZip('frustumfile.las', 'frustumfile.laz') uploadToS3('originalfile.laz', 'jippe-greyhound-to-las-test-dense', 'greyhound_to_las_test_original.laz') uploadToS3('frustumfile.laz', 'jippe-greyhound-to-las-test-dense', 'greyhound_to_las_test_frustum.laz') removeFile('originalfile.las') removeFile('originalfile.laz') removeFile('frustumfile.las') removeFile('frustumfile.laz')