fullseye

skeleton_graph3d — 3D medial op

使い方

3D 骨格を ノード(接合点・端点)と枝(長さ・半径)のグラフに組み立てる。

skeleton_junctions3d / skeleton_endpoints3d / skeleton_branches3d は 「どの voxel がノードか/枝か」を マスクで返すだけで、どの枝がどのノードと どのノードを繋ぐかは返さない。回路にするにはその接続が要る —— 神経形態の ケーブル理論では、区画の軸方向コンダクタンスが 直径と長さで決まり、区画同士の 繋がり方が回路そのものになる。この op はその 1 段を埋める。

引数: vol: 3-D の骨格(bool か {0, 1}skeletonize_vol の出力)。中身が 塊(6 近傍がすべて前景の interior voxel がある)なら、族の他の op と 同じく内部で skeletonize_vol を先に掛ける。 distance: 任意。同形の距離変換ボリューム(vol_distance_transform の 出力)。渡すと各ノード・各枝に半径が付く。単位は渡した距離場に従う —— 物理単位が要るなら vol_distance_transform(mask, spacing) を渡す。 spacing: (sz, sy, sx)。枝の長さを 実距離で測る(EM の異方ボクセルが 既定の想定)。VolumeMeta も受ける。 min_branch_len: これ未満の末端の枝(ヒゲ)を刈る(既定 0 = 刈らない)。 単位は spacing の実距離。刈るのは「片端が端点(次数 1)で、もう 片端が次数 2 以上」の枝 —— 両端とも端点の枝は刈らない。それは それ自体が 1 つの連結成分(短い孤立した管)なので、刈ると構造ごと 消えてしまう。刈ったぶんは n_pruned_branches に返す。

返り値: dict(台帳の宣言 out 型 = table)。

* ``nodes``: ノード表。``id`` / ``z,y,x``(voxel 添字での重心。実座標は
  spacing を掛ける)/ ``kind`` / ``degree`` / ``n_voxels`` / ``radius``
  (``distance`` を渡したとき、そのノードの voxel での最大値 = 内接半径)/
  ``component``。
* ``edges``: 枝表。``u`` / ``v``(ノード id の対)/ ``length``(骨格に沿った
  実距離、spacing 込み)/ ``radius_mean`` / ``radius_min`` / ``n_points``
  (経路上の voxel 数、両端のノード voxel を含む)/ ``component``。
* ``n_nodes`` / ``n_edges`` / ``n_components`` / ``n_cycles`` /
  ``n_pruned_branches`` / ``n_skeleton_voxels`` / ``spacing`` / ``has_radius``。

規約(ここが位相を決める): * 26 近傍次数 2 の voxel は枝の途中であってノードにしない。次数 1 以下 が端点(孤立 voxel を含む)、3 以上が接合。 * 接合 voxel は 1 つとは限らない(離散骨格では分岐が数 voxel の塊になる)。 26 連結で塊にまとめて 1 ノードとして数え、座標はその重心。 * 連結成分が複数なら黙って繋がない。 n_components に本数を返し、 各ノード・各枝に component を付ける。 * 閉ループだけの成分(ノードになる voxel が 1 つも無い輪)は、その成分の 先頭 voxel を 1 つだけ種のノードに立てて自己ループの枝 1 本にする。 こうすると オイラーの関係 n_cycles = n_edges - n_nodes + n_components が輪でも成り立つ(木だと仮定していない)。 * kind刈った後の次数で決まる: 0 = isolated / 1 = endpoint / 2 = chain(輪の種ノード、または刈った結果そうなったノード)/ 3 以上 = junction。刈ると接合が次数 2 に落ちることがあり、その ノードは残る(区画の境界としては正しいが、「次数 2 はノードにしない」 という上の規約は刈る前の話であることに注意)。 * 接合の塊どうしが直接隣接している(間に次数 2 の道が無い)場合は、その 対に対して 1 本の枝を作る(長さ = 隣接する voxel 対の最短)。

検証(すべて ValueError で fail-closed): 3-D でない/空配列/NaN・Inf/ bool でも {0,1} でもない値(中間値の「たぶん前景」を黙って丸めない)/ 前景がゼロ/distance の形が違う・負・非有限/spacing が 3 つの正の 有限値でない/min_branch_len が負。細線化が要る入力で scikit-image が 無ければ ImportError

注意(honest、いずれも実測):

参考(サンプルデータ・文献)

実行できる例(この op を実際に呼ぶ検証済みサンプル)

型が繋がる次の op(table を入力に取れる)

fuse_to_voxel · mesh_select_lod

同カテゴリ(medial)

distance_ridge · skeletonize_vol · medial_axis_points · topology_signature · medial_match · skeleton_junctions3d · skeleton_endpoints3d · skeleton_prune3d


Provenance: medial.py — 3D operator registry. この per-op ノートは tools/opdocs.py md が自動生成(手編集しない)。

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.