ボクセルと点群を 測る ための一角です。すべて Fullseye の登録 op の実出力で、素材は合成データのみ(実データ・AI 生成素材は使っていません)。図に焼き込んだ数字は 1 つ残らずその場の計算結果で、乱数は seed 20260902 固定なので再生成でバイト列が一致します。
断層(スライスを送る)ものは静止画にせず GIF にしてあります。各コマに位置・単位・実測値を焼いてあるので、止めた 1 コマだけでも読めます。

↑ 処理領域(domain)でメモリが 1/84 になる ―― 192³ の視野に浮かぶ合成部品を輪切りで送りながら、元ボリューム・domain マスク・切り出し後・貼り戻しを並べた。前景は全体の 0.42 % しかないので、vol_crop_domain でメモリは 56.62 MB → 0.678 MB(1/83.5)、同じ vol_gradient_magnitude が触る voxel も 7,077,888 → 84,747(同じく 1/83.5)。壁時計の実行時間も実測しているが、再生成のたびに変わるので図には焼かず _wing3d_meta.json に置いた。vol_uncrop の貼り戻しは元と bit 一致。 使用 op: vol_bounding_box, vol_crop_domain, vol_reduce_domain, vol_uncrop, vol_gradient_magnitude。

↑ 境界だけ持つと 6 % に痩せる ―― 中実の球(267,731 voxel)を vol_boundary で内側 1 層の殻にすると 6.1 %(16,418 voxel)まで痩せる。その殻を vol_boundary_points で mm 座標の点群にして fit_sphere3 に渡すと、中心誤差 0.000 mm(真値 (25.6, 25.6, 25.6) mm)。半径だけは -0.175 mm ずれる — 殻が「内側 1 層」だからで、これは消さずに図に書いてある。 使用 op: vol_boundary, vol_boundary_points, fit_sphere3。
↑ run-length で 1/71 ―― 256³ の合成部品を run-length で持つと 1/71(16.78 MB → 0.237 MB、19,764 run)。しかも展開せずに体積 1,610,948 voxel を dense を一度も作らずに返し、集合演算(球 ∪ 軸 = 1,508,456 voxel)も run のまま解ける。decode の往復は bit 一致。所要時間も実測してあるが、壁時計は再生成のたびに変わるので図には焼かず _wing3d_meta.json に置いた。 使用 op: vol_rle_encode, vol_rle_decode, vol_rle_volume, vol_rle_bbox, vol_rle_centroid, vol_rle_union, vol_rle_intersect, vol_rle_difference。

↑ CT の「窓」で同じ体が 3 通りに見える ―― 同じ合成 HU ボリュームを vol_window_level の 3 つの窓で見る。軟部組織窓では体積の 67.1 % が黒へ潰れ肋骨は白飛びし、骨窓では白飛びが 0.0 % まで下がって骨梁が読め、肺野窓では黒潰れが 0.0 % で肺の中身が出る。下の折れ線が窓そのもの(HU → [0,1] の一次写像 + クリップ)。 使用 op: vol_window_level。
↑ Frangi 対 Sato ―― 否定対照(粒状度)を並べて初めて分かる ―― 管 1 本と球 2 個だけの合成 CT に、管状度 2 種と粒状度 1 種を掛けた。vol_frangi は管を球より 1.26 倍強く出すが、vol_sato は 0.97 倍でほとんど区別しない。否定対照の vol_hessian_blobness は 0.32 倍 = 管より球を選び、向きがきれいに逆転する。「血管が光った」だけでは管状度の証明にならない、という当たり前を図にした。 使用 op: vol_frangi, vol_sato, vol_hessian_blobness。

↑ 3-D スケルトンをグラフにする ―― 合成した枝分かれ構造(8,690 voxel)を skeletonize_vol に通すと 192 voxel の 1 voxel 幅の針金になる(2.21 %)。そこから枝 4 本・分岐 1 か所・端点 4 点をグラフとして取り出した。白が分岐、ローズが端点、枝は連結成分ごとに色分け。ターンテーブルで1 周するとつながり方が読める。 使用 op: skeletonize_vol, skeleton_branches3d, skeleton_junctions3d, skeleton_endpoints3d。
↑ virtual probe で壁厚 2.000 mm(真値 2.000 mm) ―― 外径 10.000 mm / 内径 8.000 mm の合成パイプにプローブを 1 本だけ刺す。vol_edge_probe が 4 つのエッジをサブサンプル精度で拾い、vol_wall_thickness が立ち上がり→立ち下がりの対から壁厚 2.0000 mm / 2.0000 mm(真値 2.000 mm)を返す。平滑化 sigma を 3.0 まで上げると 2.1252 mm (+6.3 %)に太る — ノイズ対策がそのまま寸法の偏りになる、という測定の基本も一緒に。 使用 op: vol_profile_line, vol_edge_probe, vol_wall_thickness。

