深度估測技術研究_Depth Pro:在不到一秒的時間內獲得清晰的單目公制深度_用python結合Yolo11測試實作

 

蘋果 AI 研究團隊於2024年10月,提出一款新模型「Depth Pro」,Depth Pro在未知的新影像情境下,仍可立即準確估測深度,而無需額外學習或校準。

https://machinelearning.apple.com/research/depth-pro
https://github.com/apple/ml-depth-pro?tab=readme-ov-file
https://arxiv.org/pdf/2410.02073
提出了一個零鏡頭度量單目深度估計的基礎模型。 Depth Pro 模型合成了高解析度深度圖,具有無與倫比的清晰度和高頻細節。上圖中可看到比較靠近的呈現較深濃的紅色,較遠的則相對是冷綠色。


預測是不依賴於元數據(如相機內部函數)的。而且該模型速度很快,在 GPU 上可在 0.3 秒內生成 225 萬像素 depth map。不過我這邊於colab上實測還是稍微跑要點時間,大概要2~5秒網路延遲也有可能。

這些特性是由許多技術貢獻實現的,包括用於密集預測的高效多尺度視覺轉換器、結合真實和合成數據集以實現高度量精度以及精細邊界追蹤的訓練協議、估計深度圖中邊界精度的專用評估指標,以及來自單個圖像的最先進的焦距估計。


Depth Pro 提供了現階段最精準且高解析度的單目深度估測模型,適合各種互動式視覺應用。然而,模型仍有一些局限性,如對半透明或具有體積散射的物體效果有限(例如煙霧、水氣等)。


英文論文中出現的專業術語:
  • Zero-shot learning (零樣本學習):
    模型能處理訓練時未見過的資料,不需額外調整或微調。
  • Monocular depth estimation (單目深度估測):
    僅憑單張2D影像估測出物體真實的深度距離。
  • Metric depth (度量深度):
    預測的深度值具有真實尺度(例如以公尺為單位的絕對距離)。
  • Vision Transformer (ViT):
    基於Transformer的深度學習架構,透過自注意力機制(Self-Attention)處理影像資料。
  • Multi-scale architecture (多尺度架構):
    模型同時考慮不同解析度尺度的資訊,以更準確地捕捉局部細節與全域資訊。
  • Boundary tracing (邊界追蹤):
    在深度估測任務中,準確識別和追蹤物體邊緣的重要技術。
  • Focal length estimation (焦距估測):
    從影像推估拍攝相機的鏡頭焦距或視野角度,進一步提高3D幾何重建的準確性。
  • Segmentation & Matting datasets (影像分割與Matting資料集):
    提供像素級別的標註,用以評估深度邊界的準確性。









去Apple的官方github把他的git repo給clone下來


Colab預設已經先幫我們把常用到的套件都給準備好。

去編輯選擔下調整筆記本設定,改為GPU。



在Colab中有關於一些指令要注意
pip相關指令前面要多加!
Linux相關指令則要加%


Step1.把Depth Pro 蘋果的git repo整包clone下載,補安裝所需要的pip套件。
!git clone https://github.com/apple/ml-depth-pro.git
%cd /content/ml-depth-pro/
%pwd
!pip install -e .



Step2.下載預訓練好的Depth Pro Model裡面會有相應權重參數,要透過這支shell來去做下載。
!source get_pretrained_models.sh

緊接著我們要去試著運行看看depth-pro的執行指令檔該檔案是由python所撰寫的。
若要查看指令幫助文檔可下-h 查看help說明
!depth-pro-run -h


這邊下載2張寬高像素為1920*1080的影像檔
image1
https://drive.usercontent.google.com/download?id=1-PNmddR4WWc2sJSRpdAmD7hnPqb7e5w4&authuser=0
image2
https://drive.usercontent.google.com/download?id=1XxjV5f0YBakvj2FpUaDG063htonnPS1I&authuser=0

跟一張像素為1600*900的影像檔
image3
https://drive.usercontent.google.com/download?id=14Vx5L5_Sfa41ilwg_CXLsBQcDhIG2GUe&authuser=0

用 gdown指令從google drive給下載到當前目錄下自建的Images目錄下,若該目錄不存在會自動補建立。

Step3.接續去執行Depth Pro的深度估測程式,產生depth map影像。
!depth-pro-run -i "Images/" -o ./output/
跑完後會多增加一個output目錄



Step4.透過Yolo11去做人體偵測並進行人體資訊框選繪製顯示推理換算的遠近距離(單位:公尺)。
  • 使用YOLO物件偵測模型(yolo11s.pt),偵測影像中所有人並畫出邊框。
  • 使用Depth Pro深度估測模型取得整張影像的深度資訊(每個像素點的距離值)。
!pip install ultralytic
!pip install opencv-python


ultralytics 套件從 YOLOv8 開始提供 YOLO() 這種統一呼叫方式。
https://github.com/ultralytics/ultralytics?tab=readme-ov-file



這裡模型資訊輸出如下




測試用程式

