Criando DEM em nanoescala com GDAL

14

Talvez seja uma pergunta estranha, mas deixe-me dar uma explicação detalhada dos antecedentes antes das minhas perguntas reais:

A microscopia de força atômica (AFM) é um método que, em resumo (e para meu conhecimento limitado) permite que os pesquisadores digitalizem áreas nas micro e nanoescalas. Ele funciona "digitalizando" uma área usando uma espécie de sonda. É mais difícil explicar para mim, pois não tenho uma compreensão real disso. O que eu sei e o que despertou minha curiosidade foi que o resultado é de fato uma "grade" de valores de "altura" (uma matriz de, digamos, valores de 512x512 que descrevem a altura da sonda nesse ponto).

Então pensei: além da balança, esse é de fato um modelo de elevação digital! E isso significa que, se eu conseguir criar um arquivo DEM como entendido pelas ferramentas GIS, poderia aplicar a análise GIS a ele!

No entanto, meu trabalho significativo trabalha em um laboratório que possui uma máquina AFM e a está usando em um de seus projetos. Peguei alguns arquivos de verificação dela e consegui, usando Python (struct e numpy), analisar esses arquivos binários e o que tenho agora é uma matriz numpy de tamanho 512x512 preenchida com valores int16.

O que estou planejando a seguir e com o qual preciso de ajuda é a parte "mapeamento para um DEM adequado". Eu tenho algum conhecimento sobre DEMS, mas quando se trata de geração real deles, sou bastante novo.

O que estou pensando é que preciso georreferenciar meus dados de alguma forma e, para isso, preciso de um sistema de coordenadas (planar) personalizado. Eu imagino que meu sistema de coordenadas usaria micrômetros ou nanômetros como unidades. Então é apenas uma questão de encontrar o tamanho da área digitalizada com o AFM (isso eu acredito que esteja em algum lugar no arquivo binário, suponha que isso seja conhecido).

atualização : Eu também tenho várias varreduras em resoluções diferentes, mas da mesma área. Por exemplo, eu tenho essas informações sobre duas verificações:

imagem maior:

Scan Size: 51443.5 nm
X Offset: 0 nm
Y Offset: 0 nm

imagem menor (detalhe):

Scan Size: 5907.44 nm
X Offset: 8776.47 nm
Y Offset: 1486.78 nm

O que eu acho, é que meu sistema de coordenadas personalizado deve ter uma origem em 0,0 e, para a imagem maior, atribuo ao pixel 0,0 o valor da coordenada (0,0) e ao pixel 512,512 o valor da coordenada (51443.5, 51443.5 ) (Suponha que você tenha uma imagem dos outros pontos necessários).

Em seguida, a imagem maior mapearia os pixels (0,0) para (8776,47, 1486,78) e (512,512) para (8776,47 + 5907,44, 1486,78 + 5907,44)

A 1ª pergunta é : Como criar um def de proj4 para esse sistema de coordenadas? Ou seja: como atribuir essas "coordenadas do mundo real" ao meu sistema de coordenadas personalizado (ou, se eu seguir a sugestão de whubers e usar um sistema de coordenadas local e mentir sobre unidades (por exemplo, tratar meus nanômetros como quilômetros)

Em seguida, tenho que transferir minha matriz bidimensional numpy para um formato de arquivo DEM georreferenciado. Eu estava pensando em usar GDAL (ou melhor, as ligações Python).

A segunda pergunta é : Como criar um DEM georreferenciado a partir de dados "arbitrários", como o meu? De preferência em Python e usando bibliotecas de código aberto.

O restante deve ser bastante fácil, apenas uma questão de usar as ferramentas de análise corretas. O problema é que essa tarefa é motivada por minha própria curiosidade, portanto, não tenho certeza do que devo fazer com um DEM em nanoescala. Isso implora ao

3ª pergunta : O que fazer com um DEM em nanoescala? Que tipo de análise pode ser feita, quais são as ferramentas apropriadas para a análise do DEM e, finalmente: é possível fazer um mapa com sombra e linhas de contorno a partir desses dados? :)

Congratulo-me com todas as sugestões e sugestões, mas lembre-se de que estou procurando alternativas gratuitas, pois esse é um projeto estritamente baseado em hobby, sem orçamento ou financiamento (e não tenho acesso a aplicativos GIS). Além disso, sei que a Bruker, a empresa que vende essas máquinas AFM, envia algum software, mas usá-lo não seria nada divertido.

