1. 程式人生 > >光場相機原理(Light-Field Cameras/Light Field Photography)

光場相機原理(Light-Field Cameras/Light Field Photography)

一個比較好的相關方面的網址:https://www.vincentqin.tech/posts/light-field-depth-estimation/#more

內容一:

光場相機原理

1.什麼是光場?

    簡單的說,光場就是光線,它包含光線本身的強度、位置和方向等資訊。一般採用兩個相互平行的平面來表徵光場,如圖所示


若一條光線通過兩個平面UV和ST所產生的交點座標分別為(u,v)和(s,t),此時就可以通過光場函式L(u,v,s,t)來表示這條光線的分佈。L代表光線的強度,而(u,v)和(s,t)共同確定了光線在空間中分佈的位置和方向。

    為什麼要用這種雙平面的方式來確定光場的分佈呢?這是因為常規的相機一般都可以簡化成兩個互相平行的平面——鏡頭的光瞳面和影象感測器所在的像平面。對於常規的相機來說,每個畫素記錄了整個鏡頭所出射光線會聚在一個位置上的強度,如圖所示.

所以,傳統的相機只能獲取一個像平面的影象。而如果能夠獲取到整個相機內的光場分佈情況,我們就可以將光線重新投影到一個虛擬的像平面上,計算出這個新的像平面上所產生的影象。光場相機的目的就在於對相機的光場分佈進行記錄。

### 2.光場相機是怎麼工作的?
    光場相機由鏡頭、微透鏡陣列和影象感測器組成,其中微透鏡陣列是多個微透鏡單元所組成的二維陣列。鏡頭的光瞳面(UV面)和影象感測器的光敏面(XY面)關於微透鏡陣列(ST)成共軛關係,也就是說,鏡頭經過每個微透鏡單元都會投影到影象感測器上形成一個小的微透鏡子影象。每個微透鏡子影象包含了若干個畫素,此時各畫素所記錄的光線強度就來自於一個微透鏡和鏡頭的一個子孔徑區域之間所限制的細光束,如圖。

這裡的細光束也就是光場的離散取樣形式,通過微透鏡單元的座標ST和鏡頭子孔徑的座標UV即能夠確定每個細光束的位置和方向,獲得L(u,v,s,t)的分佈。

### 3.怎麼實現數字對焦?
    正如前面所說,獲得相機內的光場分佈後,就可以重新選擇一個虛擬的像平面(如圖,

可以選擇更遠或更近的像面位置),計算出所有的光線在這個平面上的交點位置和能量分佈,從而就得到了一幅新像面上的影象。這個過程等價於傳統相機的調焦過程,只不過是通過數字計算來實現,因而被稱為數字調焦。
    利用光場相機的數字調焦能力,只需要一次曝光就可以計算出不同像平面位置的影象,能夠實現大光圈條件下的快速對焦。更進一步,利用不同深度平面的影象序列,可以完成全景深影象合成、三維深度估計等功能。

### 4.對焦示例

原始對焦位置在書上

 

數字調焦到近處

 

數字調焦到遠處

參考資料

周志良. 光場成像技術研究[D]. 中國科學技術大學, 2012.

內容二:光場相機重聚焦原理介紹及程式碼解析

光場相機重聚焦原理介紹及程式碼解析 
光場相機重聚焦–焦點堆疊深度估計法 
全部程式碼下載地址: 
https://download.csdn.net/download/weixin_38285131/10441175

光場相機主要是記錄了光線的方向和強度,記錄了四維資訊,因此具有深度資訊,並可以實現重聚焦等

對焦和變焦
聚焦顧名思義,就是聚焦在某一物體上,由於拍照的時候景深問題,不能使所有物體全部清楚,因此可以通過對焦或者是變焦,聚集在某一平面上,使該平面上的物體清晰。對焦就是改變感測器與主鏡頭的距離來實現這一過程的 ,而變焦改變的是主鏡頭的焦距實現這一過程,可以自己琢磨一下就能明白。

重聚焦公式
個人理解的重聚焦就是同一條光線,當改變像面時,對新的位置進行積分所成的像 
 
