RGB-D画像から、学習モデルを使わずに物体を分割するための古典的な実装です。
採用している定石は次の流れです。
- 深度の平滑化
- 深度から3D点群へ逆投影
- 局所幾何から法線推定
- RANSACで支配的平面を除去
- 深度差・法線差・色差から境界を作成
- 接続成分で物体インスタンス化
机上物体や床上物体のように、「大きな支持平面の上に複数物体がある」場面で特に使いやすい構成です。
segment_rgbd.py: 本体CLIgenerate_sample.py: 合成RGB-Dサンプル生成serve_segment_api.py: Webフロントエンド連携用の最小REST APIsample_data/: 生成されたテスト用データ
python3numpyscipyPillow
この実装は opencv や学習モデルを前提にしません。
まずサンプルを生成します。
cd /root/tl
python3 rgbd_object_split/generate_sample.py次に分割を実行します。
python3 rgbd_object_split/segment_rgbd.py \
--rgb rgbd_object_split/sample_data/rgb.png \
--depth rgbd_object_split/sample_data/depth.png \
--outdir rgbd_object_split/out_sample \
--fx 250 --fy 250 --cx 160 --cy 120 \
--depth-scale 1000labels.npy: 0が背景、1以上が物体ラベルforeground_mask.png: 平面除去後の前景plane_mask.png: 検出された支配平面boundary_map.png: 分割境界labels_overlay.png: RGB上にラベルを重ねた可視化scene.json: Web/REST向けの物体メタデータと3D点群サンプル
scene.json には次が入ります。
- 各物体の
label - 2D bbox
- 3D centroid
- 3D bbox
- 平均色
- Three.js系ビューアに流しやすい
sampled_points_xyzrgb - シーン全体の
scene_points_xyzrgbl
--plane-dist-thresh-m- 平面への距離しきい値
- 深度ノイズが大きいなら少し上げる
--depth-abs-thresh-m- 物体間の段差を拾う絶対深度差
- 小物体を分けたいなら少し下げる
--normal-angle-deg- 面の向きの違いを境界化する角度
- 形状差を強く取りたいなら下げる
--color-diff-thresh- 幾何だけで切れない接触物体を色差で補う
--min-region-size- 小ノイズ成分を落とす下限ピクセル数
既存のWeb画面とREST APIでつなぐことを想定して、依存追加なしの最小サーバを付けています。
起動:
python3 rgbd_object_split/serve_segment_api.py疎通確認:
curl http://127.0.0.1:8765/health分割リクエスト例:
curl -X POST http://127.0.0.1:8765/segment \
-H 'Content-Type: application/json' \
-d '{
"rgb_path": "/root/tl/rgbd_object_split/sample_data/rgb.png",
"depth_path": "/root/tl/rgbd_object_split/sample_data/depth.png",
"camera": {
"fx": 250,
"fy": 250,
"cx": 160,
"cy": 120,
"depth_scale": 1000
},
"save_outputs": true,
"outdir": "/root/tl/rgbd_object_split/out_api"
}'返り値は JSON で、フロントエンドがそのまま使えるようにしています。
- 一覧表示には
instances - 物体選択ハイライトには
label - 3D配置には
centroid_mとbbox_3d_m - 点群プレビューには
sampled_points_xyzrgb
大きい点群を毎回返すと重いので、RESTの返り値はサンプリング済みです。
- テーブル上の複数物体
- 床上に置かれた箱や道具
- 学習データを使わずにまず幾何ベースで切りたい場合
- 奥行き差がほぼ無く、色差も少ない密着物体は分離が難しいです
- 支配平面が存在しないシーンでは平面除去の効果が弱くなります
- カメラ内パラメータが大きくずれると法線推定が不安定になります