結構光相移法-多頻外差原理+實踐(上篇)

作者:曹博

來源:微信公衆號|3D視覺工坊(系投稿)

3D視覺精品文章彙總:https://github.com/qxiaofan/awesome-3D-Vision-Papers/

點擊上方“3D視覺工坊”,選擇“星標”

乾貨第一時間送達

01 相移法原理
02 雙頻外差原理
03 多頻率外差原理
04 代碼實踐

01 相移法原理

結構光法原理其實是跟雙目視覺一樣的,都是要確定對應“匹配點”,利用“視差”三角關係計算距離,所不同的是:

  • 雙目視覺通過“被動”匹配唯一特徵點
  • 相移法作爲結構光法中的一種,通過主動投影多副相移圖案來標記唯一位置。

說明:雖然大多數結構光系統是單目的,但我們可以將其“雙目”的,因爲投影儀可以看做是一個“逆向”的相機,明白了這點,對於結構光系統一些公式推導就容易很多。

對於“雙目”系統來說,最重要的工作是通過唯一標記來標記某一點,假設我們只投射一個週期的數據,我們從投影儀投出去的光柵公式如下:

其中:

比如說四步相移公式:

我們主要關心的是求解出相位主值,因爲它對每個像素點是唯一的,假設我們從相機中獲取了這四副圖像,那怎麼反過來求解相位主值?

需要說明的是,雖然這個公式對整副相移圖像的,但是這公式對每個像素都是獨立的,所以即使我們拿從相機拍攝到經過調製變形的圖像來求解,依然可以得到單個像素點唯一的相位主值。

聯立4個方程,得到:

無論:

  • 哪臺相機
  • 拍攝到什麼圖像

我們要得到某個像素點的唯一“標記”,也就是這個相位主值,代回這個公式即可,都可以得到唯一值。得到了唯一值,建立匹配關係,就可以利用三角公式進行重建。

其中:橫座標爲任意一行的像素,這張圖中使用週期爲11的像素條紋作爲正弦光柵。

02 雙頻外差原理

解決的方法有很多,分爲空域和時域展開兩種:

  • 空域展開:依靠空間相鄰像素點之間的相位值恢復絕對相位,如果重建表面不連續,則出現解碼錯誤。
  • 時域展開:將每個像素點的相位值進行獨立計算,有格雷碼和多頻外差兩種,其中格雷碼方法對物理表面問題敏感,並且多投影的圖並不能用來提升精度,多頻外差精度更高。

當然目前還有更多精度更高、效率更快的相位展開方法,在這裏暫時不予討論,這裏主要討論多頻外差原理。

多頻外差原理:通過多個不同頻率(週期)正弦光柵的相位做差,將小週期的相位主值轉化爲大週期的相位差,從而使得相位差信號覆蓋整個視場,然後再根據相位差來得到整副圖像的絕對相位分佈。

這裏以雙頻外差爲例,原理如圖1所示:

注:通常我們說的相位函數的週期,代表的是一個週期正弦函數所佔的像素單位個數。

03 多頻率外差原理

其可以完成整個視場的無歧義標記。

04 代碼實踐

依據相移法得到的包裹相位圖如下圖所示,不同顏色代表不同頻率的相位主值:

我們進行疊加後的效果:

在這裏,我們可以看到,由兩個週期小的相位可以合成一個週期更大的編碼圖案。

其中:

明白了原理,我們來代碼實踐一下,需要注意的是,求解出來的相位我們要進行歸一化到區間操作

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus'] = False    # 用來正常顯示負號


def phase_simulation(WIDTH, T1, T2, T3):
    pha1, pha2, pha3 = np.zeros(shape=WIDTH), np.zeros(shape=WIDTH), np.zeros(shape=WIDTH)
    t1, t2, t3 = 1, 1, 1
    for idx in range(WIDTH):
        if t1 > T1: t1 = 1  # 重置一下
        pha1[idx] = (t1 / T1) * 2 * np.pi
        if t2 > T2: t2 = 1
        pha2[idx] = (t2 / T2) * 2 * np.pi
        if t3 > T3: t3 = 1
        pha3[idx] = (t3 / T3) * 2 * np.pi
        t1 += 1; t2 += 1; t3 += 1
    return pha1, pha2, pha3