S為成像面,重聚焦實際過程就是改變S的位置,使不同深度的影象清楚。S’為新的成像面,l’=alpha*l,,S’面上所成的像為US’之間光場的積分: 


對於同一根光線,有 
 
我們可以通過他們之間關係可得: 
 
進一步推導可得,s和s’之間的關係 
 
將上面的式子帶入積分公式,可得: 
 
上面的式子即為投影到新的平面上的成像公式,擴充套件到四維情況,在Ng的論文中提到了: 


所以重聚焦就是在空間平移然後在角度上進行積分

重聚焦程式碼解析
這個重聚焦程式碼是Tao給出的Matlab和C混合編譯的,這裡只有核心的部分程式碼,我在這裡解釋一下。

void remapping
        (
        double * im_in_remap,//輸入原始的光場影象
        double * im_out_remap,//輸出對映好的光場影象
        double * output_image,//重聚焦影象
        unsigned short width,//空間解析度的寬
        unsigned short height,//空間解析度的高
        unsigned short window_side,//角度解析度邊長或者說是微透鏡直徑
        unsigned short stereo_diff,//大小等於微透鏡半徑
        double         alpha//alpha就是每次改變平面的alpha值,L'=alpha*L
        )
    {
    int                 x,y ;//空間解析度的長和寬
    unsigned int        x_1,x_2,y_1,y_2;//改變焦平面之後座標值相鄰的四個元素的左上角和右下角的畫素的座標
    int                 i,j;
    double              x_ind,y_ind   ;//改變焦平面之後,光線落在新的焦平面上的座標值,一般有小數
    double              x_floor,y_floor ;
    double              x_1_w,x_2_w,y_1_w,y_2_w;//新的座標值離相鄰四個畫素值的權重,根據距離計算
    unsigned int        x_1_index,x_2_index,y_1_index,y_2_index  ;//相鄰四個座標的x和y座標值
    unsigned int        x_index_remap,y_index_remap ;//這個是Tao論文裡的關於整副原始影象重聚焦的,可以忽略
    double              interp_color_R,interp_color_G,interp_color_B    ;//三個通道
    double              output_color_R,output_color_G,output_color_B    ;//重聚焦插值之後輸出的影象
    unsigned int        height_of_remap, width_of_remap, pixels_of_remap;//對映完之後原始影象高,寬,畫素個數
    int                 window_size                                     ;//大小為微透鏡直徑

    window_size = window_side*window_side               ;//微透鏡下面覆蓋的畫素值個數

    height_of_remap = height*window_side                ;//子孔徑影象高乘以微透鏡直徑
    width_of_remap  = width*window_side                 ;//子孔徑影象寬乘以微透鏡個數
    pixels_of_remap = height_of_remap*width_of_remap    ;//對映完之後的原始影象畫素個數

    for (x = 0; x < width; ++x)//從左到右從小到下進行遍歷
        for (y = 0; y < height; ++y)
        {
        output_color_R =0;//三個通道
        output_color_G =0;
        output_color_B =0;

        for (i = -stereo_diff; i < stereo_diff+1; ++i)//相當於u和v,角度解析度
            for (j = -stereo_diff; j < stereo_diff+1; ++j)
            {
            x_ind   = i*(1-1/alpha) + x;//根據公式,新的焦平面上x的座標  新的座標:x+u(1-1/alpha)
            y_ind   = j*(1-1/alpha) + y;//同理,y座標   y+v(1-1/alpha)

            x_floor = floor(x_ind);//向下取整
            y_floor = floor(y_ind);

            x_1     = index_x(x_floor  ,width );//進行邊界判斷
            y_1     = index_y(y_floor  ,height);
            x_2     = index_x(x_floor+1,width );
            y_2     = index_y(y_floor+1,height);

            x_1_w   = 1-(x_ind-x_floor)        ;//計算四個相鄰畫素插值的權重,越近權重越大
            x_2_w   = 1-x_1_w                  ;
            y_1_w   = 1-(y_ind-y_floor)        ;
            y_2_w   = 1-y_1_w                  ;

            x_1_index = i+stereo_diff + (x_1)*window_side   ;//這個是用於原始影象重聚焦的,可以忽略
            y_1_index = j+stereo_diff + (y_1)*window_side   ;
            x_2_index = i+stereo_diff + (x_2)*window_side   ;
            y_2_index = j+stereo_diff + (y_2)*window_side   ;

            interp_color_R = y_1_w*x_1_w*im_in_remap[y_1_index+x_1_index*height_of_remap+0*pixels_of_remap]+//對三個通道根據四個相鄰畫素進行插值
                             y_2_w*x_1_w*im_in_remap[y_2_index+x_1_index*height_of_remap+0*pixels_of_remap]+
                             y_1_w*x_2_w*im_in_remap[y_1_index+x_2_index*height_of_remap+0*pixels_of_remap]+
                             y_2_w*x_2_w*im_in_remap[y_2_index+x_2_index*height_of_remap+0*pixels_of_remap];
            interp_color_G = y_1_w*x_1_w*im_in_remap[y_1_index+x_1_index*height_of_remap+1*pixels_of_remap]+
                             y_2_w*x_1_w*im_in_remap[y_2_index+x_1_index*height_of_remap+1*pixels_of_remap]+
                             y_1_w*x_2_w*im_in_remap[y_1_index+x_2_index*height_of_remap+1*pixels_of_remap]+
                             y_2_w*x_2_w*im_in_remap[y_2_index+x_2_index*height_of_remap+1*pixels_of_remap];
            interp_color_B = y_1_w*x_1_w*im_in_remap[y_1_index+x_1_index*height_of_remap+2*pixels_of_remap]+
                             y_2_w*x_1_w*im_in_remap[y_2_index+x_1_index*height_of_remap+2*pixels_of_remap]+
                             y_1_w*x_2_w*im_in_remap[y_1_index+x_2_index*height_of_remap+2*pixels_of_remap]+
                             y_2_w*x_2_w*im_in_remap[y_2_index+x_2_index*height_of_remap+2*pixels_of_remap];

            // CORRESPONDENCE ANALYSIS
            x_index_remap = i+stereo_diff + (x)*window_side   ;
            y_index_remap = j+stereo_diff + (y)*window_side   ;

            im_out_remap[y_index_remap + x_index_remap*height_of_remap + 0*pixels_of_remap] = interp_color_R;
            im_out_remap[y_index_remap + x_index_remap*height_of_remap + 1*pixels_of_remap] = interp_color_G;
            im_out_remap[y_index_remap + x_index_remap*height_of_remap + 2*pixels_of_remap] = interp_color_B;

            // DEFOCUS ANALYSIS
            output_color_R = interp_color_R + output_color_R;//該alpha值下各個通道計算之後的單通道影象
            output_color_G = interp_color_G + output_color_G;
            output_color_B = interp_color_B + output_color_B;

            }
        output_image[y + x * height + 0 * height*width] = output_color_R/window_size;//三通道重聚焦影象
        output_image[y + x * height + 1 * height*width] = output_color_G/window_size;
        output_image[y + x * height + 2 * height*width] = output_color_B/window_size;

        }
    }


注:1.Tao是用LFToolBox計算出了相機微透鏡的中心點座標,然後根據中心點和坐對原始影象進行了重新取樣,也就是上面程式碼中的im_in_remap,每個微透鏡下面以中心取radius*radius個畫素,即角度解析度個畫素 
2.Tao在論文裡面進行了256層重聚焦,alpha範圍為(0.2,2),因此每一次改變焦平面,alpha值增加(2-0.2)/256 
3.他輸入的中心點座標image_cords是[m,n,2],2代表橫座標,1是縱座標,這個需要注意。

結果展示
輸入的原始影象 

部分重聚焦影象 
alpha=0.2時: 
 
alpha=0.2+(1.8/256)*78時: 
 
alpha=2時: 


參考: 
1.光場成像技術研究-周志良 
2.Light Field Photography with a Hand-held Plenoptic Camera–Ren-Ng 
3.Depth from Combining Defocus and Correspondence Using Light-Field Cameras-W.Tao 
4.https://www.cnblogs.com/riddick/p/6731130.html
轉:https://blog.csdn.net/weixin_38285131/article/details/80457068