Pollen-Vision:機器人零樣本視覺模型的統一介面
這是 Pollen Robotics 團隊的客座部落格文章。我們是 Reachy 的建立者,Reachy 是一款開源人形機器人,專為真實世界的操作而設計。
在自主行為的背景下,機器人可用性的本質在於其理解和與環境互動的能力。這種理解主要來自於視覺感知,它使機器人能夠識別物體、識別人、導航空間等等。
我們很高興地宣佈我們的開源 pollen-vision
庫的首次釋出,這是賦予我們的機器人抓取未知物體自主能力的第一步。該庫是精挑細選的視覺模型集合,因其在機器人領域的直接適用性而被選中。 Pollen-vision
的設計易於安裝和使用,由獨立模組組成,可以組合起來建立 3D 物件檢測管道,獲取物體在 3D 空間中的位置(x、y、z)。
我們專注於選擇零樣本模型,消除了任何訓練的需要,使這些工具開箱即用。
我們的初始版本專注於 3D 物件檢測——透過提供可靠的物體空間座標估計,為機器人抓取等任務奠定基礎。目前僅限於 3D 空間內的定位(不擴充套件到完整的 6D 姿態估計),此功能為基本的機器人操作任務奠定了堅實的基礎。
Pollen-Vision 的核心模型
該庫包含幾個關鍵模型。我們希望我們使用的模型是零樣本且多功能的,允許檢測各種物體而無需重新訓練。這些模型還必須具有“即時能力”,這意味著它們應該在消費級 GPU 上至少以每秒幾幀的速度執行。我們選擇的第一個模型是
- OWL-VIT (Open World Localization - Vision Transformer,由 Google Research 開發):此模型在 RGB 影像中執行文字條件零樣本 2D 物件定位。它輸出邊界框(如 YOLO)
- Mobile Sam:Meta AI 的 Segment Anything Model (SAM) 的輕量級版本。SAM 是一種零樣本影像分割模型。它可以透過邊界框或點進行提示。
- RAM (Recognize Anything Model,由 OPPO 研究院開發):RAM 專為零樣本影像標註而設計,可以根據文字描述確定影像中是否存在物體,為進一步分析奠定基礎。
只需幾行程式碼即可開始!
下面是使用 pollen-vision 構建一個簡單的物件檢測和分割管道的示例,該管道僅將影像和文字作為輸入。
from pollen_vision.vision_models.object_detection import OwlVitWrapper
from pollen_vision.vision_models.object_segmentation import MobileSamWrapper
from pollen_vision.vision_models.utils import Annotator, get_bboxes
owl = OwlVitWrapper()
sam = MobileSamWrapper()
annotator = Annotator()
im = ...
predictions = owl.infer(im, ["paper cups"]) # zero-shot object detection
bboxes = get_bboxes(predictions)
masks = sam.infer(im, bboxes=bboxes) # zero-shot object segmentation
annotated_im = annotator.annotate(im, predictions, masks=masks)
OWL-VIT 的推理時間取決於提供的提示數量(即要檢測的物件數量)。在配備 RTX 3070 GPU 的筆記型電腦上
1 prompt : ~75ms per frame
2 prompts : ~130ms per frame
3 prompts : ~180ms per frame
4 prompts : ~240ms per frame
5 prompts : ~330ms per frame
10 prompts : ~650ms per frame
因此,從效能角度來看,僅使用影像中已知的物件來提示 OWL-VIT 很有趣。這就是 RAM 的用武之地,因為它速度快,並且能提供準確的資訊。
一個機器人應用案例:在無約束環境中抓取未知物體
有了物件的分割掩碼,我們可以透過計算二值掩碼的質心來估計其在畫素空間中的 (u, v) 位置。在這裡,擁有分割掩碼非常有用,因為它允許我們平均掩碼內的深度值,而不是整個邊界框內的深度值,因為邊界框也包含會使平均值傾斜的背景。
一種方法是平均掩碼中非零畫素的 u 和 v 座標
def get_centroid(mask):
x_center, y_center = np.argwhere(mask == 1).sum(0) / np.count_nonzero(mask)
return int(y_center), int(x_center)
我們現在可以引入深度資訊,以估計物件的 z 座標。深度值已經以米為單位,但 (u, v) 座標以畫素表示。我們可以使用相機的內參矩陣 (K) 獲取物件質心的 (x, y, z) 位置(以米為單位)
def uv_to_xyz(z, u, v, K):
cx = K[0, 2]
cy = K[1, 2]
fx = K[0, 0]
fy = K[1, 1]
x = (u - cx) * z / fx
y = (v - cy) * z / fy
return np.array([x, y, z])
我們現在已經估算出了物體在相機參考系中的 3D 位置。
如果我們知道相機相對於機器人原點框架的位置,我們可以執行一個簡單的變換來獲取物體在機器人框架中的 3D 位置。這意味著我們可以將機器人的末端執行器移動到物體所在的位置,然後抓取它!🥳
接下來是什麼?
我們在本文中介紹的是實現我們的目標的第一步,即在野外自主抓取未知物體。還有一些問題需要解決
- OWL-Vit 並非每次都能檢測到所有物體,並且可能存在不一致性。我們正在尋找更好的替代方案。
- 目前沒有時間或空間一致性。所有內容都是每幀重新計算的
- 我們目前正在努力整合點跟蹤解決方案,以增強檢測的一致性
- 抓取技術(目前僅限正面抓取)不是這項工作的重點。我們將研究不同的方法,以提高抓取能力,包括感知(6D 檢測)和抓取姿態生成。
- 整體速度有待提高
嘗試 pollen-vision
想嘗試 pollen-vision 嗎?請檢視我們的 Github 倉庫!