漫談計算攝像學

計算攝像學(Computational Photography)是近年來越來越受到注意的一個新的領域,在學術界早已火熱。本來計算攝像學的業界應用在羣衆中一直沒什麼知名度,直到Lytro公司推出了外觀十分酷炫的光場相機,打着“先拍照再對焦”的噱頭,這個學科一下子被很多研究領域以外的人開始注意到。那什麼是計算攝像學呢?讓我們看看清華大學和中科院的教授們怎麼說[1]

“計算攝影學是一門將計算機視覺、數字信號處理、圖形學等深度交叉的新興學科,旨在結合計算、數字傳感器、光學系統和智能光照等技術,從成像機理上來改進傳統相機,並將硬件設計與軟件計算能力有機結合,突破經典成像模型和數字相機的侷限性,增強或者擴展傳統數字相機的數據採集能力,全方位地捕捉真實世界的場景信息。”

這種定義雖然沒什麼錯誤,可其實相當於什麼都沒說。。個人覺得計算攝像學的定義得從一般的數碼攝影對比着來理解。一般的數碼攝影分爲兩個大步驟:1) 通過相機採集圖像;2) 後期處理。而在每個大步驟裏又有很多小的要素,比如1)裏,需要考慮光照,相機角度,鏡頭組(光學系統),傳感器等等,2)裏的方方面面就更多了,降噪,調曲線,各種PS濾鏡等等。如果這其中的每一個要素,我們都想辦法進行拓展和改變。比如用特殊手段照明,可以從不同角度,或者按一定的時序打閃光燈,再或者用可見光之外的光。又比如改變光學系統,可以調整光圈大小,調整相機鏡頭位置,或是改變光圈形狀等。而每一項採集圖像的改變,往往都需要相應的計算機算法後期處理,甚至採集到的數據可以用除了普通顯示器以外的方式呈現,那麼前面這些一套的成像辦法,就都可以歸入計算攝像學的範疇。更籠統一下,就是拓展了傳統數碼攝影中的某個或多個因素的維度來成像的方法,就是計算攝像學。其實現在早就被用的爛熟的HDR就是計算攝像學中的一種辦法,拓展的是傳統成像中的光圈大小。那麼,就當前計算攝像學的發展而言,這些拓展和改變都主要集中在哪些因素上呢?MIT的Raskar教授早就給出過結論:光學系統傳感器照明後期處理[2]。作爲漫談計算攝像學的第一篇,今天要談的光場,就是基於光學系統和後期處理上的拓展。

光場的定義

光場,顧名思義,就是關於光的某個物理量在空間內的分佈。這個概念第一次被明確提出是在1939年A. Gershun的一篇論文中[3],後來被E. H. Adelson和J. R. Bergen在上世紀末的一篇論文中完善,並給出了全光函數(Plenoptic Function)的形式。簡單來說,光場描述空間中任意一點向任意方向的光線的強度。而完整描述光場的全光函數是個7維函數,包含任意一點的位置(x, y, z),任意方向(極座標中的Θ, Φ),波長(λ)和時間(t)。附上從Raskar教授的講義裏截的圖:

在實際應用中,顏色和時間維度的信息通常是被RGB通道和不同幀表示,所以就光場而言,只關注光線的方向和位置就可以了,這樣就從7維降到了5維。而再一般的,大部分成像系統中光線都是在一個有限的光路里傳播,所以一種更簡單的,用兩個平面表示光場的方式被引入:

這種表示方式中,分別用兩個平面上的兩個點表示光線經過的兩個點,這樣一來光線的方向和位置都可以確定,並且維度降到了4個。注意到這樣雖然簡化了處理,可是侷限性是,在實際應用中,兩個平面都不是無限大的(即使是無限大也只能描述一半空間),光場可以描述的範圍被兩個平面的有效面積限制住了。

用數碼相機採集光場