Atlefren
fonte
Divertido e interessante! Você pode postar alguns dados de amostra? É necessário ter uma escala nanométrica na projeção? Pensando que talvez seja mais fácil ampliar, embora esteja "trapaceando" um pouco. Acho que você pode percorrer um longo caminho com o GDAL / ogr, embora o problema da projeção ainda precise ser resolvido. gdal.org/gdal_grid.html
alexanno
Obrigado! Acho que isso é mais um comentário do que uma resposta. Quanto à escala nanométrica, eu diria que tudo o que funciona é ótimo, mas uma verdadeira projeção em nanoescala seria a mais legal. Quando se trata de dados de amostra, terei que verificar se há algumas restrições, mas é basicamente uma matriz de 2 dim de valores int16.
atlefren
3
Por que você precisaria de parâmetros proj4? Você não transferirá esses dados para outro sistema de coordenadas (especialmente geográfico). No entanto, você deve poder fazer todas as suas análises sem nenhum sistema de coordenadas. O que você entende por um DEM? Existem vários tipos, como superfícies trianguladas (por exemplo, faça uma triangulação delauny) ou mapas de varredura (você já o possui). Obviamente, isso depende muito do software de análise. Obviamente, você pode criar outros mapas se eles forem necessários como saída para entender o probe. Você pode dar uma olhada em code.google.com/p/mtex para análise de grãos.
usar o seguinte comando
3
A razão pela qual acho que preciso de um CRS é esta: se eu apenas criar, digamos um GeoTIFF sem atribuir um CRS, a unidade de medida será pixels. E se eu quiser medir distâncias? E se eu tiver duas digitalizações AFM e souber como elas se relacionam (em termos de escala e deslocamento a partir de algum ponto). Ter um SIR atribuídos facilitaria a visualização vários scans de uma só vez
atlefren
1
Eu costumo lidar com esses dados definindo um sistema de coordenadas local (com uma origem coincidente com a origem da imagem) e "mentindo" sobre as unidades. Por exemplo, você pode estipular que as unidades são quilômetros quando são realmente nanômetros, o que facilita a conversão mental para frente e para trás. É claro que você não fará reprojeção, portanto isso não é problema. Configurar este sistema de coordenadas é o mesmo que georreferenciar qualquer DEM; pode ser tão simples quanto criar um arquivo mundial não rotacionado.
whuber

Respostas:

4

Bem, parece que eu resolvi os problemas 1 e 2 pelo menos. Código fonte completo no github , mas algumas explicações aqui:

Para um CRS personalizado, decidi (por sugestão da Whubers) "trapacear" e usar medidores como unidade. Encontrei um "crs local" em apatialreference.org ( SR-ORG: 6707 ):

LOCAL_CS["Non-Earth (Meter)",
    LOCAL_DATUM["Local Datum",0],
    UNIT["Meter",1.0],
    AXIS["X",NORTH],
    AXIS["Y",EAST]]

Usando Python e GDAL, é bastante fácil de ler:

def get_coordsys():
    #load our custom crs
    prj_text = open("coordsys.wkt", 'r').read()
    srs = osr.SpatialReference()
    if srs.ImportFromWkt(prj_text):
        raise ValueError("Error importing PRJ information" )

    return srs

Além disso, obter um DEM com a GDAL era bastante simples (acabei com uma geotiff de banda única). A linha parser.read_layer (0) retorna minha matriz 512x512 descrita anteriormente.

def create_dem(afmfile, outfile):

    #parse the afm data
    parser = AFMParser(afmfile)

    #flip to account for the fact that the matrix is top-left, but gdal is bottom-left
    data = flipud(parser.read_layer(0))

    driver = gdal.GetDriverByName("GTiff")
    dst_ds = driver.Create(
        outfile,
        data.shape[1],
        data.shape[0],
        1 ,
        gdal.GDT_Int16 ,
    )

    dst_ds.SetGeoTransform(get_transform(parser, data))
    dst_ds.SetProjection(get_coordsys().ExportToWkt())
    dst_ds.GetRasterBand(1).WriteArray(data)
    dst_ds = None

A parte mais tríplice foi descobrir como "georreferenciar" corretamente meu arquivo. Acabei usando o SetGeoTransform , obtendo os parâmetros da seguinte forma:

def get_transform(parser, data):
    #calculate dims
    scan_size, x_offset, y_offset = parser.get_size()
    x_size = data.shape[0]
    y_size = data.shape[1]
    x_res = scan_size / x_size
    y_res = scan_size / y_size

    #set the transform (offsets doesn't seem to work the way I think)
    #top left x, w-e pixel resolution, rotation, 0 if image is "north up", top left y, rotation, 0 if image is "north up", n-s pixel resolution
    return [0, x_res, 0, 0, 0, y_res]

Esta última parte é provavelmente a que mais tenho dúvidas, o que realmente estava procurando era algo line * gdal_transform -ullr *, mas não consegui encontrar uma maneira de fazer isso programaticamente.

Consigo abrir meu GeoTIFF no Qgis e visualizá-lo (e compará-lo visualmente com o resultado do programa Bruker parece correto), mas não respondi minha pergunta 3; o que fazer com esses dados. Então, aqui estou aberto a sugestões!

Atlefren
fonte
Um desafio interessante poderia ser comparar as distâncias no DEM com as distâncias entre os lugares do mundo para dar aos espectadores uma idéia de quão pequena é a nanoescala. Por exemplo, htwins.net/scale2
blah238: