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