> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-zh/tu-xiang-chu-li/depth-anything.md).

# Depth Anything

在 Clore.ai 上使用 Depth Anything 进行单目深度估计

使用 Depth Anything 从单张图像估计深度。

{% hint style="success" %}
所有示例都可以在通过以下方式租用的 GPU 服务器上运行 [CLORE.AI 市场](https://clore.ai/marketplace).
{% endhint %}

## 在 CLORE.AI 上租用

1. 访问 [CLORE.AI 市场](https://clore.ai/marketplace)
2. 按 GPU 类型、VRAM 和价格筛选
3. 选择 **按需** （固定费率）或 **竞价** （出价）
4. 配置你的订单：
   * 选择 Docker 镜像
   * 设置端口（SSH 用 TCP，Web UI 用 HTTP）
   * 如有需要，添加环境变量
   * 输入启动命令
5. 选择支付方式： **CLORE**, **BTC**，或 **USDT/USDC**
6. 创建订单并等待部署

### 访问你的服务器

* 在以下位置查找连接信息 **我的订单**
* Web 界面：使用 HTTP 端口 URL
* SSH： `ssh -p <port> root@<proxy-address>`

## 什么是 Depth Anything？

Depth Anything 提供：

* 最先进的深度估计
* 适用于任何图像
* 无需立体相机
* 快速推理

## 模型变体

| 模型                   | 大小   | 显存    | 速度   |
| -------------------- | ---- | ----- | ---- |
| Depth-Anything-Small | 25M  | 2GB   | 最快   |
| Depth-Anything-Base  | 98M  | 4GB   | 快    |
| Depth-Anything-Large | 335M | 8GB   | 最佳质量 |
| Depth-Anything-V2    | 多种   | 4-8GB | 最新   |

## 快速部署

**Docker 镜像：**

```
pytorch/pytorch:2.11.0-cuda12.8-cudnn9-runtime
```

**端口：**

```
22/tcp
7860/http
```

**命令：**

```bash
pip install transformers torch gradio && \
python depth_anything_app.py
```

## 访问你的服务

部署后，找到你的 `http_pub` URL 在 **我的订单**:

1. 前往 **我的订单** 页面
2. 点击你的订单
3. 找到 `http_pub` URL（例如， `abc123.clorecloud.net`)

使用 `https://YOUR_HTTP_PUB_URL` 替代 `localhost` 在下面的示例中。

## 安装

```bash
pip install transformers torch
pip install opencv-python pillow
```

## 基础用法

```python
from transformers import pipeline
from PIL import Image

# 加载深度估计管道
pipe = pipeline(
    task="depth-estimation",
    model="LiheYoung/depth-anything-large-hf",
    device="cuda"
)

# 估计深度
image = Image.open("photo.jpg")
depth = pipe(image)

# 保存深度图
depth["depth"].save("depth_map.png")
```

## Depth Anything V2

```python
from transformers import AutoImageProcessor, AutoModelForDepthEstimation
import torch
from PIL import Image
import numpy as np

# 加载模型
processor = AutoImageProcessor.from_pretrained("depth-anything/Depth-Anything-V2-Large-hf")
model = AutoModelForDepthEstimation.from_pretrained("depth-anything/Depth-Anything-V2-Large-hf")
model.to("cuda")

# 处理图像
image = Image.open("photo.jpg")
inputs = processor(images=image, return_tensors="pt").to("cuda")

with torch.no_grad():
    outputs = model(**inputs)
    predicted_depth = outputs.predicted_depth

# 插值到原始尺寸
prediction = torch.nn.functional.interpolate(
    predicted_depth.unsqueeze(1),
    size=image.size[::-1],
    mode="bicubic",
    align_corners=False,
)

# 转换为 numpy
depth = prediction.squeeze().cpu().numpy()
depth = (depth - depth.min()) / (depth.max() - depth.min()) * 255
depth = depth.astype(np.uint8)

# 保存
Image.fromarray(depth).save("depth.png")
```

## 着色深度图

```python
import cv2
import numpy as np
from PIL import Image

def colorize_depth(depth_array, colormap=cv2.COLORMAP_INFERNO):
    # 归一化到 0-255
    depth_normalized = cv2.normalize(depth_array, None, 0, 255, cv2.NORM_MINMAX)
    depth_uint8 = depth_normalized.astype(np.uint8)

    # 应用颜色映射
    colored = cv2.applyColorMap(depth_uint8, colormap)

    return Image.fromarray(cv2.cvtColor(colored, cv2.COLOR_BGR2RGB))

# 用法
depth_colored = colorize_depth(depth)
depth_colored.save("depth_colored.png")
```

## 批量处理

```python
from transformers import pipeline
from PIL import Image
import os

pipe = pipeline(
    task="depth-estimation",
    model="LiheYoung/depth-anything-large-hf",
    device="cuda"
)

input_dir = "./images"
output_dir = "./depth_maps"
os.makedirs(output_dir, exist_ok=True)

for filename in os.listdir(input_dir):
    if filename.endswith(('.jpg', '.png', '.jpeg')):
        image_path = os.path.join(input_dir, filename)
        image = Image.open(image_path)

        # 获取深度
        depth = pipe(image)

        # 保存
        output_path = os.path.join(output_dir, f"depth_{filename}")
        depth["depth"].save(output_path)
        print(f"Processed: {filename}")
```

## Gradio 界面

```python
import gradio as gr
from transformers import pipeline
import cv2
import numpy as np

pipe = pipeline(
    task="depth-estimation",
    model="LiheYoung/depth-anything-large-hf",
    device="cuda"
)

def estimate_depth(image, colormap):
    # 获取深度
    result = pipe(image)
    depth = np.array(result["depth"])

    # 着色
    depth_normalized = cv2.normalize(depth, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)

    colormaps = {
        "Inferno": cv2.COLORMAP_INFERNO,
        "Viridis": cv2.COLORMAP_VIRIDIS,
        "Plasma": cv2.COLORMAP_PLASMA,
        "Magma": cv2.COLORMAP_MAGMA,
        "Jet": cv2.COLORMAP_JET
    }

    colored = cv2.applyColorMap(depth_normalized, colormaps[colormap])
    colored = cv2.cvtColor(colored, cv2.COLOR_BGR2RGB)

    return result["depth"], colored

demo = gr.Interface(
    fn=estimate_depth,
    inputs=[
        gr.Image(type="pil", label="输入图像"),
        gr.Dropdown(
            ["Inferno", "Viridis", "Plasma", "Magma", "Jet"],
            value="Inferno",
            label="颜色映射"
        )
    ],
    outputs=[
        gr.Image(label="深度图（灰度）"),
        gr.Image(label="深度图（彩色）")
    ],
    title="Depth Anything - 深度估计"
)

demo.launch(server_name="0.0.0.0", server_port=7860)
```

## API 服务器

```python
from fastapi import FastAPI, UploadFile, File
from fastapi.responses import Response
from transformers import pipeline
from PIL import Image
import io
import numpy as np
import cv2

app = FastAPI()

pipe = pipeline(
    task="depth-estimation",
    model="LiheYoung/depth-anything-large-hf",
    device="cuda"
)

@app.post("/depth")
async def estimate_depth(image: UploadFile = File(...), colored: bool = True):
    # 加载图像
    img = Image.open(io.BytesIO(await image.read()))

    # 估计深度
    result = pipe(img)
    depth = np.array(result["depth"])

    if colored:
        depth_normalized = cv2.normalize(depth, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
        depth_img = cv2.applyColorMap(depth_normalized, cv2.COLORMAP_INFERNO)
        depth_img = cv2.cvtColor(depth_img, cv2.COLOR_BGR2RGB)
    else:
        depth_img = depth

    # 转换为字节
    output = Image.fromarray(depth_img)
    buffer = io.BytesIO()
    output.save(buffer, format="PNG")

    return Response(content=buffer.getvalue(), media_type="image/png")

# 运行：uvicorn server:app --host 0.0.0.0 --port 8000
```

## 3D 点云生成

```python
import numpy as np
import open3d as o3d
from PIL import Image

def depth_to_pointcloud(rgb_image, depth_map, focal_length=500):
    """将 RGB 图像和深度图转换为 3D 点云"""
    rgb = np.array(rgb_image)
    depth = np.array(depth_map)

    # 获取图像尺寸
    height, width = depth.shape

    # 创建网格
    u = np.arange(width)
    v = np.arange(height)
    u, v = np.meshgrid(u, v)

    # 转换为 3D 坐标
    z = depth.astype(float)
    x = (u - width / 2) * z / focal_length
    y = (v - height / 2) * z / focal_length

    # 堆叠坐标
    points = np.stack([x, y, z], axis=-1).reshape(-1, 3)
    colors = rgb.reshape(-1, 3) / 255.0

    # 创建点云
    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(points)
    pcd.colors = o3d.utility.Vector3dVector(colors)

    return pcd

# 用法
rgb = Image.open("photo.jpg")
depth = pipe(rgb)["depth"]

pcd = depth_to_pointcloud(rgb, depth)
o3d.io.write_point_cloud("output.ply", pcd)
```

## 应用场景

### 3D 照片效果

```python
def create_3d_photo(image, depth, shift=20):
    """为 3D 照片创建视差效果"""
    import cv2
    import numpy as np

    img = np.array(image)
    depth_arr = np.array(depth)

    # 归一化深度
    depth_norm = (depth_arr - depth_arr.min()) / (depth_arr.max() - depth_arr.min())

    # 创建移位版本
    shifted = np.zeros_like(img)
    for y in range(img.shape[0]):
        for x in range(img.shape[1]):
            offset = int(shift * depth_norm[y, x])
            new_x = min(x + offset, img.shape[1] - 1)
            shifted[y, new_x] = img[y, x]

    return Image.fromarray(shifted)
```

### 背景模糊（人像模式）

```python
def portrait_mode(image, depth, blur_strength=25):
    import cv2
    import numpy as np

    img = np.array(image)
    depth_arr = np.array(depth)

    # 归一化深度
    depth_norm = (depth_arr - depth_arr.min()) / (depth_arr.max() - depth_arr.min())

    # 创建模糊掩码（背景 = 高深度 = 更强模糊）
    blur_mask = depth_norm

    # 应用模糊
    blurred = cv2.GaussianBlur(img, (blur_strength, blur_strength), 0)

    # 基于深度进行混合
    mask_3d = np.stack([blur_mask] * 3, axis=-1)
    result = (img * (1 - mask_3d) + blurred * mask_3d).astype(np.uint8)

    return Image.fromarray(result)
```

## 性能

| 模型    | GPU      | 每张图像耗时  |
| ----- | -------- | ------- |
| 小型    | RTX 3060 | \~50毫秒  |
| 基础    | RTX 3060 | \~100毫秒 |
| Large | RTX 3090 | \~150毫秒 |
| Large | RTX 4090 | \~80毫秒  |
| V2-大型 | RTX 4090 | \~100毫秒 |

## 故障排查

### 深度质量较差

* 使用更大的模型变体
* 确保图像质量良好
* 检查是否有反光表面

### 内存问题

* 使用更小的模型变体
* 降低图像分辨率
* 启用 fp16 推理

### 处理缓慢

* 使用更小的模型
* 如果可能，进行批处理
* 使用 GPU 推理

## 成本估算

CLORE.AI 市场常见费率（截至 2024 年）：

| GPU       | 小时费率    | 日费率     | 4 小时会话  |
| --------- | ------- | ------- | ------- |
| RTX 3060  | \~$0.03 | \~$0.70 | \~$0.12 |
| RTX 3090  | \~$0.06 | \~$1.50 | \~$0.25 |
| RTX 4090  | \~$0.10 | \~$2.30 | \~$0.40 |
| A100 40GB | \~$0.17 | \~$4.00 | \~$0.70 |
| A100 80GB | \~$0.25 | \~$6.00 | \~$1.00 |

*价格因提供商和需求而异。请查看* [*CLORE.AI 市场*](https://clore.ai/marketplace) *以获取当前费率。*

**节省费用：**

* 使用 **竞价** 可中断工作市场——约三分之一的服务器将现货价格定得低于按需价格（中位数约优惠 13%），其余则与按需价格持平
* 使用 **CLORE** 代币支付
* 比较不同提供商的价格

## 下一步

* [ControlNet](/guides/guides_v2-zh/tu-xiang-chu-li/controlnet-advanced.md) - 使用深度进行控制
* [Segment Anything](/guides/guides_v2-zh/tu-xiang-chu-li/segment-anything.md) - 对象分割
* [3D 生成](/guides/guides_v2-zh/3d-sheng-cheng/triposr.md) - 视频深度


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-zh/tu-xiang-chu-li/depth-anything.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