知道了光場的定義,那麼是不是有什麼專門的神奇設備能夠在空間中採集這樣的4維信息呢?沒有的,光場雖然聽上去比較高大上,可通常採集的辦法還是傳統的成像系統:相機。最經典的光場採集辦法就是相機陣列,比如下圖是Stanford Multi-Camera Array:

所以就是把相機排列在了一個平面上而已。爲什麼這樣的相機陣列就採集了光場呢?我們先從最原始的針孔(Pinhole)相機模型談起:

小孔成像模型是最直觀也是最古老的成像模型,小孔相當於把光束的寬度限制得很小,所以如左圖光束通過小孔之後再像面上成了一個倒像。這種成像雖然簡單,然而一個重大不足是成像的分辨率被小孔大小限制着,小孔越小,則成像越清晰,然而光量也越小,像會很黯淡。爲了成明亮的像我們希望光束的量大,也就是小孔大,但也不希望光束的不集中導致成像模糊,所以很自然的,凸透鏡成像解決了這個問題。在凸透鏡成像系統中,不過鏡頭怎麼複雜,模式都是和中間的示意圖一樣,一個空間中的點發出的光束,打在透鏡的一塊麪積上後,折射,然後匯聚到一點。所以單從光線採集的角度而言,和小孔成像系統的沒有差別。那麼這和光場的聯繫在哪呢,回顧前面說的用兩個平面上的兩點座標表示廣場的辦法,如果我們這裏把鏡頭中心所在平面看成uv平面,定義鏡頭中心爲(0,0),而成像平面,也就是傳感器所在平面看成xy平面,則在普通的成像系統中捕捉到的一幅圖像可以看成是u=0, v=0出發的光線在傳感器平面上的採樣,也就是說我們採集了

L(0,0,x,y)|x,ysensor plane

其中每個L(0,0,x,y)的值就是傳感器上的像素值。一個直觀的例子是上圖的第三個光路圖,簡化到二維情況的話,只看L(u,x),假設在傳感器平面上有6個像素,那麼採集到的6條光線就分別是L(0,-1), L(0,-0.6), L(0,-0.2), L(0,0.2), L(0,0.6), L(0,1)。那麼很自然地,如果改變uv的位置,也就是鏡頭中心的位置,不僅能採集xy平面的光線,uv平面的也可以採集了,所以就能採集整個uv和xy間的光場了,所以相機陣列就相當於在uv平面上佈滿了很多采樣點。

當然,上面說的是最直觀最理想的情況,把相機近似成針孔模型還有個前提是景深足夠,另外我的例子裏xy平面是用傳感器所在平面定義,另一種流行的定義方法是用相機的焦平面,也就是在鏡頭前方,也就是上圖中的虛線箭頭,這種方法相對來說就更爲直觀了,尤其是在假設焦距很小的情況下,虛線所在的平面就是相機平面距離爲焦距的地方。事實上,在幾何光學裏,因爲光線是嚴格直線傳播,所以沿着光軸中心的不同位置上,如果都能採樣的話,那麼採到的像都是相似的,所以理論上講uv和xy平面是可以沿着光路的中心軸任意位置定義的。另外,除了用x和y,也有很多學者喜歡用s和t描述像平面,不過這僅僅是字母使用習慣上的不同。

相機陣列只是採集光場的最基本模型,實際實現的系統都是基於相機陣列的原理,但是具體結構非常不一樣。

Lytro

Lytro採用的是在傳感器表面覆蓋一層微鏡頭陣列[4]

微鏡頭陣列就是類似如下,近距離覆蓋在傳感器表面:

這個圖是Lytro創始人博士論文裏的原型機的陣列,(A)是陣列宏觀的可視效果,(B)和(C)是微觀結構,後來在Lytro中已經改進成了六邊形的鏡頭陣列。一個Lytro在傳感器成像的原始圖片如下:

