1. 程式人生 > >漫談計算攝像學 (二):利用光場實現“先拍照後對焦”

漫談計算攝像學 (二):利用光場實現“先拍照後對焦”

在上一篇直觀理解光場中,談到了光場的基本概念、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(n2logn),當然為了得到4D的傅立葉變換還有一步初始化計算,複雜度是O(n4logn)。所以在已經有了採集到的4D資料需要不斷生成新的重聚焦圖片的場景下,在頻域的重聚焦演算法時間上更經濟一些。更多關於頻域重聚焦演算法的詳細,有興趣的朋友可以參考[1]

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

插值法去重影

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

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

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

光圈的模擬

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

得到的影象:

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

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

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

相關推薦

漫談計算攝像 ()利用實現拍照

在上一篇直觀理解光場中,談到了光場的基本概念、3D性質、實際應用中的採集辦法和插值求任意光線的辦法。這一篇繼續上一篇的基礎上給出利用光場實現“先拍照後聚焦”的原理和基本步驟。 對焦與光路 首先,什麼是對焦呢,我們先簡單回顧一下中學物理。 先看左圖,物體端的對焦面就是最上方的平面,從這個平面上的每一點發出的

STM32應用實例十四利用極管實現光度測量

src 變化 數據 adc 得出 設計軟件 es2017 開發 是我 最近我們在開發臭氧發生器時,需要監測生成的臭氧的濃度,於是想到使用光度計來測量。因為不同濃度的臭氧對管的吸收作用是不相同的,於是檢測光照強度的變化就可以得到相應的濃度數據。 1、硬件設計 此次光照度檢測我

使用jmeter+ant進行接口自動化測試(數據驅動)之利用apache-ant執行測試用例並生成HTML格式測試報告

extras true -c 註釋符 www 文件的 介紹 ntc encoding 在 使用jmeter+ant進行接口自動化測試(數據驅動)之一 介紹了如何使用csv文件來批量管理接口 本次接著介紹如何利用apache-ant執行測試用例並生成HTML格式測試報告 ①下

Python3網絡爬蟲()利用urllib.urlopen向有道翻譯發送數據獲得翻譯結果

-c doctype result click 如果 enc tex 自己 數據 一、urlopen的url參數 Agent url不僅可以是一個字符串,例如:http://www.baidu.com。url也可以是一個Request對象,這就需要我們先定義一個

opencv學習筆記四十稠密流跟蹤

利用Gunnar Farneback演算法計算全域性性的稠密光流演算法(即影象上所有畫素點的光流都計算出來),由於要計算影象上所有點的光流,故計算耗時,速度慢  稠密光流需要使用某種插值方法在比較容易跟蹤的畫素之間進行插值以解決那些運動不明確的畫素 calcOpticalF

JAVA實驗利用維陣列(double[])實現一個矩陣類Matrix的相乘、轉置、相加等

題目:利用二維陣列(double[])實現一個矩陣類:Matrix。 要求提供以下方法: (1)set(int row, int col, double value):將第row行第col列的元素賦值為value; (2)get(int row,int col):取第row行第c

html5學習筆記利用canvas繪製簡單圖形

一,認識canvas Canvas是html5新增的開發跨平臺動畫 遊戲的標準方案,能夠實現對圖形和視訊進行畫素級操作,這為web圖形和視訊處理打開了廣闊的空間。藉助canvas,使用者可以再web中繪製各種圖形。Canvas元素及隨其而來的程式設計介面canvas api

QA()利用Attention機制,帶著問題閱讀

摘要 本文介紹一種結合 math-LSTM 和Pointer Net利用end-end的來解決QA問題的方式 模型 最主要的還是 match-LSTM:有兩個句子,一個是前提,另外一個是假設,match-LSTM序列化的經過假設的每一個詞,然後

LINUX攝像驅動虛擬驅動VIVI測試及徹底分析

LInux Kernel:3.4.2 gcc version: 4.3.2 測試虛擬驅動vivi 準備工作:安裝xawtv sudo apt-get install xawtv 在這個網站建立新的sources.list http://rep

