lingbot-depth-pretrain-vitl-14实战教程:Linux服务器无GUI环境下纯CLI调用流程
lingbot-depth-pretrain-vitl-14实战教程:Linux服务器无GUI环境下纯CLI调用流程
1. 引言:为什么需要纯命令行调用?
想象一下这个场景:你正在一台远程的Linux服务器上工作,这台服务器没有图形界面,只有黑底白字的终端。你部署了一个强大的深度估计模型,但发现官方文档只介绍了网页界面的使用方法。这时候,你该怎么办?
这就是我们今天要解决的问题。lingbot-depth-pretrain-vitl-14是一个基于DINOv2 ViT-L/14编码器的深度估计模型,它确实提供了方便的WebUI界面。但在实际的工程部署、自动化处理或者资源受限的环境中,我们往往需要通过纯命令行(CLI)的方式来调用它。
学习目标:通过这篇教程,你将学会如何在没有任何图形界面的Linux服务器上,通过纯命令行方式调用lingbot-depth模型,完成深度估计和补全任务。
前置知识:你只需要对Linux命令行有基本了解,知道怎么用cd、ls、curl这些命令就行。不需要你是深度学习专家,也不需要你懂Python高级编程。
教程价值:无论你是做机器人导航、3D重建,还是工业检测,掌握CLI调用都能让你的工作流程更加自动化、更加高效。更重要的是,当服务器资源紧张或者需要批量处理时,命令行方式往往是最可靠的选择。
2. 环境准备:确认你的部署状态
在开始之前,我们需要先确认几件事情。别担心,这些检查都很简单,就像开车前检查油表一样。
2.1 检查模型服务是否正常运行
首先,登录到你的Linux服务器。如果你用的是云服务商提供的实例,通常可以通过SSH连接:
ssh username@your-server-ip
登录成功后,第一件事就是检查模型服务是否已经启动。lingbot-depth镜像默认会启动两个服务:FastAPI REST服务(端口8000)和Gradio WebUI服务(端口7860。
我们可以用curl命令来快速检查:
# 检查FastAPI服务是否正常
curl -s http://localhost:8000/docs | grep -q "FastAPI" && echo "FastAPI服务正常" || echo "FastAPI服务异常"
# 检查Gradio服务是否正常(虽然我们用CLI,但检查一下也无妨)
curl -s http://localhost:7860 | grep -q "Gradio" && echo "Gradio服务正常" || echo "Gradio服务异常"
如果两个服务都正常,你会看到相应的提示。如果服务没有启动,你需要先启动它:
# 进入模型目录并启动服务
cd /root
bash start.sh
启动过程大概需要5-8秒来加载模型到GPU显存。你可以用nvidia-smi命令查看GPU使用情况,确认模型是否加载成功。
2.2 准备测试数据
模型服务正常后,我们需要准备一些测试图片。幸运的是,镜像已经自带了一些示例图片,我们直接使用就行:
# 查看示例图片目录
ls -la /root/assets/lingbot-depth-main/examples/
# 通常会有多个示例目录,比如0、1、2等
# 每个目录包含rgb.png(彩色图)和raw_depth.png(原始深度图)
让我们看看第一个示例的内容:
# 查看图片信息
file /root/assets/lingbot-depth-main/examples/0/rgb.png
file /root/assets/lingbot-depth-main/examples/0/raw_depth.png
# 如果需要查看图片尺寸(虽然看不到图片内容,但可以看元数据)
identify /root/assets/lingbot-depth-main/examples/0/rgb.png 2>/dev/null || echo "需要安装imagemagick"
如果identify命令不可用,别担心,我们后面会用Python代码来获取图片信息。
3. 基础概念:理解模型的工作模式
在开始调用之前,我们先花几分钟理解一下这个模型能做什么。这样你在使用的时候就知道该选择哪种模式,参数该怎么设置。
3.1 两种核心模式
lingbot-depth模型主要支持两种工作模式:
-
单目深度估计(Monocular Depth)
- 输入:只需要一张RGB彩色图片
- 输出:估计出的深度图
- 原理:模型从纯视觉外观推断场景的深度信息
- 适用场景:当你只有普通相机拍摄的图片时
-
深度补全(Depth Completion)
- 输入:RGB图片 + 稀疏深度图
- 输出:补全后的完整深度图
- 原理:结合视觉信息和已有的深度测量值,填补缺失的深度区域
- 适用场景:当你使用RGB-D相机(如Kinect)或LiDAR,但深度数据不完整时
3.2 理解输入输出格式
为了正确调用API,我们需要知道数据该怎么传:
- 图片格式:支持PNG、JPEG等常见格式
- 颜色空间:RGB格式,像素值范围0-255
- 深度图单位:输入深度图如果是毫米(mm),需要转换为米(m)
- 输出深度:单位是米(m),浮点数
4. 纯CLI调用:三种实战方法
现在进入正题。我将介绍三种不同的命令行调用方法,从最简单到最灵活,你可以根据需求选择。
4.1 方法一:使用curl直接调用REST API(最简单)
这是最直接的方法,适合快速测试和简单集成。模型提供了FastAPI服务,我们可以用curl命令直接调用。
4.1.1 单目深度估计示例
让我们从最简单的单目深度估计开始:
#!/bin/bash
# 保存为 test_monocular.sh
# 定义API地址
API_URL="http://localhost:8000/predict"
# 准备图片数据(base64编码)
IMAGE_PATH="/root/assets/lingbot-depth-main/examples/0/rgb.png"
IMAGE_BASE64=$(base64 -w 0 "$IMAGE_PATH")
# 构建JSON请求
JSON_DATA=$(cat <<EOF
{
"image": "$IMAGE_BASE64",
"mode": "monocular",
"return_npy": false
}
EOF
)
# 发送请求
echo "正在发送请求到模型..."
RESPONSE=$(curl -s -X POST "$API_URL" \
-H "Content-Type: application/json" \
-d "$JSON_DATA")
# 检查响应
if echo "$RESPONSE" | grep -q "status.*success"; then
echo "✓ 深度估计成功!"
# 提取深度图并保存
DEPTH_BASE64=$(echo "$RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('depth_image', ''))")
if [ -n "$DEPTH_BASE64" ]; then
echo "$DEPTH_BASE64" | base64 -d > depth_result.png
echo "✓ 深度图已保存为 depth_result.png"
fi
# 显示统计信息
echo "响应信息:"
echo "$RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin); info=data.get('info', {}); print(f'深度范围: {info.get(\"depth_range\", \"N/A\")}'); print(f'输入尺寸: {info.get(\"input_size\", \"N/A\")}'); print(f'模式: {info.get(\"mode\", \"N/A\")}')"
else
echo "✗ 请求失败"
echo "响应内容:$RESPONSE"
fi
运行这个脚本:
chmod +x test_monocular.sh
./test_monocular.sh
如果一切正常,你会看到深度估计成功的提示,并且生成一个depth_result.png文件。虽然你在命令行看不到图片内容,但可以用file命令确认文件已生成:
file depth_result.png
4.1.2 深度补全示例
深度补全需要同时提供RGB图片和稀疏深度图:
#!/bin/bash
# 保存为 test_completion.sh
API_URL="http://localhost:8000/predict"
# 准备两张图片
RGB_PATH="/root/assets/lingbot-depth-main/examples/0/rgb.png"
DEPTH_PATH="/root/assets/lingbot-depth-main/examples/0/raw_depth.png"
RGB_BASE64=$(base64 -w 0 "$RGB_PATH")
DEPTH_BASE64=$(base64 -w 0 "$DEPTH_PATH")
# 注意:这里需要相机内参
JSON_DATA=$(cat <<EOF
{
"image": "$RGB_BASE64",
"depth": "$DEPTH_BASE64",
"mode": "completion",
"fx": 460.14,
"fy": 460.20,
"cx": 319.66,
"cy": 237.40,
"return_npy": false
}
EOF
)
echo "正在发送深度补全请求..."
RESPONSE=$(curl -s -X POST "$API_URL" \
-H "Content-Type: application/json" \
-d "$JSON_DATA")
if echo "$RESPONSE" | grep -q "status.*success"; then
echo "✓ 深度补全成功!"
# 保存结果
DEPTH_BASE64=$(echo "$RESPONSE" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('depth_image', ''))")
if [ -n "$DEPTH_BASE64" ]; then
echo "$DEPTH_BASE64" | base64 -d > depth_completion_result.png
echo "✓ 补全深度图已保存为 depth_completion_result.png"
fi
else
echo "✗ 请求失败"
echo "响应内容:$RESPONSE"
fi
4.2 方法二:使用Python脚本调用(最灵活)
如果你需要更复杂的处理逻辑,或者想要批量处理多张图片,使用Python脚本是更好的选择。
4.2.1 安装必要的Python库
首先确保你有必要的Python库:
pip install requests pillow numpy opencv-python
如果已经部署了lingbot-depth镜像,这些库应该都已经安装好了。
4.2.2 完整的Python调用示例
创建一个Python脚本call_lingbot.py:
#!/usr/bin/env python3
"""
lingbot-depth模型命令行调用示例
支持单目深度估计和深度补全两种模式
"""
import requests
import base64
import json
import argparse
from pathlib import Path
import cv2
import numpy as np
from PIL import Image
import time
class LingBotDepthClient:
"""lingbot-depth模型客户端"""
def __init__(self, base_url="http://localhost:8000"):
self.base_url = base_url
self.predict_url = f"{base_url}/predict"
def image_to_base64(self, image_path):
"""将图片转换为base64字符串"""
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode('utf-8')
def save_depth_image(self, depth_base64, output_path):
"""保存base64编码的深度图"""
if not depth_base64:
print("警告:没有深度图数据")
return False
try:
depth_data = base64.b64decode(depth_base64)
with open(output_path, "wb") as f:
f.write(depth_data)
print(f"深度图已保存: {output_path}")
return True
except Exception as e:
print(f"保存深度图失败: {e}")
return False
def predict_monocular(self, image_path, output_path="depth_output.png",
return_npy=False):
"""
单目深度估计
参数:
image_path: RGB图片路径
output_path: 输出深度图路径
return_npy: 是否返回npy格式的原始数据
"""
print(f"开始单目深度估计: {image_path}")
# 准备请求数据
image_base64 = self.image_to_base64(image_path)
payload = {
"image": image_base64,
"mode": "monocular",
"return_npy": return_npy
}
# 发送请求
start_time = time.time()
try:
response = requests.post(self.predict_url, json=payload, timeout=30)
response.raise_for_status()
result = response.json()
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None
elapsed = time.time() - start_time
print(f"推理完成,耗时: {elapsed:.2f}秒")
# 检查结果
if result.get("status") != "success":
print(f"模型推理失败: {result.get('message', '未知错误')}")
return None
# 保存深度图
depth_image = result.get("depth_image")
if depth_image:
self.save_depth_image(depth_image, output_path)
# 显示信息
info = result.get("info", {})
print(f"模式: {info.get('mode', 'N/A')}")
print(f"深度范围: {info.get('depth_range', 'N/A')}")
print(f"输入尺寸: {info.get('input_size', 'N/A')}")
print(f"设备: {info.get('device', 'N/A')}")
return result
def predict_completion(self, rgb_path, depth_path, output_path="completion_output.png",
fx=460.14, fy=460.20, cx=319.66, cy=237.40,
return_npy=False):
"""
深度补全
参数:
rgb_path: RGB图片路径
depth_path: 稀疏深度图路径
output_path: 输出深度图路径
fx, fy, cx, cy: 相机内参
return_npy: 是否返回npy格式的原始数据
"""
print(f"开始深度补全")
print(f" RGB图像: {rgb_path}")
print(f" 深度图: {depth_path}")
print(f" 相机内参: fx={fx}, fy={fy}, cx={cx}, cy={cy}")
# 准备请求数据
rgb_base64 = self.image_to_base64(rgb_path)
depth_base64 = self.image_to_base64(depth_path)
payload = {
"image": rgb_base64,
"depth": depth_base64,
"mode": "completion",
"fx": fx,
"fy": fy,
"cx": cx,
"cy": cy,
"return_npy": return_npy
}
# 发送请求
start_time = time.time()
try:
response = requests.post(self.predict_url, json=payload, timeout=30)
response.raise_for_status()
result = response.json()
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None
elapsed = time.time() - start_time
print(f"推理完成,耗时: {elapsed:.2f}秒")
# 检查结果
if result.get("status") != "success":
print(f"模型推理失败: {result.get('message', '未知错误')}")
return None
# 保存深度图
depth_image = result.get("depth_image")
if depth_image:
self.save_depth_image(depth_image, output_path)
# 显示信息
info = result.get("info", {})
print(f"模式: {info.get('mode', 'N/A')}")
print(f"深度范围: {info.get('depth_range', 'N/A')}")
print(f"输入尺寸: {info.get('input_size', 'N/A')}")
return result
def main():
parser = argparse.ArgumentParser(description="lingbot-depth模型命令行客户端")
parser.add_argument("--mode", choices=["monocular", "completion"],
required=True, help="运行模式")
parser.add_argument("--image", required=True, help="RGB图像路径")
parser.add_argument("--depth", help="深度图路径(仅completion模式需要)")
parser.add_argument("--output", default="output.png", help="输出文件路径")
parser.add_argument("--fx", type=float, default=460.14, help="相机内参fx")
parser.add_argument("--fy", type=float, default=460.20, help="相机内参fy")
parser.add_argument("--cx", type=float, default=319.66, help="相机内参cx")
parser.add_argument("--cy", type=float, default=237.40, help="相机内参cy")
parser.add_argument("--return-npy", action="store_true",
help="是否返回npy格式数据")
args = parser.parse_args()
# 创建客户端
client = LingBotDepthClient()
# 根据模式调用
if args.mode == "monocular":
if args.depth:
print("警告:单目模式不需要深度图参数,忽略--depth")
result = client.predict_monocular(
args.image,
args.output,
args.return_npy
)
elif args.mode == "completion":
if not args.depth:
print("错误:深度补全模式需要--depth参数")
return
result = client.predict_completion(
args.image,
args.depth,
args.output,
args.fx, args.fy, args.cx, args.cy,
args.return_npy
)
if result:
print("✓ 处理完成")
else:
print("✗ 处理失败")
if __name__ == "__main__":
main()
使用这个脚本非常简单:
# 单目深度估计
python3 call_lingbot.py --mode monocular \
--image /root/assets/lingbot-depth-main/examples/0/rgb.png \
--output monocular_depth.png
# 深度补全
python3 call_lingbot.py --mode completion \
--image /root/assets/lingbot-depth-main/examples/0/rgb.png \
--depth /root/assets/lingbot-depth-main/examples/0/raw_depth.png \
--output completion_depth.png \
--fx 460.14 --fy 460.20 --cx 319.66 --cy 237.40
4.3 方法三:批量处理脚本(最实用)
在实际工作中,我们经常需要处理大量图片。下面是一个批量处理的示例:
#!/usr/bin/env python3
"""
批量处理脚本:处理整个目录的图片
"""
import os
import glob
from pathlib import Path
from call_lingbot import LingBotDepthClient # 假设上面的类在call_lingbot.py中
def batch_process_monocular(input_dir, output_dir, pattern="*.png"):
"""
批量单目深度估计
参数:
input_dir: 输入图片目录
output_dir: 输出目录
pattern: 文件匹配模式
"""
# 创建输出目录
os.makedirs(output_dir, exist_ok=True)
# 获取所有图片文件
image_files = glob.glob(os.path.join(input_dir, pattern))
print(f"找到 {len(image_files)} 张图片")
# 创建客户端
client = LingBotDepthClient()
# 批量处理
success_count = 0
for i, image_path in enumerate(image_files):
print(f"\n处理第 {i+1}/{len(image_files)} 张: {os.path.basename(image_path)}")
# 生成输出路径
output_path = os.path.join(
output_dir,
f"depth_{Path(image_path).stem}.png"
)
try:
result = client.predict_monocular(image_path, output_path)
if result:
success_count += 1
print(f" ✓ 成功")
else:
print(f" ✗ 失败")
except Exception as e:
print(f" ✗ 异常: {e}")
print(f"\n批量处理完成,成功: {success_count}/{len(image_files)}")
def main():
# 示例:处理示例目录中的所有rgb图片
input_dir = "/root/assets/lingbot-depth-main/examples"
output_dir = "/root/batch_results"
# 先收集所有rgb.png文件
rgb_files = []
for example_dir in sorted(glob.glob(os.path.join(input_dir, "*"))):
rgb_path = os.path.join(example_dir, "rgb.png")
if os.path.exists(rgb_path):
rgb_files.append(rgb_path)
print(f"找到 {len(rgb_files)} 个示例")
# 创建客户端
client = LingBotDepthClient()
# 逐个处理
for i, rgb_path in enumerate(rgb_files):
example_name = Path(rgb_path).parent.name
print(f"\n处理示例 {example_name} ({i+1}/{len(rgb_files)})")
output_path = os.path.join(output_dir, f"{example_name}_depth.png")
client.predict_monocular(rgb_path, output_path)
if __name__ == "__main__":
main()
5. 实用技巧与常见问题
掌握了基本调用方法后,我们来看看一些实用技巧和可能遇到的问题。
5.1 性能优化建议
在命令行环境下,性能优化很重要:
# 1. 使用合适的图片尺寸
# 模型对14的倍数尺寸处理最好,如448x448、336x336
# 可以在调用前先调整图片尺寸
# 2. 批量处理时控制并发
# 虽然可以并行调用,但要注意GPU显存限制
# 建议使用队列控制同时处理的数量
# 3. 缓存模型结果
# 如果多次处理相同图片,可以考虑缓存结果
5.2 常见问题解决
问题1:服务没有响应
# 检查服务状态
curl -I http://localhost:8000/docs
# 查看服务日志
tail -f /root/lingbot-depth.log # 如果有日志文件的话
# 重启服务
cd /root
pkill -f "python.*fastapi" # 谨慎使用
bash start.sh
问题2:显存不足
# 查看GPU显存使用
nvidia-smi
# 如果显存不足,可以尝试:
# 1. 减小图片尺寸
# 2. 降低并发数量
# 3. 使用CPU模式(不推荐,速度慢)
问题3:图片格式问题
# 在Python中检查图片格式
from PIL import Image
img = Image.open("your_image.jpg")
print(f"格式: {img.format}, 尺寸: {img.size}, 模式: {img.mode}")
# 如果不是RGB,需要转换
if img.mode != "RGB":
img = img.convert("RGB")
img.save("converted.jpg")
5.3 自动化脚本示例
最后,分享一个完整的自动化处理脚本,你可以根据自己的需求修改:
#!/bin/bash
# 自动化处理脚本:monitor_and_process.sh
# 监控目录,自动处理新图片
INPUT_DIR="/data/images/input"
OUTPUT_DIR="/data/images/output"
PROCESSED_DIR="/data/images/processed"
LOG_FILE="/var/log/lingbot_processor.log"
# 创建目录
mkdir -p "$INPUT_DIR" "$OUTPUT_DIR" "$PROCESSED_DIR"
echo "$(date): 开始监控目录 $INPUT_DIR" >> "$LOG_FILE"
# 无限循环监控
while true; do
# 查找新图片
NEW_IMAGES=$(find "$INPUT_DIR" -name "*.jpg" -o -name "*.png" | head -10)
if [ -n "$NEW_IMAGES" ]; then
echo "$(date): 发现新图片,开始处理..." >> "$LOG_FILE"
for IMAGE in $NEW_IMAGES; do
FILENAME=$(basename "$IMAGE")
echo "处理: $FILENAME" >> "$LOG_FILE"
# 调用Python脚本处理
python3 /root/call_lingbot.py --mode monocular \
--image "$IMAGE" \
--output "$OUTPUT_DIR/depth_$FILENAME" \
2>&1 >> "$LOG_FILE"
# 移动已处理图片
mv "$IMAGE" "$PROCESSED_DIR/"
echo "完成: $FILENAME" >> "$LOG_FILE"
done
fi
# 等待10秒再次检查
sleep 10
done
6. 总结
通过这篇教程,我们学习了在Linux服务器无GUI环境下调用lingbot-depth模型的三种方法:
- curl直接调用:最简单快捷,适合快速测试和简单集成
- Python脚本调用:最灵活强大,适合复杂逻辑和自定义处理
- 批量处理脚本:最实用高效,适合处理大量数据
关键要点回顾:
- 模型提供了REST API接口,端口是8000
- 支持单目深度估计和深度补全两种模式
- 深度补全需要提供相机内参
- 图片需要转换为base64编码传输
- 输出可以是PNG图片或npy原始数据
下一步建议:
如果你需要将深度估计集成到更大的系统中,可以考虑:
- 将API调用封装成服务
- 添加错误重试机制
- 实现结果缓存提高性能
- 添加监控和报警
最后的小提示:虽然命令行看起来不如图形界面直观,但它给了你最大的灵活性和控制力。一旦掌握了这些方法,你就能在各种环境下自如地使用lingbot-depth模型,无论是本地开发、远程服务器,还是自动化流水线。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)