可以看到和相機陣列不同,Lytro採集到的圖像是虛脫6邊型構成的,不過其實背後的原理都是一樣的,這一大幅看着像昆蟲眼睛採到的圖像是能夠通過算法轉化成前面提到的相機陣列等效圖像的,而每一幅等效的圖像又叫Sub-Aperture圖像。和Lytro類似的還有Raytrix的光場相機,不過Raytrix的採樣精度和採樣數都大幅高於玩具般的Lytro,屬於工業級光場相機。

Adobe Plenoptic Lenses

名字已經寫得很清楚了,lenses,和Lytro還有Raytrix不同,Adobe的光場相機把光場採樣鏡頭置於主鏡頭組前[5]

PiCam

這是個微縮版的相機陣列,用的就是手機上的那種鏡頭,4x4陣列,特點是用提出的算法優化了分辨率和深度圖估計[6]

微縮相機陣列裏還有一個例子是去年發佈的華爲榮耀6 Plus。

光場和3D

知道了光場的直觀意義,那麼很自然地就會想到和普通的照片比起來,獲取的信息不再是一幅簡單的2D像素陣列,而是三維空間中的光線,也就是說光場中是包含三維信息的。一個簡單的例子來說明:

左邊的例子是不同uv平面上的相機成像的差別,假設成像後焦平面都取相同的區域的話,可以看到因爲uv的不同,所以不同距離上的物體在最終的圖像上的位置也不一樣,其實這個就是典型的視覺中的Stereo問題。另外既然提到了Stereo,也需要特別提到的是,在相機陣列採集到不同拍照位置的圖像之後,有個非常重要的步驟叫做Calibration,也就是在選定的x平面上,要保證兩個相機視野是重合的,如左圖所示。那麼深度的信息是如何獲得的呢,來看下圖:

假象我們可以保持右邊的相機的光場不變,然後向左平移,使得藍色的光線在成像面上重合,那麼最終藍色方塊在兩個相機成像的照片裏位置就會完全相同,這其實就等效於把原始位置成的像向左移動了一段距離,然後和左邊相機成的圖像疊加,那麼就會發現藍色方塊重合了。類似的,如右圖所示,如果把右邊相機成的圖像向左移動一大段距離,那麼更遠的綠色三角圖像就重合了,要想是不同位置的物體重合就要對應不同的移動距離,而這個距離實際上是和物體到鏡頭的距離相關的,通過移動距離和相機採樣點之間距離的比值就可以輕易求出,進而就相當於我們得出了藍色方塊和綠色三角的深度信息。順帶提一句,讓藍色方塊和綠色三角重合的過程其實就已經是所謂的先拍照後聚焦的聚焦過程了,這篇文章不會展開來講。那麼再回到第一幅圖中的插值問題,如何通過兩個相機得到的圖像求出一個虛擬的在兩個相機之間的圖像呢?

以綠色三角爲例子,因爲我們用的是鏡頭前像平面的二維例子,所以這裏用L(x,u)表示入射到虛擬位置的光線,則有

L(x,u)=λ0L(x0,u0)+λ1L(x1,u1)

其實就是以虛擬位置到已有采樣位置的距離爲權重的線性插值。那具體到採集到的圖像這個過程是怎麼實現的呢,在相機陣列中需要注意的一點是不僅僅是相機採樣是離散點,圖像因爲是像素構成的所以也是離散採樣。示意圖如下:

所以實際上用來插值L(u,x)的光線採樣有4條,公式如下:

L(x,u)=λ0L(x00,u0)+λ1L(x01,u0)+λ2L(x10,u1)+λ3L(x11,u1)

其中

λ0=(1|xx00||x01x00|)(1|uu0||u0u1|)

λ1=(1|xx01||x01x00|)(1|uu0||u0u1|)

λ2=(1|xx10||x11x10|)(1|uu1||u0u1|)

λ3=(1|xx11||x11x10|)(1|uu1||u0u1|)

這是二維光場的情況,如果實際應用中需要對4維光場插值,則這個公式一共涉及到16條光線,下面是個示意圖:

