# Transparent Object Manipulation for Robots - IROS

Objective

iCeiRA 當時有一個 project 是想要做實驗室自動化,因為我們希望讓機器人彈性地切換任務,所以我們選擇用 PR2 來當作開發的機器人平台,而不是一堆偏向純機械的自動化設備。

若要做到這件事,能夠辨識並抓取實驗室裡面常常出現的燒杯等透明儀器就很重要。

Method

Preprocessing for better segmentation

我們這一篇主要是優化 GrabCut 的 Seed,減少拿到錯誤 candidate 的機率。優化流程如下:

怎麼計算 highlight?

  1. 用 0 - 255 來 threshold image,每個 threshold 都會保留不同的pixel

  2. 計算每張 threshold 完的圖剩下多少 perimeter pixel(在邊緣上的點)

  3. 算出一個 histogram

  4. 分別從 255 開始往回走,每加一個點就重新 fit 一條直線

  5. 當直線斜率開始大增的時候,就表示開始不是 highlight 了

Code 可以在這邊找到:

https://github.com/Po-Jen/transparent_objects/commit/064032f4316a43a7e3f7b0bb154b322fa90eeafa

怎麼計算每個輪廓的周邊 pixel 有哪些 & 中間是哪些?

  1. 先對偵測到的 candidate 邊緣做 dilation,得到 dilation 完的 pixel。

  2. dilation 完的 pixel - 在 candidate 內的 pixel = candidate 周邊 pixel

  3. 計算 candidate 內 pixel 跟 周邊 pixel 的 hue histogram,比較兩者差距

Pose estimation

這邊是用別人的黑盒子,細節並沒有知道得很詳細。之後再慢慢補充。

怎麼 train?

怎麼 match?

怎麼避免 clutter?

Result

雖然在 accuracy 上沒有顯著提升,但是 precision 提升很多,所以機器人就不會把不是真正透明物體的地方錯誤辨識成透明物體。

Impact

讓實驗室有一個基本的版本可以再更深入研究。

FAQ

  1. Challenges a. 手有時大/有時小 b. 不是每個 frame 都可以偵測到手

  2. Mistakes/Failures a. IROS 投稿失敗

  3. Enjoyed a.

  4. Leadership

  5. Conflicts

  6. What you'd do differently

  7. 為什麼用這個方法不用 CNN based 方法?

    當初的方法還無法對 segmentation 做得很好,但我們需要 silhouette 才能做 pose estimation。

知識補充

  1. Connected component 計算

    可以參考 Leetcode - Number of Islands(用 DFS)

    // direction vectors
    const int dx[] = {+1, 0, -1, 0};
    const int dy[] = {0, +1, 0, -1};
    
    // matrix dimensions
    int row_count;
    int col_count;
    
    // the input matrix
    int m[MAX][MAX];
    
    // the labels, 0 means unlabeled
    int label[MAX][MAX];
    
    void dfs(int x, int y, int current_label) {
      if (x < 0 || x == row_count) return; // out of bounds
      if (y < 0 || y == col_count) return; // out of bounds
      if (label[x][y] || !m[x][y]) return; // already labeled or not marked with 1 in m
    
      // mark the current cell
      label[x][y] = current_label;
    
      // recursively mark the neighbors
      for (int direction = 0; direction < 4; ++direction)
        dfs(x + dx[direction], y + dy[direction], current_label);
    }
    
    void find_components() {
      int component = 0;
      for (int i = 0; i < row_count; ++i) 
        for (int j = 0; j < col_count; ++j) 
          if (!label[i][j] && m[i][j]) dfs(i, j, ++component);
    }

相關資料

Last updated