lingbot-depth-vitl14实战教程:使用curl命令调用FastAPI /predict端点完整示例
1. 引言:为什么需要命令行调用?
如果你正在开发机器人导航、AR应用或者3D重建系统,可能会遇到这样的需求:需要把深度估计功能集成到自己的程序里,而不是每次都打开网页手动上传图片。这时候,通过命令行直接调用API接口就成了最直接、最高效的方式。
今天我要分享的就是如何用最简单的curl命令,调用lingbot-depth-vitl14模型的FastAPI接口。这个教程特别适合那些:
- 想要自动化处理大量图片的开发者
- 需要在服务器端集成深度估计功能的工程师
- 喜欢用命令行工具快速测试接口的程序员
我会从最基础的curl命令开始,一步步带你完成整个调用流程,包括如何准备图片、发送请求、解析响应,以及处理可能遇到的问题。即使你之前没怎么用过curl,跟着这个教程也能轻松上手。
2. 环境准备:确认服务已经启动
在开始调用API之前,我们需要先确认lingbot-depth-vitl14的服务已经正常运行。
2.1 检查服务状态
首先,登录到你的服务器或者实例,执行以下命令检查FastAPI服务是否在运行:
# 检查8000端口是否被监听 netstat -tlnp | grep 8000 # 或者使用lsof命令 lsof -i :8000 # 更简单的方式,直接curl测试 curl http://localhost:8000/如果服务正常运行,最后一个命令会返回FastAPI的默认响应,类似这样:
{"message":"Welcome to LingBot-Depth API"}2.2 准备测试图片
为了后续的测试,我们先准备一张测试图片。lingbot-depth-vitl14镜像已经内置了一些示例图片,我们可以直接使用:
# 查看示例图片目录 ls -la /root/assets/lingbot-depth-main/examples/ # 通常会有多个示例,比如: # 0/ 1/ 2/ 3/ 4/ # 每个目录下都有rgb.png和raw_depth.png # 我们使用第一个示例的RGB图片 TEST_IMAGE="/root/assets/lingbot-depth-main/examples/0/rgb.png" # 确认图片存在且可读 file "$TEST_IMAGE"如果一切正常,你会看到图片的详细信息,比如“PNG image data, 640 x 480, 8-bit/color RGB”。
3. 基础调用:最简单的单目深度估计
现在我们来尝试第一个API调用——单目深度估计。这是最基本的功能,只需要一张RGB图片。
3.1 理解API接口
lingbot-depth-vitl14的FastAPI服务提供了/predict端点,支持两种调用方式:
- 表单数据(multipart/form-data):适合上传文件
- JSON数据:适合传递base64编码的图片
我们先从最简单的表单方式开始。
3.2 第一个curl命令
打开终端,执行以下命令:
curl -X POST "http://localhost:8000/predict" \ -F "mode=monocular" \ -F "image=@/root/assets/lingbot-depth-main/examples/0/rgb.png" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40"让我解释一下每个参数:
-X POST:指定使用POST方法-F:表示这是一个表单字段mode=monocular:告诉模型使用单目深度估计模式image=@...:上传图片文件,@后面是文件路径fx/fy/cx/cy:相机内参,即使单目模式也建议提供,虽然模型会估算
3.3 解析响应结果
执行命令后,你会得到一个JSON响应,内容类似这样:
{ "status": "success", "mode": "monocular", "input_size": "640x480", "depth_range": "0.523m ~ 8.145m", "depth_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...", "depth_data": "https://example.com/temp/depth_12345.npy", "point_cloud": "https://example.com/temp/points_12345.npy", "inference_time": 0.087 }响应包含几个关键信息:
status:请求状态,成功就是"success"depth_range:估计的深度范围,告诉你最近和最远的物体距离depth_image:base64编码的深度图(伪彩色热力图)depth_data:原始深度数据的下载链接(.npy格式)inference_time:推理耗时,单位是秒
3.4 保存深度图
深度图是base64编码的,我们可以用命令行工具把它解码保存为图片:
# 先获取完整的响应,保存到文件 curl -X POST "http://localhost:8000/predict" \ -F "mode=monocular" \ -F "image=@/root/assets/lingbot-depth-main/examples/0/rgb.png" \ -o response.json # 使用jq提取base64数据并解码 jq -r '.depth_image | sub("data:image/png;base64,"; "")' response.json | \ base64 -d > depth_output.png # 如果没有jq,也可以用Python python3 -c " import json, base64 with open('response.json') as f: data = json.load(f) img_data = data['depth_image'].split(',')[1] with open('depth_output.png', 'wb') as f: f.write(base64.b64decode(img_data)) print('深度图已保存为 depth_output.png') "现在你可以用图片查看器打开depth_output.png,看到生成的深度热力图了。
4. 进阶功能:深度补全模式
单目深度估计虽然方便,但如果有稀疏深度信息(比如来自LiDAR或ToF传感器),深度补全模式能给出更准确的结果。
4.1 准备深度图数据
深度补全需要两张图片:
- RGB彩色图
- 稀疏深度图(可以是传感器原始数据)
# 示例目录中已经提供了配对的RGB和深度图 RGB_IMAGE="/root/assets/lingbot-depth-main/examples/0/rgb.png" DEPTH_IMAGE="/root/assets/lingbot-depth-main/examples/0/raw_depth.png" # 查看深度图信息 file "$DEPTH_IMAGE"深度图通常是单通道的PNG或16位TIFF,每个像素值代表深度(单位可能是毫米或米)。
4.2 调用深度补全API
深度补全的调用方式和单目模式类似,只是多了一个深度图参数:
curl -X POST "http://localhost:8000/predict" \ -F "mode=completion" \ -F "image=@/root/assets/lingbot-depth-main/examples/0/rgb.png" \ -F "depth=@/root/assets/lingbot-depth-main/examples/0/raw_depth.png" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40" \ -F "depth_unit=mm" # 指定深度图单位注意新增的参数:
mode=completion:切换到深度补全模式depth=@...:上传稀疏深度图depth_unit:深度图的单位,可以是"mm"(毫米)或"m"(米)
4.3 对比两种模式的结果
为了直观感受两种模式的区别,我们可以同时调用并保存结果:
#!/bin/bash # 定义图片路径 RGB="/root/assets/lingbot-depth-main/examples/0/rgb.png" DEPTH="/root/assets/lingbot-depth-main/examples/0/raw_depth.png" # 单目模式 echo "正在执行单目深度估计..." curl -s -X POST "http://localhost:8000/predict" \ -F "mode=monocular" \ -F "image=@$RGB" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40" \ > monocular.json # 深度补全模式 echo "正在执行深度补全..." curl -s -X POST "http://localhost:8000/predict" \ -F "mode=completion" \ -F "image=@$RGB" \ -F "depth=@$DEPTH" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40" \ -F "depth_unit=mm" \ > completion.json echo "结果已保存到 monocular.json 和 completion.json"比较两个JSON文件中的depth_range字段,你会发现深度补全的结果通常范围更准确,因为有了稀疏深度作为参考。
5. 实用技巧:批量处理和自动化
在实际项目中,我们经常需要处理大量图片。下面分享几个实用的批量处理技巧。
5.1 批量处理脚本
假设你有一个图片目录,需要为每张图片生成深度图:
#!/bin/bash # batch_process.sh INPUT_DIR="./input_images" OUTPUT_DIR="./depth_output" API_URL="http://localhost:8000/predict" # 创建输出目录 mkdir -p "$OUTPUT_DIR" # 遍历所有jpg和png图片 for img_path in "$INPUT_DIR"/*.jpg "$INPUT_DIR"/*.png; do if [ -f "$img_path" ]; then filename=$(basename "$img_path") name_no_ext="${filename%.*}" echo "处理: $filename" # 调用API response=$(curl -s -X POST "$API_URL" \ -F "mode=monocular" \ -F "image=@$img_path" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40") # 提取并保存深度图 echo "$response" | python3 -c " import json, base64, sys data = json.load(sys.stdin) if data['status'] == 'success': img_data = data['depth_image'].split(',')[1] with open('$OUTPUT_DIR/${name_no_ext}_depth.png', 'wb') as f: f.write(base64.b64decode(img_data)) print(' 成功保存深度图') else: print(' 处理失败:', data.get('error', '未知错误')) " fi done echo "批量处理完成!结果保存在 $OUTPUT_DIR/"5.2 使用Python进行更复杂的处理
如果你需要更灵活的处理,比如下载原始深度数据或者进行后续分析,用Python会更方便:
import requests import base64 import json from pathlib import Path def estimate_depth(image_path, mode='monocular', depth_path=None): """调用深度估计API""" url = "http://localhost:8000/predict" # 准备表单数据 files = { 'image': open(image_path, 'rb'), 'mode': (None, mode), 'fx': (None, '460.14'), 'fy': (None, '460.20'), 'cx': (None, '319.66'), 'cy': (None, '237.40') } # 如果是深度补全模式,添加深度图 if mode == 'completion' and depth_path: files['depth'] = open(depth_path, 'rb') files['depth_unit'] = (None, 'mm') try: # 发送请求 response = requests.post(url, files=files) response.raise_for_status() result = response.json() if result['status'] == 'success': print(f"处理成功!深度范围: {result['depth_range']}") print(f"推理时间: {result['inference_time']:.3f}秒") # 保存深度图 depth_data = result['depth_image'].split(',')[1] output_path = Path(image_path).stem + '_depth.png' with open(output_path, 'wb') as f: f.write(base64.b64decode(depth_data)) print(f"深度图已保存: {output_path}") return result else: print(f"处理失败: {result.get('error', '未知错误')}") return None except Exception as e: print(f"API调用出错: {e}") return None finally: # 关闭所有打开的文件 for file_obj in files.values(): if hasattr(file_obj, 'close'): file_obj.close() # 使用示例 if __name__ == "__main__": # 单目深度估计 result = estimate_depth( image_path="/root/assets/lingbot-depth-main/examples/0/rgb.png", mode='monocular' ) # 如果需要,可以下载原始深度数据 if result and 'depth_data' in result: depth_url = result['depth_data'] # 使用requests下载.npy文件 # ...5.3 性能优化建议
处理大量图片时,可以考虑以下优化:
- 保持连接复用:使用
curl --keepalive或Python的requests.Session() - 并行处理:使用
xargs -P或Python的concurrent.futures - 调整图片尺寸:如果不需要高分辨率,可以先缩放图片
# 使用xargs并行处理4张图片 ls ./input_images/*.jpg | xargs -P 4 -I {} bash -c ' curl -s -X POST "http://localhost:8000/predict" \ -F "mode=monocular" \ -F "image=@{}" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40" \ > "depth_output/$(basename {} .jpg)_result.json" '6. 常见问题与解决方案
在实际使用中,你可能会遇到一些问题。这里整理了一些常见问题和解决方法。
6.1 连接问题
问题:curl命令返回连接拒绝或超时
curl: (7) Failed to connect to localhost port 8000: Connection refused解决:
# 1. 检查服务是否启动 ps aux | grep fastapi # 2. 检查端口监听 ss -tlnp | grep :8000 # 3. 如果服务没启动,手动启动 cd /root && bash start.sh # 4. 等待服务完全启动(首次启动需要5-8秒加载模型) sleep 106.2 图片格式问题
问题:API返回错误,提示图片格式不支持
{"detail":"Invalid image format"}解决:
# 1. 确认图片格式 file your_image.jpg # 2. 如果是其他格式,用ImageMagick转换 convert your_image.bmp -quality 95 your_image.jpg # 3. 或者用Python处理 python3 -c " from PIL import Image img = Image.open('your_image.tiff') img.convert('RGB').save('your_image.jpg', 'JPEG') "6.3 内存不足问题
问题:处理大图片时出现内存错误
CUDA out of memory解决:
# 1. 缩小图片尺寸(保持14的倍数) convert large_image.jpg -resize 448x448 resized_image.jpg # 2. 检查GPU内存使用 nvidia-smi # 3. 如果显存不足,可以尝试CPU模式(修改启动参数) # 需要修改FastAPI代码,这里不展开6.4 响应解析问题
问题:base64解码失败或JSON解析错误
解决:
# 1. 先保存原始响应,检查结构 curl -v -X POST "http://localhost:8000/predict" ... > raw_response.txt # 2. 使用jq验证JSON格式 cat response.json | jq . # 3. 如果jq报错,说明JSON格式有问题 # 查看服务日志 tail -f /root/fastapi.log 2>/dev/null || tail -f /var/log/syslog6.5 性能问题
问题:处理速度慢,特别是批量处理时
解决:
# 1. 检查推理时间 curl ... | jq '.inference_time' # 2. 正常应该在0.1-0.3秒之间,如果太慢: # - 检查GPU是否正常工作:nvidia-smi # - 检查图片尺寸是否过大 # - 考虑使用更小的模型(如果有的话) # 3. 批量处理时添加延迟,避免压垮服务 for img in *.jpg; do curl ... sleep 0.5 # 添加500ms延迟 done7. 实际应用示例
让我们看几个实际的应用场景,了解如何将API调用集成到真实项目中。
7.1 机器人导航系统
假设你正在开发一个机器人导航系统,需要实时获取深度信息:
import requests import numpy as np import cv2 from threading import Thread from queue import Queue class DepthEstimator: def __init__(self, api_url="http://localhost:8000/predict"): self.api_url = api_url self.result_queue = Queue() def estimate_async(self, image_frame): """异步估计深度""" def worker(): # 将OpenCV图像转换为jpg字节流 _, img_encoded = cv2.imencode('.jpg', image_frame) img_bytes = img_encoded.tobytes() # 准备请求 files = { 'image': ('frame.jpg', img_bytes, 'image/jpeg'), 'mode': (None, 'monocular'), 'fx': (None, '460.14'), 'fy': (None, '460.20'), 'cx': (None, '319.66'), 'cy': (None, '237.40') } try: response = requests.post(self.api_url, files=files, timeout=2.0) if response.status_code == 200: result = response.json() if result['status'] == 'success': self.result_queue.put(result) except Exception as e: print(f"深度估计失败: {e}") # 启动线程 Thread(target=worker, daemon=True).start() def get_latest_depth(self): """获取最新的深度结果""" if not self.result_queue.empty(): return self.result_queue.get() return None # 使用示例 estimator = DepthEstimator() # 模拟从摄像头获取帧 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break # 异步估计深度 estimator.estimate_async(frame) # 检查是否有新的深度结果 depth_result = estimator.get_latest_depth() if depth_result: # 处理深度信息,比如障碍物检测 depth_range = depth_result['depth_range'] print(f"当前深度范围: {depth_range}") # 可以在这里添加导航逻辑 # ... # 显示视频帧 cv2.imshow('Camera', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()7.2 3D重建流水线
对于3D重建项目,你可能需要批量处理图片并保存深度数据:
#!/bin/bash # 3d_reconstruction_pipeline.sh # 配置 INPUT_VIDEO="input_video.mp4" FRAME_DIR="./frames" DEPTH_DIR="./depth_maps" POINT_CLOUD_DIR="./point_clouds" API_URL="http://localhost:8000/predict" # 1. 从视频提取帧 echo "提取视频帧..." mkdir -p "$FRAME_DIR" ffmpeg -i "$INPUT_VIDEO" -vf "fps=30" "$FRAME_DIR/frame_%04d.jpg" 2>/dev/null # 2. 为每帧估计深度 echo "估计深度..." mkdir -p "$DEPTH_DIR" frame_count=0 for frame in "$FRAME_DIR"/*.jpg; do if [ -f "$frame" ]; then frame_count=$((frame_count + 1)) filename=$(basename "$frame" .jpg) echo "处理第 $frame_count 帧: $filename" # 调用API curl -s -X POST "$API_URL" \ -F "mode=monocular" \ -F "image=@$frame" \ -F "fx=460.14" \ -F "fy=460.20" \ -F "cx=319.66" \ -F "cy=237.40" \ | jq -r '.depth_image | sub("data:image/png;base64,"; "")' \ | base64 -d > "$DEPTH_DIR/${filename}_depth.png" fi done echo "深度估计完成!共处理 $frame_count 帧" # 3. 下载原始深度数据(用于3D重建) echo "下载原始深度数据..." mkdir -p "$POINT_CLOUD_DIR" # 这里需要先获取深度数据的URL,然后下载.npy文件 # 实际项目中可能需要修改API以直接返回数据或保存到指定位置 echo "流水线执行完成!" echo "- 彩色帧: $FRAME_DIR/" echo "- 深度图: $DEPTH_DIR/" echo "- 点云数据: $POINT_CLOUD_DIR/"7.3 Web应用集成
如果你正在开发一个Web应用,可以通过后端调用深度估计API:
# web_backend.py from fastapi import FastAPI, File, UploadFile, HTTPException import requests import base64 from io import BytesIO from PIL import Image app = FastAPI() DEPTH_API = "http://localhost:8000/predict" @app.post("/api/depth-estimate") async def depth_estimate( image: UploadFile = File(...), mode: str = "monocular" ): """Web应用的后端接口,转发到深度估计API""" # 验证图片格式 if not image.content_type.startswith('image/'): raise HTTPException(400, "请上传图片文件") try: # 读取上传的图片 image_data = await image.read() # 准备转发到深度估计API files = { 'image': (image.filename, image_data, image.content_type), 'mode': (None, mode), 'fx': (None, '460.14'), 'fy': (None, '460.20'), 'cx': (None, '319.66'), 'cy': (None, '237.40') } # 调用深度估计服务 response = requests.post(DEPTH_API, files=files, timeout=10.0) if response.status_code != 200: raise HTTPException(502, "深度估计服务暂时不可用") result = response.json() if result['status'] != 'success': raise HTTPException(500, f"深度估计失败: {result.get('error', '未知错误')}") # 返回结果给前端 return { 'success': True, 'depth_image': result['depth_image'], # base64图片 'depth_range': result['depth_range'], 'inference_time': result['inference_time'] } except requests.Timeout: raise HTTPException(504, "请求超时,请稍后重试") except Exception as e: raise HTTPException(500, f"处理失败: {str(e)}") # 前端可以这样调用 """ fetch('/api/depth-estimate', { method: 'POST', body: formData // 包含图片文件 }) .then(response => response.json()) .then(data => { if (data.success) { // 显示深度图 document.getElementById('depth-image').src = data.depth_image; // 显示深度范围 document.getElementById('depth-range').textContent = data.depth_range; } }); """8. 总结
通过这篇教程,你应该已经掌握了使用curl命令调用lingbot-depth-vitl14模型FastAPI接口的完整流程。让我们回顾一下关键点:
8.1 核心要点回顾
- 基础调用很简单:一个curl命令就能完成深度估计,不需要复杂的编程
- 两种模式都支持:单目深度估计和深度补全,根据需求选择
- 响应格式统一:JSON格式包含状态、深度图、深度范围等信息
- 批量处理可行:通过脚本可以自动化处理大量图片
8.2 实际使用建议
根据我的经验,这里有几个实用建议:
对于快速测试:
# 最简单的测试命令 curl -X POST "http://localhost:8000/predict" \ -F "mode=monocular" \ -F "image=@test.jpg"对于生产环境:
- 添加超时设置:
curl --max-time 30 - 记录日志:
curl ... 2>&1 | tee -a api.log - 错误重试:使用循环或专门的工具
对于性能要求高的场景:
- 考虑图片预处理(缩放、压缩)
- 使用连接池(Python的requests.Session)
- 异步调用避免阻塞
8.3 下一步学习方向
如果你已经掌握了基础调用,可以进一步探索:
- 深入研究API参数:尝试不同的相机内参,观察对结果的影响
- 结合其他工具:将深度图导入到CloudCompare、MeshLab等3D处理软件
- 优化处理流程:实现实时视频流的深度估计
- 错误处理完善:添加更健壮的错误处理和重试机制
8.4 最后的小提示
记住,lingbot-depth-vitl14虽然强大,但也有其局限性:
- 对输入图片尺寸敏感,建议使用14的倍数
- 深度范围有限,适合室内和中等距离场景
- 深度补全需要合理的稀疏深度输入
在实际应用中,建议先在小规模数据上测试,确保模型表现符合预期,再扩展到大规模应用。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。