# 匯入所需套件
import cv2  # OpenCV影像處理函式庫
from ultralytics import YOLO  # 使用YOLO物件偵測模型
from google.colab.patches import cv2_imshow  # Colab環境顯示影像函式
import numpy as np  # 用於數值陣列處理的函式庫

# 載入已訓練好的YOLO物件偵測模型,使用模型權重檔案"yolo11s.pt"
model = YOLO("yolo11s.pt")

# 指定要處理的影像檔案路徑
image_path = "Images/image2.jpeg"

# 使用OpenCV讀取影像
image_input = cv2.imread(image_path)

# 對輸入影像執行YOLO物件偵測,結果包含物件位置(boxes)和類別(classes)
results = model(image_input)

# 儲存偵測到人物的框座標
person_boxes = []

# 遍歷YOLO模型的所有偵測結果
for result in results:
    boxes = result.boxes.xyxy.cpu().numpy()  # 取得物件邊界框(x1,y1,x2,y2)
    classes = result.boxes.cls.cpu().numpy()  # 取得物件類別編號

    # 遍歷每個偵測到的物件框及類別
    for box, cls in zip(boxes, classes):
        if result.names[int(cls)] == "person":  # 如果偵測到物件類別是"person"(人類)
            x1, y1, x2, y2 = map(int, box[:4])  # 取得邊界框座標,轉為整數
            person_boxes.append((x1, y1, x2, y2))  # 加入人物邊界框列表
            # 在影像上繪製綠色方框標示人物位置
            cv2.rectangle(image_input, (x1, y1), (x2, y2), (0, 255, 0), 2)

# 若需要可顯示影像(暫時註解,若需要再啟用)
# cv2_imshow(image_input)

# --- 使用 depth_pro 模型取得影像的深度資訊 ---


from PIL import Image# 載入PIL套件用於影像處理
import depth_pro  # 引入深度估測模型套件

# 初始化深度估測模型與前處理轉換(transform)
model, transform = depth_pro.create_model_and_transforms()
model.eval()  # 設定模型為推論模式 (不會更新權重)

# 使用depth_pro套件載入原始RGB影像,並取得焦距像素(f_px)
image, _, f_px = depth_pro.load_rgb(image_path)

# 將影像進行模型所需的前處理(例如轉Tensor、正規化)
image = transform(image)

# 進行深度估測推論,取得深度資訊
prediction = model.infer(image, f_px=f_px)

# 從推論結果取得深度資料,單位為公尺[m]
depth = prediction["depth"]
# 將深度資料轉為numpy陣列,並移除額外維度
depth_np = depth.squeeze().cpu().numpy()

# 遍歷每個偵測到的人物,標示其中心位置深度值
for x1, y1, x2, y2 in person_boxes:
    # 計算人物框的中心座標
    center_x = (x1 + x2) // 2
    center_y = (y1 + y2) // 2

    # 取得人物中心點的深度值
    depth_value = depth_np[center_y, center_x]

    # 在原圖上標示深度值文字
    text = f"Depth: {depth_value:.2f} m"
    font = cv2.FONT_HERSHEY_SIMPLEX  # 設定文字字體
    font_scale = 1  # 文字大小比例
    font_thickness = 2  # 文字粗細

    # 計算文字大小並設定位置
    text_size = cv2.getTextSize(text, font, font_scale, font_thickness)[0]
    text_x = x1  # 文字起始x位置
    text_y = y1 - 10  # 文字起始y位置(框的上方10個像素)

    # 計算背景矩形座標(黑色底,增加文字可見度)
    rect_x1 = text_x - 5
    rect_y1 = text_y - text_size[1] - 10
    rect_x2 = text_x + text_size[0] + 5
    rect_y2 = text_y + 5

    # 繪製黑色背景矩形和白色深度文字
    cv2.rectangle(image_input, (rect_x1, rect_y1), (rect_x2, rect_y2), (0, 0, 0), -1)
    cv2.putText(image_input, text, (text_x, text_y), font, font_scale, (255, 255, 255), font_thickness)

# 顯示加入深度標示後的最終影像,並儲存為"depth.jpg"
cv2_imshow(image_input)
cv2.imwrite("depth.jpg", image_input)
cv2.waitKey(0)

# --- 將深度資訊轉為視覺化彩色影像 ---

# 將深度值正規化為0~1範圍,用於後續顏色轉換
depth_np_normalized = (depth_np - depth_np.min()) / (depth_np.max() - depth_np.min())

# 反轉深度值(較近的地方顏色較鮮豔)
inv_depth_np_normalized = 1.0 - depth_np_normalized

# 將深度資訊轉為彩色影像(使用COLORMAP_TURBO色階)
depth_colormap = cv2.applyColorMap((inv_depth_np_normalized * 255).astype(np.uint8), cv2.COLORMAP_TURBO)

# 顯示並儲存深度彩色視覺化結果
cv2_imshow(depth_colormap)
cv2.imwrite("depth_colormap2.jpg", depth_colormap)
cv2.waitKey(0)

# 結束OpenCV視窗
cv2.destroyAllWindows()






留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header