Main Content

segmentGroundSMRF

SMRF アルゴリズムを使用して LiDAR データから地面をセグメント化

R2021a 以降

説明

groundPtsIdx = segmentGroundSMRF(ptCloud) は、単純なモルフォロジー フィルター (SMRF) アルゴリズムを使用して、入力点群 ptCloud を地面と地面以外の点にセグメント化します。SMRF アルゴリズムの詳細については、単純なモルフォロジー フィルターを参照してください。

groundPtsIdx = segmentGroundSMRF(ptCloud,gridResolution) は、グリッド要素の次元を追加で指定します。

[groundPtsIdx,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(___) は、前述の構文の任意の入力引数の組み合わせを使用して、地面の点のインデックスに加え、地面の点と地面以外の点を個別の pointCloud オブジェクトとして返します。

[___] = segmentGroundSMRF(___,Name=Value) は、1 つ以上の名前と値の引数を使用してオプションを指定します。たとえば、ElevationThreshold=0.4 は、地面以外の点を識別するための高度のしきい値を 0.4 に設定します。

すべて折りたたむ

アンオーガナイズドの航空点群で地面をセグメント化します。

aerialLidarData2.las のデータにアクセスするためのlasFileReaderオブジェクトを作成します。

fileName = fullfile(toolboxdir("lidar"),"lidardata","las", ...
           "aerialLidarData2.las");
lasReader = lasFileReader(fileName);

関数readPointCloudを使用して、点群データを LAS ファイルから読み取ります。

ptCloud = readPointCloud(lasReader);

点群から地面のデータをセグメント化します。

[groundPtsIdx,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF(ptCloud);

地面と地面以外の点を可視化します。

figure
pcshowpair(groundPtCloud,nonGroundPtCloud)

Figure contains an axes object. The axes object contains 2 objects of type scatter.

オーガナイズド点群から地面をセグメント化して除去します。

点群データをワークスペースに読み込みます。この点群はハイウェイのシナリオで取得されたものです。

ld = load("drivingLidarPoints.mat");

入力点群を表示します。

pcshow(ld.ptCloud)
xlim([-40 40])
ylim([-50 50])

Figure contains an axes object. The axes object contains an object of type scatter.

点群から地面のデータをセグメント化します。

[~,nonGroundPtCloud,groundPtCloud] = segmentGroundSMRF( ...
  ld.ptCloud,MaxWindowRadius=5,ElevationThreshold=0.1,ElevationScale=0.25);

地面以外の点を可視化します。

figure
pcshow(nonGroundPtCloud)
xlim([-40 40])
ylim([-50 50])

Figure contains an axes object. The axes object contains an object of type scatter.

入力引数

すべて折りたたむ

点群データ。pointCloud オブジェクトとして指定します。

各グリッド要素の次元。正のスカラーとして指定します。関数は、グリッド サイズを使用して入力点群を xy 方向に沿ってグリッドにサンプリングすることで最小表面マップを作成します。グリッド分解能の値を小さくすると、地面以外の点が地面として返される可能性があります。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

名前と値の引数

オプションの引数のペアを Name1=Value1,...,NameN=ValueN として指定します。ここで、Name は引数名、Value は対応する値です。名前と値の引数は他の引数の後に表示されなければなりませんが、ペアの順序は重要ではありません。

R2021a より前は、名前と値をそれぞれコンマを使って区切り、Name引用符で囲みます。

例: segmentGroundSMRF(ptCloud,ElevationThreshold=0.4) は、地面以外の点を識別するための高度のしきい値を 0.4 に設定します。

モルフォロジー オープニング処理における円盤型の構造化要素の最大半径。正の整数として指定します。小さい半径を指定することで、大きな建物を地面としてセグメント化できます。この値を大きくすると、関数の計算時間が増える可能性があります。

メモ

既定値は航空 LiDAR データ向けの効果的な値になっています。地上データでのパフォーマンスを高めるには、MaxWindowRadius8 などのより小さい値に設定します。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

最小高度表面マップでグリッド要素が地面と地面以外のどちらであるかを識別するための勾配のしきい値。非負のスカラーとして指定します。関数は、グリッド要素の勾配が SlopeThreshold 未満であれば、そのグリッド要素を地面として分類します。より急峻な勾配を地面として分類するには、この値を大きくします。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

推定高度モデルで点が地面と地面以外のどちらであるかを識別するための高度のしきい値。非負のスカラーとして指定します。関数は、点と推定される地面の表面の間の高度差が ElevationThreshold 未満であれば、その点を地面として分類します。でこぼこの地面からより多くの点を含めるには、この値を大きくします。

メモ

既定値は航空 LiDAR データ向けの効果的な値になっています。地上データで最良の結果を得るには、ElevationThreshold0.1 などのより小さい値に設定します。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

高度のしきい値のスケーリング係数。非負のスカラーとして指定します。この値を大きくすることで、急勾配の地面の点を識別できます。

データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

出力引数

すべて折りたたむ

セグメント化された点群のバイナリ マップ。logical 行列または logical ベクトルとして返されます。

  • M×N×3 の形式のオーガナイズド点群の場合、groundPtsIdx は M 行 N 列の logical 行列として返されます。

  • M 行 3 列の形式のアンオーガナイズド点群の場合、groundPtsIdx は M 要素の logical ベクトルとして返されます。

この出力の要素は、点群の地面の点に対応するものは true、地面以外の点に対応するものは false になります。

地面以外の点の点群。pointCloud オブジェクトとして返されます。

地面の点の点群。pointCloud オブジェクトとして返されます。

アルゴリズム

単純なモルフォロジー フィルター (SMRF) アルゴリズム[1]では、点群データを地面と地面以外の点にセグメント化します。このアルゴリズムは 3 つの段階で構成されます。

  1. 点群データから最小高度表面マップを作成する。

  2. 表面マップを地面と地面以外のグリッド要素にセグメント化する。

  3. 元の点群データをセグメント化する。

最小高度表面マップの作成

  1. 点群データを xy- 平面 (鳥瞰ビュー) に沿ってグリッドに分割します。gridResolution を使用してグリッド サイズを指定します。

  2. 各グリッド要素 (ピクセル) の最も低い高度 (Zmin) の値を調べます。

  3. すべての Zmin の値を組み合わせて 2 次元行列 (ラスター イメージ) にすることで、最小高度表面マップを作成します。

表面マップのセグメント化

  1. 最小表面マップにモルフォロジー オープニング処理を適用します。これにより、収縮フィルターが適用され、続いて膨張フィルターが適用されます。モルフォロジー オープニングの詳細については、モルフォロジー演算のタイプを参照してください。

  2. モルフォロジー オープニングの近傍探索は、構造化要素の形状とそのウィンドウ半径で定義されます。円盤型の構造化要素を使用し、ウィンドウ半径は 1 ピクセルから始めます。詳細については、構造化要素を参照してください。

  3. 各グリッド要素について、最小表面マップとオープニング処理後の表面マップの間の勾配を計算します。この差が高度のしきい値を超えていれば、そのピクセルを地面以外として分類します。

  4. 手順 1 ~ 3 を反復的に実行します。MaxWindowRadius で指定された最大半径に達するまで、各反復でウィンドウ半径を 1 ずつ増やしていきます。

  5. この反復プロセスにより、最終的に点群の各ピクセルが地面または地面以外のいずれかに分類されたバイナリ マスクが得られます。

元の点群のセグメント化

  1. 元の最小表面マップにバイナリ マスクを適用して地面以外のグリッドを除去します。

  2. 塗りつぶされていないグリッドをイメージ内挿法を使用して塗りつぶし、推定高度モデルを作成します。

  3. 元の点群の各点と推定高度モデルの対応する点の間の高度差を計算します。この差が ElevationThreshold を超えていれば、そのピクセルを地面以外として分類します。

  4. 各点の高度モデルの勾配を ElevationScale で乗算し、その結果を ElevationThreshold の値に加算して、急勾配の地面の点を識別します。

参照

[1] Pingel, Thomas J., Keith C. Clarke, and William A. McBride. “An Improved Simple Morphological Filter for the Terrain Classification of Airborne LIDAR Data.” ISPRS Journal of Photogrammetry and Remote Sensing 77 (March 2013): 21–30.https://doi.org/10.1016/j.isprsjprs.2012.12.002.

拡張機能

GPU コード生成
GPU Coder™ を使用して NVIDIA® GPU のための CUDA® コードを生成します。

バージョン履歴

R2021a で導入