GDALを使用したナノスケールDEMの作成


14

少し奇妙な質問かもしれませんが、実際の質問の前に、背景について簡単に説明しましょう。

原子間力顕微鏡(AFM)は、要するに(そして、私の限られた知識で)研究者がマイクロおよびナノスケールで領域をスキャンできる方法です。ある種のプローブを使用して領域を「スキャン」することで機能します。それ以上のことを説明するのは難しいです。私はそれを本当に理解していないからです。私が知っていること、そして私の好奇心を引き起こしたのは、結果が実際には「高さ」値の「グリッド」であるということでした(そのポイントでのプローブの高さを表す512x512の値のマトリックス)。

それから私は考えました:さて、スケールとは別に、これは実際にはデジタル標高モデルです!また、これは、GISツールで理解できるようにDEMファイルを作成できれば、GIS分析を適用できることを意味します。

現状では、AFMマシンを備えたラボで私の重要な仕事をしており、彼女のプロジェクトの1つでそれを使用しています。私は彼女からいくつかのスキャンファイルを取得し、Python(structおよびnumpy)を使用してこれらのバイナリファイルを解析しました。

次に計画しているのは、「適切なDEMへのマッピング」パートです。私はDEMSについてある程度の知識を持っていますが、実際にそれらを生成することになると、私はかなり新しいです。

私が考えているのは、何らかの方法でデータをジオリファレンスする必要があるということです。そのためには、カスタム(平面)座標系が必要です。私の座標系では、マイクロメートルまたはナノメートルを単位として使用することを想定しています。次に、AFMでスキャンされた領域のサイズを見つけるだけです(これはバイナリファイルのどこかにあると考えられます。これは既知であると仮定してください)。

更新:解像度は異なるが同じ領域のスキャンもいくつか行っています。たとえば、2つのスキャンに関する次の情報があります。

大きな画像:

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

小さい(詳細)画像:

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

私が考えているのは、カスタム座標系の原点は0,0である必要があり、大きな画像ではピクセル0,0に座標値(0,0)を割り当て、ピクセル512,512に座標値(51443.5、51443.5)を割り当てることです)(必要な他のポイントの写真を取得すると思います)。

次に、大きい画像はピクセル(0,0)を(8776.47、1486.78)に、(512,512)を(8776.47 + 5907.44、1486.78 + 5907.44)にマッピングします

1番目の質問は次のとおりです。このような座標系のproj4 defを作成するにはどうすればよいですか?すなわち、これらの「現実世界の座標」をカスタム座標系に割り当てるには(または、whubersの提案に従い、ローカル座標系を使用してユニットについて横になっている場合(つまり、ナノメートルをキロメートルとして扱う)

次に、numpy 2次元配列をGeoreferenced DEMファイル形式に転送する必要があります。私はGDAL(または、むしろPythonバインディング)の使用を考えていました。

2番目の質問は次のとおりです。私のような「任意の」データからジオリファレンスされたDEMを作成するにはどうすればよいですか。できればPythonで、オープンソースライブラリを使用してください。

そうすれば、適切な分析ツールを使用するだけで、残りはかなり簡単になります。問題は、このタスクは私自身の好奇心によって駆動されるため、ナノスケールDEMで実際に何をするべきかはよくわかりません。これは頼みます

3番目の質問:ナノスケールDEMをどうするか?どのような分析を行うことができ、DEM分析に適したツールは何ですか?最後に、このデータから陰影起伏と等高線を使用してマップを作成することは可能ですか?

私はすべての提案とポインタを歓迎しますが、予算や資金がない厳密な趣味ベースのプロジェクトであり、ライセンスされたGISアプリケーションにアクセスできないため、無料の代替案を探していることに注意してください。さらに、これらのAFMマシンを販売しているBrukerがソフトウェアを出荷していることは知っていますが、それを使用するのは面白くないでしょう。


楽しくて面白い!サンプルデータを投稿できますか?投影にナノメートルスケールが必要ですか?少し「だましている」けれども、スケールアップするのは簡単だと思うかもしれません。ところで、投影の問題に対処する必要がありますが、GDAL / ogrで長い道のりを歩むことができると思います。gdal.org/gdal_grid.html
アレクサンノ

ありがとう!これは答えというよりもコメントだと思います。ナノメートルのスケールに関しては、どんなものでもうまくいくと思いますが、真のナノスケールのピージェクションが最もクールだと思います。サンプルデータに関しては、いくつかの制限があるかどうかを確認する必要がありますが、基本的にはint16値の2次元の行列です。
atlefren

3
なぜproj4パラメーターが必要なのですか?このデータを別の座標系(特に地理的)に転送することはありません。私見では、座標系なしですべての分析を行うことができるはずです。DEMで何を理解していますか?三角形分割されたサーフェス(三角形分割の削除など)やラスターマップ(既にこれがあります)など、いくつかのタイプがあります。もちろん、これは分析ソフトウェアに大きく依存しています。もちろん、プローブを理解するための出力として必要な場合は、他のマップを作成できます。穀物分析については、code.google.com / p / mtexをご覧ください。
ミスタピンク

3
私が(考えて)CRSが必要な理由は、これです。CRSを割り当てずにGeoTIFFを作成するだけの場合、測定単位はピクセルになります。距離を測定したい場合はどうすればよいですか?そして、もし2つのAFMスキャンがあり、それらが相互にどのように関係しているのかを知ると(スケールとある点からのオフセットの点で)。CRSを割り当てると、複数のスキャンを一度に表示しやすくなります
-atlefren

1
私は通常、ローカル座標系(原点を画像の原点と一致させる)を設定し、ユニットについて「嘘をつく」ことによって、このようなデータに対処します。たとえば、単位が実際にナノメートルである場合、単位はキロメートルであると規定できます。これにより、精神的に簡単に前後に変換できます。もちろん、再投影することはないので、それは問題ではありません。この座標系の設定は、DEMのジオリファレンスと同じです。回転していないワールドファイルを作成するのと同じくらい簡単です。
whuber

回答:


4

まあ、少なくとも問題1と2を解決したようです。githubの完全なソースコードですが、ここにいくつかの説明があります。

カスタムCRSの場合、私は(Whubersの提案に従って)メーターを「チート」し、単位としてメーターを使用することにしました。私はapatialreference.org(SR-ORG:6707)で「ローカルcrs」を見つけました:

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

PythonとGDALを使用すると、これは非常に読みやすくなります。

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

また、GDALを使用してDEMを改良することは、実際にはかなり簡単でした(最終的にはシングルバンドジオティフになりました)。行parser.read_layer(0)は、前述の512x512マトリックスを返します。

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

最もトリッキーな部分は、ファイルを適切に「ジオリファレンス」する方法を考えていたため、最終的にSetGeoTransformを使用してパラメーターを取得しました。

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]

この最後の部分は、おそらく私が最もよく知らない部分であり、本当に探していたのは* gdal_transform -ullr *という行でしたが、プログラムでこれを行う方法が見つかりませんでした。

GeoTIFFをQgisで開いて表示することができます(そして、それを適切に見えるBrukerプログラムの結果と視覚的に比較します)が、質問3にはまだ答えていません。このデータをどうするか。だから、ここで私は提案を募集しています!


興味深い課題の1つは、DEM上の距離と地球上の場所間の距離を比較して、ナノスケールがどれだけ小さいかを視聴者に知らせることです。例:htwins.net/scale2
blah238
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.