0%

PointAnything

這篇文是關於我和我的隊友(黃仁駿劉冠言游惠晴)在 2024 交大資工系人工智慧概論的 Final Project 所繳交的成果,其中我負責了題目的發想、文獻的研究、做法的提出以及第一版作法的程式碼編寫。最後,我們的作品在兩個班共同舉辦的 AI Workshop 中取得了 Best Project 的成績。

Project GitHub repo


關於題目

這個作品的完整題目是 PointAnything: Pointing Estimation from single RGB image 。我們的目標是給定一張某個人指著某個物體的圖片,預測出那個人所指的物體是什麼。另外,雖然名稱沒有提到,因為我們都是直接拿 pre-trained model 來用,沒有自己 train 任何東西,這個作品本身也是 zero-shot 的,而且未來可以藉著新技術的發展,替換現今使用的模組提升最後的正確率。

給定左邊那個蜘蛛人的圖片,我們的作品能夠判斷出左邊的那個人指的是右邊的那個人

題目來源

一開始我是看到這篇 SIGGRAPH 2023 Poster 的作品,覺得這個”判斷手指著的物體”的題目很有趣,而且又有很直觀的擴展方向:其一是這篇做的題目是在 Omnidirectional image 上,但方法直接拿來做一般的圖片應該也是可行的;其二是他們沒有使用到深度資訊來協助判斷(我也和 Depth Estimation in Omnidirectional image 不熟),如果有深度資訊應該可以更準確(尤其在一般相機的 Perspective View 上)。於是在學期中前後,這個題目的雛型就大致確定了:我們要做的是在一般的圖片上,運用人體骨架預測、深度預測、物體識別的現成模型,對於給定的一張某個人指著某個物體的圖片,預測出那個人所指的物體是什麼。

方法

大概念是這樣:先用 PYSKL 預測出人體骨架,藉由其 COCO-Keypoints 的手肘和手腕的座標資訊,我們可以得知人所指的方向向量(在 2D 圖片上)。接著用 Depth Anything 預測出深度圖,我們就能把向量升維進 3D 空間中,也能夠藉這個 3D 向量去找到第一個接觸的點座標。再把那個點座標餵給 Segment Anything(SAM),我們就能夠知道那個點屬於哪個區域,最後再把整個區域餵給 YOLO 就能夠知道那個人指的是什麼物體了。

當然最後沒有這麼簡單好做,畢竟如果把上面提到這些模型都當成黑盒子,那我們的方法是一個極度基於物理觀察的方法,而這類型的方法最大特色就是任何一個環節的測量誤差都會傳遞到最後的預測結果,進而造成整體預測不準確。我們透過一些方法來降低這些誤差的影響,首先是關於找第一個接觸的點座標的部分,我們不只是枚舉射線所經過的點檢查,也考慮了射線附近的點(考慮上下左右幾個 pixel ,並設定了深度誤差的 threshold)。

此外,我們發現 SAM mask 總是切出很多小區域,例如給他一個人的頭髮的 pixel 他可能只會切出整片頭髮的 mask ,而把這個東西餵給 YOLO 是看不出這是一個人的。我們試著調整了 SAM 的參數還是沒辦法解決這個問題,就把作法反過來改成先把圖片餵給 YOLO ,再把所有射線有經過的 YOLO bounding box 餵給 SAM ,理想上 SAM 能夠比較準確的告訴我們物體的 mask ,這樣能得知物體的準確深度了。

我們遇到幾個問題:

  • YOLO 支援的物體類別過少,COCO 分類只有 80 種物品。註:這個問題直到最後都還是沒辦法獲得改善
  • 手肘和手腕給出的指向不準確
  • 深度圖不準確。註:這個問題也是直到最後都還是沒辦法獲得改善
  • 把 YOLO bounding box 餵給 SAM 有可能會反而抓到背景的 mask,而非物體的 mask

關於指向不準確的問題,我讀到這篇 paper有注意到當人在指物體的時候,實際上與被指物體的連線可能會是 (a) 前臂方向 (b) 手指方向 (c) 眼睛-手指方向 的其一。於是我們用了一個小 trick ,就是把前臂射線稍微往前延伸一點的位置當成手指位置,就能夠使用 (c) 的方法來預測物體了。這個做法最後並沒有改善正確率,因為手指座標不準確造成深度資訊失真的影響太大了。

其實我們主要關注要解決的問題是在找到接觸的座標之後,要如何得知這個位置的物體叫什麼。我們最後找到了 Detectron2 這個模型來接,降低了前述問題的影響,也些微提升了正確率,但因為分類類別太少的問題,最後的正確率還是不太理想,僅 25% 左右。

參考資料