Simple range detector using flash light

[more demo]

第一篇先來個有趣的實驗,簡單方法重建栩栩如生的3D模型,文章最後附上Demo程式,希望可以提升讀者們的興趣

用普通的相機加上閃燈重建3D模型,來自於SIGGRAPH08的”A Perceptually Validated Model for Surface Depth Hallucination”

概念上是這樣的,假設一個物體為diffuse表面,也就是不反光的材質,利用有打閃光燈與沒有打閃光燈的差異可以得到一個物體表面的diffuse反射係數,想像離我們比較近的pixel強度比較大,閃燈嚴然成了一個簡易的測距工具,幾乎就要反映出物體深度拉。具體公式如下:

\[I^a(x,y)=\frac{I^f(x,y) – I^d(x,y)} {I^c(x,y)}\]

其中\(I^a(x,y)\)表示diffuse反射係數(Albedo),\(I^d(x,y)\)表示未打閃燈的影像(diffuse),\(I^f(x,y)\)則是有打閃燈的影像(Flash),最後\(I^c(x,y)\)則是校正用影像(Calibration)

\(I^d(x,y)\)img_d

\(I^f(x,y)\)img_f

\(I^c(x,y)\)img_c

這邊解釋為什麼需要\(I^c(x,y)\),由於閃燈的發光形狀可能會影響到\(I^f(x,y)\)的強弱,所以我們在相同打閃設定下在物體前放上一張白紙拍攝,以此作為閃燈結果的基本值。舉例來說,若閃燈距離很近,就可能產生光暈在畫面中間特強的影像,\(I^f(x,y)-I^d(x,y) \)的值永遠會呈現中間高四周低的結果,無法反映物體深度。除上\(I^c(x,y)\)可以normalize不同閃燈造成的深度誤差。

到此我們得到了\(I^a(x,y)\),看起來很像是\(I^d(x,y)\)的灰階版本,如下圖

\(I^a(x,y)\)diffuse_shading

不過這還不能成為深度影像,直接套用我們會得到一個非常noisy的3D模型,論文中的作法是類似利用不同模糊程度影像,由模糊到清晰依序的序疊加。此部份的操作就等同於由粗略的深度開始,逐漸刻出細節。權重的給法則是模糊影像較大,細節影像較小來壓制noise;做法接近multi-band blending。

pyramid

論文中的疊加過程修正了不同圖層間的權重,最後就得到我們的深度影像如下圖。這個方法也有其限制,一是物體材質必須要接近diffuse,二則是無法對有遮擋的物體進行完整重建,畢竟只有single view嘛! 優點則是便宜快速,看起來頗精緻,可以應用在遊戲貼圖上!

map

Demo程式下載

3D model為了即時渲染使用maya2011做了auto reduce處理,面數大約只有40000,與800*533原有精度些許落差。其實用bump mapping更省,不過那又是另外一個題目囉。

拖曳滑鼠左鍵改變模型方向
拖曳滑鼠右鍵改變光源方向
z、x改變鏡頭zoom in/zoom out
t開關材質貼圖
數字鍵1、2、3改變三種sample模型
你可能會需要Visual C++ 2010開啟專案或執行程式

這是修林奕成教授IBMR的project之一,本來是要挑戰實作迪士尼”High-Quality Single-Shot Capture of Facial Geometry”那篇的人臉重建,最後因為餅畫太大所以僅挑了Depth Hallucination來充數XD

在〈Simple range detector using flash light〉中有 2 則留言

    1. 謝謝! 其實我的研究和工作更有趣,連我自己都覺得是砸錢的黑科技,但是礙於商業秘密總是只能寫些一般論XD

發佈回覆給「adahbingee」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *