深度マップとノーマルマップとは?
深度マップ(depth map)
- 各ピクセルごとに「カメラからの距離」を持たせた画像です。
- 一般的には手前ほど白く、奥ほど黒くなります。
ノーマルマップ(normal map)
- 各ピクセルごとに「面の向き(法線ベクトル)」を RGB で符号化した画像です。
- どの方向を向いた面なのかが分かるので、リライトや 3D っぽい変形に使われます。
単眼深度推定
- 1 枚の RGB 画像から深度マップを推定するタスクです。
- 本当に正確な深度を求めようと思ったら、LiDAR やステレオカメラなど複数センサーが必要ですが、単眼深度推定は「1 枚の写真だけから、擬似的な奥行き情報を復元しよう」という試みです。
- 深度とノーマルは近い情報なので、両方を同時に推定できるモデルも多いですね。
単眼深度推定の代表モデル
MiDaS / ZoeDepth(拡散モデル以前の定番)
拡散モデルが一般化する前は、MiDaS や ZoeDepth が単眼深度推定の定番モデルでした。
MiDaS_Depth-Normal_Map.json
{
"id": "7dc3def5-a895-4b0c-b417-14463917dad2",
"revision": 0,
"last_node_id": 5,
"last_link_id": 4,
"nodes": [
{
"id": 4,
"type": "PreviewImage",
"pos": [
1247.6461167320394,
490.11986803330626
],
"size": [
327.82870022539464,
258
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 3
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.75",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
},
{
"id": 2,
"type": "MiDaS-NormalMapPreprocessor",
"pos": [
1005.425383378875,
806.6054384302507
],
"size": [
210,
106
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 2
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4
]
}
],
"properties": {
"cnr_id": "comfyui_controlnet_aux",
"ver": "12f35647f0d510e03b45a47fb420fe1245a575df",
"Node name for S&R": "MiDaS-NormalMapPreprocessor"
},
"widgets_values": [
6.283185307179586,
0.1,
512
],
"color": "#232",
"bgcolor": "#353"
},
{
"id": 3,
"type": "LoadImage",
"pos": [
558.9991789425821,
627.1175485569306
],
"size": [
355.980078125,
350.29999999999995
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
1,
2
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.75",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"bridge.jpg",
"image"
]
},
{
"id": 5,
"type": "PreviewImage",
"pos": [
1247.067690643409,
806.6054384302507
],
"size": [
334.59053343350865,
262.5289256198346
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 4
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.75",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
},
{
"id": 1,
"type": "MiDaS-DepthMapPreprocessor",
"pos": [
1005.425383378875,
490.11986803330626
],
"size": [
210,
106
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 1
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
3
]
}
],
"properties": {
"cnr_id": "comfyui_controlnet_aux",
"ver": "12f35647f0d510e03b45a47fb420fe1245a575df",
"Node name for S&R": "MiDaS-DepthMapPreprocessor"
},
"widgets_values": [
6.283185307179586,
0.1,
512
],
"color": "#232",
"bgcolor": "#353"
}
],
"links": [
[
1,
3,
0,
1,
0,
"IMAGE"
],
[
2,
3,
0,
2,
0,
"IMAGE"
],
[
3,
1,
0,
4,
0,
"IMAGE"
],
[
4,
2,
0,
5,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.9090909090909091,
"offset": [
-458.99917894258215,
-390.11986803330626
]
},
"frontendVersion": "1.34.2",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
-
MiDaS
- カメラパラメータがバラバラな「雑多な画像」からでも相対深度を推定できるように学習されたモデル。
- 「相対的にどちらが手前か・奥か」が分かればよい用途で広く使われてきました。
-
ZoeDepth
- 相対深度とメートル単位の深度を統一的に扱うことを目指したモデル。
新しい workflow でこれを使う意味はあまりありませんが、古い workflow で見かけることがあるので、名前だけ覚えておきましょう。
Depth Anything 系
最近の主流は Depth Anything / Depth Anything V2 / V3 といった深度推定の基盤モデルです。
{
"id": "7dc3def5-a895-4b0c-b417-14463917dad2",
"revision": 0,
"last_node_id": 7,
"last_link_id": 9,
"nodes": [
{
"id": 3,
"type": "LoadImage",
"pos": [
558.9991789425821,
627.1175485569306
],
"size": [
355.980078125,
350.29999999999995
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
8
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.75",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"bridge.jpg",
"image"
]
},
{
"id": 4,
"type": "PreviewImage",
"pos": [
1222.0552076411293,
627.1175485569306
],
"size": [
469.0687002253949,
355.46000000000004
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 9
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.75",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
},
{
"id": 7,
"type": "DepthAnythingV2Preprocessor",
"pos": [
946.7014370612255,
627.1175485569306
],
"size": [
243.6315905862604,
82
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 8
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
9
]
}
],
"properties": {
"cnr_id": "comfyui_controlnet_aux",
"ver": "12f35647f0d510e03b45a47fb420fe1245a575df",
"Node name for S&R": "DepthAnythingV2Preprocessor"
},
"widgets_values": [
"depth_anything_v2_vitl.pth",
512
],
"color": "#232",
"bgcolor": "#353"
}
],
"links": [
[
8,
3,
0,
7,
0,
"IMAGE"
],
[
9,
7,
0,
4,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 1.2100000000000009,
"offset": [
-458.99917894258215,
-527.1175485569306
]
},
"frontendVersion": "1.34.2",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
ComfyUI で深度マップを作るときは、ControlNet の前処理として使うのがほとんどだと思いますが、とりあえずこれを使っておけば OK です。
拡散モデル由来の深度・ノーマル推定
拡散モデルが普及してからは、「生成モデルが持っている世界知識を、他のタスクにも使おう」という方向の研究も出てきました。
誤解を恐れずいえば、「深度マップ風に絵柄変換している」 ようなものです。
Marigold
Marigold は Stable Diffusion 2 をベースに、「深度推定タスク用に微調整したモデル」です。
画像生成モデルを画像生成以外で使うというアイデアが他にあまり無かったため、当時はかなり注目されました。
ただ、1 枚画像生成しているのとほぼ同じだけの計算コストがかかるため、単なる下処理としては少々ヘビーです。
Lotus
Lotus は、「拡散モデルのアーキテクチャを使うが、ノイズ予測ではなく深度や法線そのものを出す」タイプの dense prediction モデルです。
LBM(Latent Bridge Matching)
LBM は Stable Diffusion XL をベースにした「1 ステップ image-to-image」のための枠組みですが、その中に深度推定 / 法線推定の派生モデルがあります。