↑ Richardson-Lucy ―― 前方一貫性 0.033x に対し真値 RMSE は 0.689x ―― sigma 2.0 のガウス PSF でぼかした合成ボリュームを vol_richardson_lucy で反復復元する。復元をもう一度ぼかして観測と比べる前方一貫性は 0.033 倍まで一気に落ちるのに、真値との RMSE は 0.689 倍までしか下がらない。残っているのは球のふちの階段で、「観測をよく説明できた」ことは「真値に近い」ことではない ―― という反例をそのまま展示にした。 使用 op: vol_gaussian_psf, vol_richardson_lucy。

↑ visual hull ―― 影を重ねて形を削り出す ―― L 字の合成物体を 16 方向から撮ったシルエットで visual_hull を彫る。1 枚では真の体積の 5.12 倍という柱状の塊だが、枚数を足すと 16 枚で 1.24 倍(IoU 0.755)まで縮む。ただし L 字の凹みは何枚重ねても埋まらない ―― これは実装の粗さではなく visual hull の原理的な限界で、収束先が真値でないことが図から読める。 使用 op: visualhull.look_at, synthesize_silhouette, visual_hull。

↑ 外から抱く箱(OBB)と中に入る箱(inner_box3) ―― z 軸まわりに 30° 傾けた合成直方体(13,617 voxel)に 3 つの箱を同時に描いてターンテーブルで 1 周させた。軸平行の AABB は voxel 数の 1.99 倍まで膨らむのに、obb(PCA で向きを合わせた外接箱)は 0.94 倍まで縮み、半幅は 19.99 / 10.00 / 8.00 voxel (真値 20 / 10 / 8)とほぼ真値。1 倍を切るのは、点群が voxel の「中心」の集まりでその外接を測っているから(縁の半 voxel が入らない)。逆に inner_box3 の最大内接箱は 0.32 倍まで痩せる。掴み幅を決めるなら OBB、中を部品が通るかを見るなら内接箱。 使用 op: obb, inner_box3, vol_bounding_box。

↑ 点群レジストレーション ―― ICP 29 回 / GICP 5 回 ―― 合成した表面点群(3100 点)を 22° 回して平行移動したものを、icp_point2point_3d で戻す。初期 RMSE 3.804 が 29 反復で 1.8e-14 まで落ち、復元した姿勢の誤差は回転 1.7e-06 度・並進 5.6e-15。面の共分散を使う gicp は同じ答えに 5 反復で着く。 使用 op: icp_point2point_3d, gicp。
↑ 異方性ボクセル ―― spacing を忘れると体積が 4.17 倍 ―― z だけ粗い spacing (1.5, 0.4, 0.4) mm/voxel でサンプリングした合成だ円体(真の体積 19301.9 mm³)。vol_region_props に spacing を渡せば 19273.2 mm³(-0.15 %)だが、渡し忘れると 80305(+316 %、4.17 倍)になる。例外は飛ばない。もっともらしい数字が静かに返るだけ、というのがこの展示の要点。 使用 op: vol_label, vol_region_props, vol_boundary_points。

↑ MIP と X 線投影のターンテーブル ―― 合成 CT ボリューム(96³)を render_volume_projection で 1 周させた。左は最大値投影(MIP、骨窓)で光線上の最大値だけを拾うので骨が浮き、右は減衰積算(X 線)で厚みが出る。投影 投影は 72 枚(所要時間の実測は _wing3d_meta.json)。正規化の上限は全フレーム共通にしてある ―― 1 枚ごとに正規化すると回転中に明るさがちらついて、形の変化と見分けがつかなくなる。 使用 op: vol_window_level, render_volume_projection。

↑ 距離変換で局所の太さを測る(最大内接半径 4.528 mm) ―― 合成した 3 本の管に vol_distance_transform を掛けると、各ボクセルが「ふちから何 mm 離れているか」になる。その最大値が最大内接球の半径 = 局所の太さで、実測 4.5277 mm(真値 4.500 mm、差 +0.0277 mm — 離散格子でふちが半 voxel 内側に来るぶん)。虹の等高線は 0.5 mm ごと。 使用 op: vol_distance_transform。
↑ 連結性の定義だけで殻の厚みが 1.9 倍変わる ―― 半径 30 voxel の合成球(112,931 voxel)の殻を、vol_boundary の connectivity(6 / 18 / 26)と side(inner / outer)だけ変えて 6 通り取った。面だけ触れる 6 近傍の内側殻は 9,170 voxel(8.12 %)、斜めの接触も数える 26 近傍の外側殻は 17,570 voxel(15.56 %)で、同じ形なのに 1.92 倍違う。「表面のボクセル数」という言い方が定義抜きでは意味を持たない、という 6 枚。手前半分を切って厚みが見えるようにしてある。 使用 op: vol_boundary。

