Convertendo arquivo LAS para matriz numpy?

15

Comecei a aprender a manipular dados LAS em python e queria ver como outras pessoas lidam com arquivos LAS. Gostaria de ler os pontos (estou usando uma matriz numpy) e filtrar as classes 1 e 2 (não classificadas e fundamentadas) em uma matriz separada. Eu tenho o código a seguir, mas não consigo obter os pontos filtrados.

# Import modules
from liblas import file
import numpy as np

if __name__=="__main__":
    '''Read LAS file and create an array to hold X, Y, Z values'''
    # Get file
    las_file = r"E:\Testing\ground_filtered.las"
    # Read file
    f = file.File(las_file, mode='r')
    # Get number of points from header
    num_points = int(f.__len__())
    # Create empty numpy array
    PointsXYZIC = np.empty(shape=(num_points, 5))
    # Load all LAS points into numpy array
    counter = 0
    for p in f:
        newrow = [p.x, p.y, p.z, p.intensity, p.classification]
        PointsXYZIC[counter] = newrow
        counter += 1

Eu vi arcpy.da.featureClassToNumpyArray, mas não queria importar o arcpy nem precisar converter para o shapefile.

De que outra forma posso filtrar / ler dados do LAS em uma matriz numpy?

Barbarossa
fonte
Qual é a mensagem de erro (se houver)?
til_b
Sem erro. Eu simplesmente não sabia como filtrar e não tinha certeza se havia uma maneira melhor de obter o LAS na matriz.
Barbarossa

Respostas:

14

Seu PointsXYZICagora é uma matriz numpy. O que significa que você pode usar a indexação numpy para filtrar os dados nos quais está interessado. Por exemplo, você pode usar um índice de booleanos para determinar quais pontos buscar.

#the values we're classifying against
unclassified = 1
ground = 2

#create an array of booleans
filter_array = np.any(
    [
        PointsXYZIC[:, 4] == unclassified, #The final column to index against
        PointsXYZIC[:, 4] == ground,
    ],
    axis=0
)

#use the booleans to index the original array
filtered_rows = PointsXYZIC[filter_array]

Agora você deve ter uma matriz numpy com todos os valores em que os dados não são classificados ou fundamentados. Para obter os valores que foram classificados, você pode usar:

filter_array = np.all(
    [
        PointsXYZIC[:, 4] != unclassified, #The final column to index against
        PointsXYZIC[:, 4] != ground,
    ],
    axis=0
)
om_henners
fonte
O filtro parece funcionar, mas grava apenas 5 registros. Tentei filtrar apenas as classes 1 e 2 e, em seguida, tentei filtrar todos, exceto 1 e 2, ambos me dando apenas 5 resultados. Alguma ideia?
Barbarossa
Esses 5 registros estão em uma matriz 1-d.
Barbarossa
Desculpe, atualizei o código acima, pois requer especificação do eixo para realizar qualquer cálculo (sem ele executa todas as dimensões da matriz).
Om_henners #
5

Use laspy para ler arquivos LAS e retornar facilmente os dados como matrizes numpy com as quais você pode interagir. laspy é python puro, é quase tão rápido quanto libLAS, possui mais recursos do que as ligações libLAS Python e é muito mais fácil de implementar.

Howard Butler
fonte
0

Peço desculpas se você já sabe disso, mas o LASTools é uma ferramenta fantástica de código-fonte aberto que agora se integra ao ArcGIS e ao QGIS 2.0 - Isso tem opções para filtrar os dados da maneira que você está olhando.

Nicholas Duggan
fonte
@Nicholas obrigado, eu estou usando a biblioteca liblas python, que está intimamente ligada à LASTools
Barbarossa