def parse_phase(pha1, pha2, T1, T2):
    pha12 = np.zeros_like(pha1)
    # 計算Delta(如果滿足條件,輸出左側,否則右側)
    pha12 = np.where(pha1 >= pha2, pha1 - pha2, pha1 - pha2 + 2 * np.pi)
    # # 跟下面這段代碼等價
    # for idx in range(0, pha12.shape[0]):
    #     if pha1[idx] >= pha2[idx]:
    #         pha12[idx] = pha1[idx] - pha2[idx]
    #     else:
    #         pha12[idx] = pha1[idx] - pha2[idx] + 2 * np.pi

    T12 = T1 * T2 / (T2 - T1)
    # 方法1
    pha12 = T2 / (T2 - T1) * pha12
    # # 方法2
    # m = np.round((T2 / (T2 - T1) * pha12 - pha1) / (2 * np.pi))
    # pha12 = 2 * np.pi * m + pha12

    # 歸一化到[0,2π]
    min_value, max_value = np.min(pha12), np.max(pha12)
    pha12 = (pha12 - min_value) * (2 * np.pi / (max_value - min_value))
    return pha12, T12


if __name__ == '__main__':
    # 視場寬度
    WIDTH = 854
    # 條紋週期
    T1 = 11
    T2 = 12
    T3 = 13
    pha1, pha2, pha3 = phase_simulation(WIDTH, T1, T2, T3)
    X = np.arange(0, WIDTH)
    plt.plot(X, pha1, label="pha1")
    plt.plot(X, pha2, label="pha2:")
    plt.plot(X, pha3, label="pha3")
    plt.title("相移主值圖(仿真)")
    plt.xlabel("像素")
    plt.ylabel("w/rad")
    plt.legend()
    plt.show()

    # 解相位
    pha12, T12 = parse_phase(pha1, pha2, T1, T2)
    pha23, T23 = parse_phase(pha2, pha3, T2, T3)
    pha123, T123 = parse_phase(pha12, pha23, T12, T23)

    plt.plot(X, pha12, label="pha12")
    plt.plot(X, pha23, label="pha23")
    plt.plot(X, pha123, label="pha123")
    plt.title("解出絕對相位")
    plt.xlabel("像素")
    plt.ylabel("w/rad")
    plt.legend()
    plt.show()

可以看出,最終解出的絕對相位線單調遞增,每個相位值時唯一的,雖然在一些交界處會有些許誤差。

結構光多頻外差的原理很簡單,而精度這塊,其實很大程度依賴於標定、高反處理這些地方。這一期內容將分爲上下兩期,爲了便於理解,不再講述更多內容,更多我們下一期再講!怎麼拿實際投影拍攝到的光柵圖片來還原絕對相位!

備註:作者也是我們「3D視覺從入門到精通」特邀嘉賓:一個超乾貨的3D視覺學習社區

本文僅做學術分享,如有侵權,請聯繫刪文。下載1在「3D視覺工坊」公衆號後臺回覆:3D視覺,即可下載 3D視覺相關資料乾貨,涉及相機標定、三維重建、立體視覺、SLAM、深度學習、點雲後處理、多視圖幾何等方向。
下載2在「3D視覺工坊」公衆號後臺回覆:3D視覺github資源彙總,即可下載包括結構光、標定源碼、缺陷檢測源碼、深度估計與深度補全源碼、點雲處理相關源碼、立體匹配源碼、單目、雙目3D檢測、基於點雲的3D檢測、6D姿態估計源碼彙總等。
下載3在「3D視覺工坊」公衆號後臺回覆:相機標定,即可下載獨家相機標定學習課件與視頻網址;後臺回覆:立體匹配,即可下載獨家立體匹配學習課件與視頻網址。

重磅!3DCVer-學術論文寫作投稿 交流羣已成立掃碼添加小助手微信,可申請加入3D視覺工坊-學術論文寫作與投稿 微信交流羣,旨在交流頂會、頂刊、SCI、EI等寫作與投稿事宜。
同時也可申請加入我們的細分方向交流羣,目前主要有3D視覺、CV&深度學習、SLAM、三維重建、點雲後處理、自動駕駛、多傳感器融合、CV入門、三維測量、VR/AR、3D人臉識別、醫療影像、缺陷檢測、行人重識別、目標跟蹤、視覺產品落地、視覺競賽、車牌識別、硬件選型、學術交流、求職交流、ORB-SLAM系列源碼交流、深度估計等微信羣。一定要備註:研究方向+學校/公司+暱稱,例如:”3D視覺 + 上海交大 + 靜靜“。請按照格式備註,可快速被通過且邀請進羣。原創投稿也請聯繫。▲長按加微信羣或投稿▲長按關注公衆號

3D視覺從入門到精通知識星球:針對3D視覺領域的知識點彙總、入門進階學習路線、最新paper分享、疑問解答四個方面進行深耕,更有各類大廠的算法工程人員進行技術指導。與此同時,星球將聯合知名企業發佈3D視覺相關算法開發崗位以及項目對接信息,打造成集技術與就業爲一體的鐵桿粉絲聚集區,近2000星球成員爲創造更好的AI世界共同進步,知識星球入口:

學習3D視覺核心技術,掃描查看介紹,3天內無條件退款 圈裏有高質量教程資料、可答疑解惑、助你高效解決問題覺得有用,麻煩給個贊和在看~  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章