↑ CT のかたまりが寸法になるまで(7 工程) ―― ノイズ付きの合成 CT(176³、spacing 0.6 mm)が寸法になるまでの 7 工程をコマ送りに束ねた。窓 → 二値化 → ラベリング(連結成分 1 個)→ 最大成分(5816.9 mm³、球形度 0.4702)→ vol_crop_domain でメモリ 1/7.7 → 細線化(枝 5 / 分岐 2 / 端点 4)→ 距離変換で最大内接半径 4.8374 mm(真値 4.800 mm)。各コマに工程名と進捗が焼いてあるので、止めた 1 コマでも読める。 使用 op: vol_window_level, vol_label, vol_region_props, vol_crop_domain, vol_uncrop, skeletonize_vol, skeleton_branches3d, skeleton_endpoints3d, skeleton_junctions3d, vol_distance_transform。

↑ 断層を送る ―― z = 48 / 95 は 38.40 mm のこと ―― 合成 CT(96×128×128、spacing (0.8, 0.3, 0.3) mm)を 1 スライスずつ 96 コマ送る。各コマに添字と物理位置の両方(z = 48 / 95 = 38.40 mm)と位置バーを焼いた。1 スライス送りは 0.80 mm、面内 1 画素は 0.30 mm = 0.37 倍なので、下の折れ線のとおり「添字を 1 つ動かす」は軸ごとに違う距離を意味する ―― 異方性 CT でいちばん踏みやすい段差。 使用 op: vol_window_level。

↑ 3 直交断面(MPR)とクロスヘア ―― 同じ 1 点を 3 方向から見る MPR。axial(vol[z])・coronal(vol[:, y, :])・sagittal(vol[:, :, x])を横に並べ、らせん状の目印を追いながら 3 本のクロスヘアを同時に動かした。各パネルにどの軸が横でどの軸が縦かを書き、+x に球・-y に横棒・+z にリングという非対称なランドマークを入れてある ―― 軸の入れ替わりや左右反転が起きたら、この 3 つの位置がずれて必ず露見する(3 直交断面そのものは配列の基本スライス、コントラストは vol_window_level、線は imagedraw の op)。 使用 op: vol_window_level, imagedraw.draw_line。

↑ 斜めに切ると円が楕円になる(長径は 1/cos で伸びる) ―― 半径 5.00 mm の合成円柱を、切断面を 0° から 70° まで倒しながら切る(vol_rotate の逆回し)。短径は角度によらず 10.000 mm のままなのに、長径は 2r / cos θ に沿って伸び、70° では 29.238 mm = 2.92 倍になる。36 角度(0°〜70°)すべてで理論値との差は最大 0.0000 mm(0.00 画素)。「斜めの断面で測った直径」をそのまま寸法にしてはいけない、という一本。 使用 op: vol_rotate。

↑ CT の窓を掃引する ―― 見えるものは窓が決めている ―― 同じ 1 枚の断面に vol_window_level の窓だけを 70 通り当てる。center を動かすと明るさの基準が、width を動かすと捨てる範囲が変わる。各コマに center / width の実数値と、黒潰れ・白飛びの割合、6 つの組織が「いま何色に見えるか」を焼いた。軟部窓では骨が 1.00 で飽和し、骨窓では軟部と肺が 0 付近に沈む ―― どちらも情報を捨てている、というのが 1 本で見える。 使用 op: vol_window_level。

↑ 等値面のしきい値で面が育ち、くびれ、割れる ―― 2 つの球をぼかして重ねた合成ボリュームに voxel_to_mesh(marching cubes)を掛け、level を 0.06 から 0.82 まで 40 段階で動かした。表面積は 6679 → 2842 voxel² へ縮み、level 0.742 を超えると 1 つだった面が 2 つに割れる。各コマに level・頂点数・三角形数・表面積・連結成分数を焼いてある。しきい値を書かない 3D 計測は再現できない、ということでもある。 使用 op: voxel_to_mesh, mesh_area。

↑ 管に沿って切る ―― 軸に直交しないと内径が 1.13 倍に太る ―― 28° 傾いた合成管(中央に狭窄)を 49 断面ぶん送る。軸に直交する断面で測った短径は真の内径をほぼそのまま返す(平均誤差 0.0206 mm)のに、素朴に z 方向へ切った断面の長径は 1/cos θ = 1.133 倍に伸びて平均 0.5776 mm ずれる。狭窄部では真値 2.801 mm が素朴断面では 3.217 mm ―― 狭窄が浅く見えてしまう。 使用 op: vol_rotate。