python接口自動化測試python代碼實現接口測試

服務 獲取 解碼 odi false 壓縮 詳情 異常 將不 url = ‘接口地址‘ r = requests.get(url) #發送get請求 print(r.status_code) #打印狀態碼,若有重定向,返回的是重定向

DL之BigGAN利用BigGAN演算法實現超強炸天效果——畫風的確skr、skr、skr,太特麼的skr了

文章推薦Paper之BigGAN:ICLR 2019最新論文《LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS》論文研究中 本博主剛剛利用程式碼進行測試, 結果:的確吊(不)炸(可)天(思議)! PS:B

粒子濾波初探(利用粒子濾波實現視訊目標跟蹤-程式碼部分(C++&&opencv2.49)

利用粒子濾波實現視訊目標跟蹤工程實戰 放在最前:致謝taotao1233、yangyangcv、yang_xian521 以及先驅 Rob Hess 所開源的程式碼和思路。 本篇:基本為工程翻譯,以及對上面版本的一些修正,使用的是opencv2.49,以Ma

架構系列使用Nginx+tomcat實現叢集部署

在前面的一篇文章《架構系列一:系統架構的演變》中,簡單介紹了系統架構的演變,從單機到叢集部署,現在的企業級專案,可以說99.99%以上的專案,都是叢集部署,當叢集中的一個節點出現故障,會自動切換另一個節點,實現故障自動轉移,現在就基於Nginx+tomcat搭建

JVM物件的建立(詳解new發生的故事)

在Java中我們建立物件都會用new進行建立,下面我來接收一下new之後物件建立及記憶體分配的具體的過程 一:虛擬機器遇到一條new指令後,先去檢查這條指令引數是否能在常量池中定位到一個類的符號引用,並檢查這個符號引用代表的類是否已被載入、解析和初始化過,如果沒有,那必須先執行相應的類載入過程。

EL之Bagging利用Bagging演算法實現迴歸預測(實數值評分預測)問題

EL之Bagging:利用Bagging演算法實現迴歸預測(實數值評分預測)問題 輸出結果   設計思路   核心思路 #4.1、當treeDepth=1,對圖進行視覺化 #(1)、定義numTreesMax、

c++利用模板類實現氣泡排序

首先我們來明確函式模板與類模板的概念及其用法。 模板是一種對型別進行引數化的工具,通常有兩種形式------>函式模板和類模板。 函式模板針對僅引數型別不同的函式; 類模板針對僅資料成員和成員函式型別不同的類。 函式模板的格式:     template &l

Java專案開發心得(一)利用Java技術實現查詢手機號碼歸屬地

      鑑於最近專案涉及到查詢歸屬地的問題,今天在此做一下技術分享,如果有更好的建議,還請讀者大神指出。       迴歸正題,關於手機號碼歸屬地,想要查詢的無非是執行商、省份、市之類的資

實驗順序表的實現

一、實驗目的 建立一個由n個學生成績的順序表,n的大小由自己確定,每一個學生的成績資訊由自己確定,實現資料的對錶進行插入、刪除、查詢等操作。分別輸出結果。 二、實驗過程 #ifndef SeqList_H #define SeqList_H const int Maxsi

問題五十怎麼用C++實現矩陣運算

C++程式碼如下: bool matrix_4_4_multiply_4_4(const float matrix1[4][4], const float matrix2[4][4], float (&result)[4][4]) { //求兩個4*4矩陣的乘積 for (int

機器學習利用K-均值聚類算法未標註數據分組——筆記

最大的 相似度計算 最小 合並 表示 所有 改變 們的 描述 聚類:   聚類是一種無監督的學習,它將相似的對象歸到同一個簇中。有點像全自動分類。聚類方法幾乎可以應用於所有對象,簇內的對象越相似,聚類的效果越好。聚類分析試圖將相似對象歸入同一簇,將不相似對象歸到不同簇。相似