公式看上去很複雜,不過直觀地理解也不困難,每根光線前的係數裏,和u有關的部分就是指將圖像按照相機採樣位置差異進行移動的幅度,也就是把採到的圖像進行平移(如下圖),而和x有關的部分就是在傳感器上對光線通過的位置進行插值。利用深度信息的輔助,在整幅圖像上進行這個過程就能得到一個沒有采樣點上的虛擬相機採到的插值圖像。

來做個簡單的實例試一試,用手機拍9幅照片,也就是3x3的採樣:

接下來是前面提到的Calibration,以中心的字母U作爲聚焦平面,並且重新構圖裁剪畫面:

做Calibration的過程中可以得到照片拍攝時的位置信息:

可以看到由於手持手機的誤差,我的採樣位置是很不規則的,不過能大概看出是在“田”字格上採樣,除了位置信息還能提取出深度信息,提取深度的算法有很多,爲了方便我這裏使用的是最原始的disparity比較:

接下來進行採樣插值,我採取的策略是在每四個採樣點之間進行Quadrilinear採樣:

採樣的效果怎麼樣呢,沿着我的採樣點我畫了條軌跡試試,起點和終點分別是左下角和右下角的採樣點,把對應的插值圖像提取出來,軌跡和對應的動圖如下:

在上一篇直觀理解光場中,談到了光場的基本概念、3D性質、實際應用中的採集辦法和插值求任意光線的辦法。這一篇繼續上一篇的基礎上給出利用光場實現“先拍照後聚焦”的原理和基本步驟。

對焦與光路

首先,什麼是對焦呢,我們先簡單回顧一下中學物理。

先看左圖,物體端的對焦面就是最上方的平面,從這個平面上的每一點發出的光線最後都匯聚在另一端的像平面上,一個典型的光路如加粗的四色直線所示。如果希望物體端的焦面移動到和原焦面到透鏡之間的位置,可以看到光線仍然是那些光線,但是聚焦到像面的光線組合就不再是之前的光線了,比如右圖裏,加粗的光線除了紅線以外,黑綠藍三色的光線都不再是原來的那幾根。對應對焦的基本光路,再回來看光場,根據上一篇文章中介紹過的光場的基本原理,很自然的,我們會想到,只要把在一個物平面上發出的光線所對應的像素疊加在一起,不就實現了重聚焦了嗎?事實上這就是最簡單的基於光場的重聚焦算法,叫Shift-and-Add[1]

先拍照後對焦的算法

還是藉助上一篇文章中的配圖來講解Shift-and-Add算法:

如左圖所示,在原始的採集位置上,藍色光線在兩幅採集到的圖像裏分別對應於不同的位置,所以如果要對焦於藍色的方塊,則需要將他們的相對位移消除,這一步就是Shift,然後在把兩個像素的平均值求出作爲對焦後的新圖像的像素值,則得到了對焦於藍色方塊的圖像。同樣道理,對於更遠的綠色三角,則進行更大距離的位移來消除對應像素之間的相對距離,然後疊加得到新的對焦於綠色三角的圖像。需要注意的是,如上面的小圖所示,移動疊加之後,邊緣部分總是有些像素是不重合的,所以或多或少都會形成瑕疵。

具體到上篇文章裏手機拍的照片例子,就是按照每張照片採樣位置相對於中心位置進行等比例的移動,就可以得到在不同物平面上重聚焦的圖像,比如我們選取9個採樣點的中心點作爲中心位置的話,將其他8個採樣點放置到不同位置上,就對應得到不同的重聚焦圖片:

綠圈位置對應圖像:

藍圈位置對應圖像:

