利用光場進行深度圖估計(Depth Estimation)算法之一——聚焦算法


前面幾篇博客主要說了光場相機,光場相機由於能夠記錄相機內部整個光場,可以實現重聚焦(模糊線索)和不同視角的變換(視差線索),同時也可以利用這個特性進行深度估計(Depth Estimation)。

 

先說一下利用重聚焦得到的不同聚焦平面圖像獲取深度圖(模糊線索 ,defocus),其實這個原理非常簡單。

 

1. 以聚焦范圍為0.2F-2F為例,alpha∈(0.2,2),取Depth Resolution=256, 那么步長就為(2-0.2)/256,我們通過重聚焦算法可以獲取得到這個范圍內的256幅重聚焦圖像。

 

2. 對每一幅重聚焦的圖像進行求梯度的操作,得到梯度圖,比如使用matlab中的Gradient2D()函數,得到256幅梯度圖。注意,都是三通道的,所以求梯度也要在每一個通道進行。

用C++實現的gradient2D的代碼如下:

 

 1 void gradient2D(Mat input, Mat& output)
 2 {
 3     Mat Ix(input.size(), CV_32F);
 4     Mat Iy(input.size(), CV_32F);
 5     //get Iy
 6     for (int nrow = 0; nrow < input.rows; nrow++)
 7     {
 8         for (int ncol = 0; ncol < input.cols; ncol++)
 9         {
10             if (ncol == 0)
11             {
12                 Ix.at<float>(nrow, ncol) = abs(input.at<uchar>(nrow, 1) - input.at<uchar>(nrow, 0));
13             }
14             else if (ncol == input.cols - 1)
15             {
16                 Ix.at<float>(nrow, ncol) = abs(input.at<uchar>(nrow, ncol) - input.at<uchar>(nrow, ncol - 1));
17             }
18             else
19             {
20                 Ix.at<float>(nrow, ncol) = abs((input.at<uchar>(nrow, ncol + 1) - input.at<uchar>(nrow, ncol - 1)) / 2.0);
21             }
22         }
23     }
24     //get Ix
25     for (int nrow = 0; nrow < input.rows; nrow++)
26     {
27         for (int ncol = 0; ncol < input.cols; ncol++)
28         {
29             if (nrow == 0)
30             {
31                 Iy.at<float>(nrow, ncol) = abs(input.at<uchar>(1, ncol) - input.at<uchar>(0, ncol));
32             }
33             else if (nrow == input.rows - 1)
34             {
35                 Iy.at<float>(nrow, ncol) = abs(input.at<uchar>(nrow, ncol) - input.at<uchar>(nrow - 1, ncol));
36             }
37             else
38             {
39                 Iy.at<float>(nrow, ncol) = abs((input.at<uchar>(nrow + 1, ncol) - input.at<uchar>(nrow - 1, ncol)) / 2.0);
40             }
41         }
42     }
43     magnitude(Ix, Iy, output);
44 }
View Code

 

 

 

 

3.對每一幅梯度圖在局部窗口內進行均值濾波,相當於參考每一個像素點處的鄰域梯度值,增加魯棒性。這個可以簡單的使用OpenCV中的Blur()函數實現。

 

4.均值濾波后的圖像也是三通道的,這一步需要將每一個像素點處的三個通道值求平均,得到灰度圖像。每一個像素點處的灰度值就為其對應的梯度值,而大家都知道,梯度值能夠反應邊緣、紋理等信息。

 

5.在每一個像素點處,遍歷256幅圖像,找到梯度值最大的那一幅圖像(即該點在這一幅圖像中最清晰,也就是聚焦到該像素點對應的物平面),獲取該圖像的索引值。(比如某一像素點處的第200幅圖像中的梯度值最大,則記錄index=200)。遍歷所有像素點,並獲取索引值。這樣得到的是一幅索引圖像,每一個像素點處的值對應為該點在該索引下的圖像中梯度最大,在程序中為0~255.

6.得到上述索引圖后就簡單了,可以根據每一個像素點處的索引值找到對應的alpha值,也就相應的得到alpha*F的值,該值就為像距V。

 

7.得到像距V,根據光學中的物像位置公示1/U +1/V = 1/F。V和F均已知,當然可以算出該點處的U值,而U就是深度,深度圖就得到了。

 

這次沒有放圖,有時間再放上去,原算法參考論文為[1],中文較為詳細的參考[2]

[1] Tao M W, Hadap S, Malik J, et al. Depth from combining defocus and correspondence using light-field cameras[C]//Proceedings of the IEEE International Conference on Computer Vision. 2013: 673-680.

[2] 楊德剛, 肖照林, 楊恆, 等. 基於光場分析的多線索融合深度估計方法[J]. 計算機學報, 2015, 38(12): 002437-2449.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM