01 なぜ生データから元画像を取り出すのか
PortalCamのスキャンをLCC Studioで書き出すと、3DGSと点群、それにLiDARメッシュが出てきます。ここまでで映像制作にはほぼ困りませんが、現場を歩いたときのカメラそのものの4K画像が別に欲しい場面があります。3DGSからは作れない使いどころが2つあります。
- AIの参照素材として使う ── 3DGSのレンダリング画像より、実写の4K画像のほうが背景修正・生成AIの参照精度が上がります。
- 別のパイプラインでの3D再構成を試す ── フォトグラメトリなど、3DGS以外の手法にも同じ現場データを流用できないか検証できます(この記事の後半で、実際に試した結果を正直に書きます)。
PortalCamのLCC StudioにもGUIから画像を書き出す機能はありますが、この記事ではGUIを開かず、CLIツールだけで完結する方法を使います。バッチ処理や自動化に組み込みやすいためです。
02 PortalCamのスキャン成果物の中身
抽出の前に、PortalCamが1回のスキャンで作るフォルダの中身を把握しておきます。ShotData/<スキャン名>/ 配下は、だいたい次のような構成になっています。
ShotData/<スキャン名>/
├─ 2026-XX-XX-XXXXXX.xbin # 生センサー記録(画像+LiDAR+IMU+GNSS)
├─ ply/ply-result/
│ ├─ point_cloud/iteration_100/point_cloud.ply # 3DGS本体
│ └─ cameras.json # ダミー(startup.jpgの1件のみ・使えない)
├─ Lcc2/lcc2-result/ # LCC2書き出し(3dgs/*.sog+mesh/*.ply+info/poses.json)
├─ mesh-files/<スキャン名>.obj # LiDARメッシュ(粗い。数万頂点・三角形サイズ20cm前後)
└─ project_data/
├─ poses.csv # 移動軌跡(ts,x,y,z,qx,qy,qz,qw)
└─ log/project.json # DeviceInfo.CameraList でカメラ構成が分かるこの中で今回使うのは、いちばん重いファイルである.xbinだけです。ファイルサイズは撮影時間に比例し、数分のスキャンで1GB前後になります。
03 xBinの正体:JPEGではなくH.264動画
.xbinを実際にバイナリ解析すると、正体はXBAG形式(マジックナンバー「XBAG」)の、ROSバッグに似た「センサーデータ多重化コンテナ」でした。カメラ映像・LiDAR点群・IMU・GNSSが時系列で1本のファイルに混在しています。
自前でH.264ストリームをデマックスしてffmpegに渡す方法もありますが、XBAGのレコード境界を正しく辿る実装が要るため手間がかかります。次の章で使うXGRIDS純正のCLIツールなら、この工程を意識せずに済みます。
04 4K元画像を抽出するコマンド
使うツールは、LixelStudioに同梱されているextract_images_h264.exeです。LCC StudioやLixel Studioを起動する必要はなく、コマンド1行で完結します。
"C:\Program Files (x86)\LixelStudio\extract_images_h264.exe" ^
--hbc_path <xbinのパス> --out_dir <出力先> ^
--out_fps 5 --prj_version 1 --device_type 4 --use_blur_detect 1--prj_version 1 は省略できません省略すると、エラーメッセージも出さずに「hbc not exsit」とだけ表示して無言で終了します。.hbc形式なら0、.xbin形式なら1を指定します。--device_typeは撮影機材を指定するフラグですが、PortalCamは選択肢の一覧に載っていません。実際に試した結果、次の値が正解でした。
| device_type | 対象機材 | 結果 |
|---|---|---|
| 1 | Lixel L2 | 0枚 |
| 3 | Lixel L2 Pro | 0枚 |
| 4 | Lixel K1 (PortalCamはこれを指定する) | 抽出成功 |
| 5 / 6 | (他機材) | 0枚 |
この2つのフラグさえ合わせれば、あとは指定した--out_dirの下にimages/camera_0/とimages/camera_1/ができ、4000×3000(1200万画素)の魚眼JPEGがタイムスタンプ付きファイル名で並びます。なお--out_fpsは指定しても実質効かず、元データの全フレームがそのまま出力されます。
fisheye2perspective.exeで透視投影に変換します。この記事の冒頭とこのあとの図版も、変換後のものです。05 4カメラのうち2台しか出せない制約
PortalCamのカメラ構成はproject_data/log/project.jsonのDeviceInfo.CameraListで確認でき、left_main / left_seco / right_main / right_seco の4眼です。.xbinのヘッダにも、この4チャンネル分の定義がバイナリ内に存在します。
ところがextract_images_h264.exeが実際にデコードするのはleft_mainとright_mainの2本だけです。seco側を出力する方法は今のところ見つかっていません。
幸い、camera_0とcamera_1はタイムスタンプの差が0msの同期ステレオペアになっているので、視差情報そのものは確保できています。
06 検証:抽出画像からのフォトグラメトリは全滅
ここからは条件付きの結論です。「4K元画像が取れるなら、フォトグラメトリでメッシュも作れるのでは」と考え、会議室スキャン(82地点×2眼=163枚)で実際に試しましたが、現時点ではこの道は塞がっています。
fisheye2perspective.exeで透視投影(2000×2000・水平画角100°)に変換してから読み込んでも、Aligning Imagesの工程でCPU使用量がゼロのまま止まります。実測でCPU時間593秒消費後、38分間まったく進捗が動かず、メモリ使用量が1GBから0.29GBまで解放され、メインウィンドウが操作不能になったため強制終了しました。出力は0件です。0xC0000142で即座に落ちます。原因はWindowsのSmart App Controlが未署名DLL(cholmod-*.dll)をブロックしていることです。Smart App Controlの無効化はWindowsの再インストールでしか元に戻せない不可逆操作のため、この検証では実施していません。本質的な原因は枚数や間隔の問題です。82地点×2眼という疎な撮影では、特徴点マッチングが成立しません。PortalCamは歩きながら連続的に3DGS用のデータを集める設計であり、フォトグラメトリが前提とする「1点にとどまって高いオーバーラップ率で撮る」撮り方とは根本的に噛み合いません。加えて、検証した会議室は無地の壁が多く、手がかりになる特徴点自体が少ない現場でした。魚眼から透視投影への変換自体は問題なく機能しており(163枚を8.2秒で処理)、詰まっているのはあくまで再構成側です。
07 使いどころとまとめ
この記事の流れをまとめると、PortalCamの生データ(.xbin)はXBAG形式のH.264動画で、extract_images_h264.exeに--prj_version 1と--device_type 4を指定すれば4K元画像を抽出できる、という一本道です。ただし4眼のうち出せるのは2眼のみで、抽出画像そのものからのフォトグラメトリ再構成は現状うまくいっていません。
いちばん実用的な使いどころは、AIの参照素材です。抽出した連番フレームは現場の実写そのものなので、Nano Banana ProやGeminiで背景の破綻を修正するときの参照、Higgsfield(SeeDance)の@location要素として強力に効きます。実際のAI活用ワークフローは3DGSから「空撮カット」を生成する方法で詳しく解説しているので、あわせて参照してください。
生データの取り扱いや3DGS制作についてご相談があれば、お気軽にお問い合わせください。
PortalCamの生データ活用・カスタムスキャンのご相談
AI参照素材としての元画像出力や、現場ごとの撮影条件に合わせたスキャン設計など、生データレベルでの調整が必要な案件はお気軽にご相談ください。
お問い合わせ →