就這麼簡單。那麼,Lytro中的算法是不是Shift-and-Add呢?答案是否定的,Lytro的算法是把平移-疊加這種空域的算法放到了頻域執行。基於的原理叫做中心切片定理,這裏只簡單提兩句,中心切片定理是二維的,不過其基本原理可以拓展到任意維度,Lytro中用的是其在4維時的應用。簡單來說就是把4維的光場進行傅里葉變換之後,在4D的傅里葉空間內,不同位置的重聚焦圖片分別對應一個穿過中心的不同角度的二維傅里葉空間的插值切片的逆傅里葉變換。所以本質上而言,這種辦法和Shift-and-Add沒有區別,只不過是把線性操作換到了頻域空間。shift-and-Add每次產生新的重聚焦圖片時都需要用到所有采集的光場信息,算法複雜度是O(n4)。而如果是從變換後4D數據裏產生新的重聚焦圖片,則分爲兩步:1) 求插值得到2D的傅里葉空間切片,複雜度是O(n2);2) 二維傅里葉逆變換,複雜度是O(n2log⁡n),當然爲了得到4D的傅里葉變換還有一步初始化計算,複雜度是O(n4log⁡n)。所以在已經有了採集到的4D數據需要不斷生成新的重聚焦圖片的場景下,在頻域的重聚焦算法時間上更經濟一些。更多關於頻域重聚焦算法的詳細,有興趣的朋友可以參考[1]

另外特別要提的一點是,在這種Shift-and-Add框架下的重聚焦算法,和實際相機成像的圖片是有區別的。原因就是第一節中對焦與光路部分。可以看到在凸透鏡光路中,不同位置上對焦的光線是互相不平行的,而Shift-and-Add算法下,所有光線都被認爲是“平行”移動的,所以在重聚焦後的照片中,虛化的部分圖像是不一樣的,然而這種差距對於人眼來說,其實也沒那麼大差別。

插值法去重影

可能有的朋友看到這裏已經發現了,雖然重聚焦是完成了,可是重對焦後圖像的質量並不好,比如上一節中對焦在Dell標誌上的一張:

花朵的部分有很明顯的重影,和用相機鏡頭照出來的顯然不一樣。通過前面部分的原理講解,這個原因也是很顯然的:因爲只有9個採樣點,在移動-疊加的過程中,不同圖像對應像素的移動超過了一個像素,則疊加後的圖像就會出現這種類似於重影的瑕疵。其實這個問題解決起來也很簡單,記得在上篇文章中,已經講過如何通過插值得到虛擬位置採樣的圖像,所以很自然地,我們只要通過插值,讓採樣點更密,密到每一個採樣點和相鄰採樣點的圖像上的對應像素的位移都小於或接近一個像素,那麼視覺上這種重影的現象就可以消除了。得到的結果如下:

最後來個連續變焦的動圖:

光圈的模擬

許多人在用傳統相機拍攝“虛化”照片時喜歡通過調整光圈來控制虛化的程度。這在基於光場的重聚焦中也是可以模擬的,道理很簡單,就是將採樣的範圍調整就可以了。還是用上一篇文章中的例子,比如用所有的採樣點(包括插值得到的):

得到的圖像:

而如果只採用中間一小部分的採樣點的話,相當於小光圈:

則得到虛化程度比較低的圖片:

[1] R. Ng, "Digital Light Field Photography," PhD thesis, Stanford University, Stanford, CA (2006)


參考文獻:

[1] http://wenku.baidu.com/link?url=ViSzmcYvSZNN-NYa-mxlqy8hnKJWxqj1hukSUYLIuVm79LUjYG54dfEOZTHVDGeMwsd4hFMTUepFMnsVLINlZ1o0-s5oGucwWg4o4RlejYG

[2] http://web.media.mit.edu/~raskar/photo/

[3] A. Gershun, “The light field,” J. Math. Phys., Vol. 18, pp. 51–151, 1939

[4] R. Ng, "Digital Light Field Photography," PhD thesis, Stanford University, Stanford, CA (2006)

[5] T. Georgiev, A. Lumsdaine, "Focused plenoptic camera and rendering," Journal of Electronic Imaging 19(2), 2010

[6] K. Venkataraman, et. al "PiCam: An Ultra-Thin High Performance Monolithic Camera Array," ACM Transactions on Graphics(SIGGRAPH) 2013

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