Light Field 光场以及Matlab光场工具包(LightField ToolBox)的使用说明

2021-05-28 15:49:16 浏览数 (1)

我在这篇文章里详细介绍了光场数据的处理过程,如果你是研究光场领域的新手,这篇文章对你来说应该是非常有用的。声明一下:一切理解都是本人观点,如有疑问,还望在评论中留言。如需转载请与本人联系,谢谢合作!

光场相机

首先介绍下目前我正在使用的光场相机。大家在刚刚进入光场领域的时候如果想自己采集数据,消费级别的手持光场相机Lytro或者ILLUM应该是不二之选。如图为实验室的设备(我可买不起ILLUM)

(Left).Lytro; (Right).Illum

以上是Lytro公司推出的两款光场相机,左图是第一代光场相机,右图是第二代。

二代相对于一代在光场角度以及空间分辨率方面都有所提升,用户体验相比于一代也有了很大的改进。本文重点不在于此,我将会介绍用光场相机采集完成数据之后,如何获取光场数据的过程。

以下的介绍的前提是你有光场相机,如果没有的话,请直接跳转到文末「没有相机怎么搞」

获取LFP 或者 LFR源文件

由Lytro拍摄的图像的源图像格式是.lfp/.lfr格式,我们要对其解码成我们需要的格式。

工具:Lytro DesktopMatlab光场工具包(很强大,推荐;本文介绍该方法)。

用神奇的数据线把你的相机连接到电脑,打开Lytro Desktop,点击想要导入的图片,选中点击右上角立即处理。

然后打开我的电脑图片/Lytro Desktop/Libraries/Lytro 图库.lytrolibrary*,就可以发现有很多文件夹名字是一串很长数字字母。点击进去就可以发现好几个文件,以Lytro为例,这几个文件如下形式:

(Light field files)

raw.lfp就是我们需要的原文件,之后我们就要利用Matlab光场工具包对其进行解码操作

Matlab Light Field ToolBox(光场工具箱)的使用

下载光场工具包(LFToolBox)

假设你已经有了光场数据,我们接下来用Matlab'光场工具包对其进行解码。

首先下载光场工具包并仔细阅读说明文档,根据文档把相应的数据拷贝到工具箱的文件夹下(这一步很关键,要仔细配置)。

如果不想在官网下载的话可以下载我在Github上传了一个版本,大家可以git clone文末的几个链接。下载下来的工具包是这样的:

(工具包文件夹)

LFToolbox0.4就是我们要的工具包,里面包含很多函数,如下图:

(工具包函数)

我把一些比较常用的函数或者文档用红色的框标注出来,其中PDF文档是该工具包的说明书。

这个说明书中详细的介绍了该工具包的使用方法,我们完全可以根据该文档的介绍来实现自己想要的功能。如下是该说明书的首页截图:

(说明文档)

该说明文档提供了一系列函数,用于从lfp/lfr文件中提取自己感兴趣的各种信息:白图像(white image),Raw Image,对齐后的图像,以及颜色校正,频域滤波后的图像等。

前期准备

STEP 1
「创建自己的工作目录」

如果是直接clone我在github上的工程的话直接跳转step 2。如果没有,那就要建立自己的工作目录,便于文件的管理。这一步是必要的,如果建立的目录不一致,可能导致程序无法运行,这也是我当时初次用这个工具包时常常出错的地方。好了,建立这样的目录结构:

(文件目录)

STEP 2
「根据相机序列号修改文件名」

Sample_test表示我们的测试目录,里面包含了相机信息以及自己拍摄照片的图像(lfp/lfr)。

Cameras这个目录中又包含了几个文件夹,它们分别是以“A”或者“B”开头,在其后面有一长串数字,这其实就是光场相机的serial number.

我们可以从默认目录 :

c:Users\AppDataLocalLytrocamerassn-serial_number中找到。

这个数字每个相机不一样,大家根据自己的相机序列号修改这个目录。

”A”表示的是Lytro系列相机,“B”表示ILLUM系列相机;以上图为例,”A303134427”就是我相机的序列号。

STEP 3
「把白图像文件拷贝到相应的文件夹下」

在每个序列号文件夹下又有一个文件夹WhiteImages,这里面放着由该相机拍摄的白图像。所谓白图像就是由光场相机拍摄的白色的图像,当然自己也可以拿着光场相机对着白色的墙面拍几张,但是由于受到环境噪声以及相机传感器的限制,其效果并不一定很好。

庆幸的是LYTRO官方提供了白图像,以Lytro为例,我们可从以下目录找到: c:Users usernameAppDataLocalLytrocamerassn-serial_number。如下图所示:

(图像目录)

我们发现这里有以下4个文件:data.C.0/1/2/3,这是官方把白图像以及配置文件压缩成了这种特殊的格式。我们需要的就是这四个文件,并需要用光场工具箱对其进行处理。

拷贝出这4个文件,放在Sample_test/Cameras/A303134643/WhiteImages文件夹里。这一步相当关键,一定要确保拷贝对了目录。注意,Illum相机的白图像与Lytro的白图像的存放位置不一样,在相机的SD卡里。

STEP 4
「将测试文件放到Images目录」

Images文件夹下包含我们需要处理的文件们,F01下存放Lytro系列拍摄的文件,B01下存放ILLUM系列拍摄的文件。

Lytro为例,由于前面已经有了测试文件raw.lfp,我们就把这个文件放在F01下。经过我们上述的过程之后,最后我们的目录会变成这样(注意:Sample_test与LFToolBox0.4为同级目录,各个文件夹的名字务必正确):

(文件目录结构)

测试开始

我使用的电脑配置是:Intel(R) Core(TM) i7-4790 CPU @3.60GHz 3.60GHz RAM 16GB。

文末有一个名为Demo.m的测试文件,接下来的过程就是Running code了。该测试程序大致可以分为以下几个测试:

  • 处理白图像
  • 解码LFP文件
  • 频域滤波
  • 颜色校正
STEP 1
「处理白图像」

处理白图像的目的是得到相机的某些参数(我当时是为了获得每幅光场的中心点坐标才进行的这一步)。因为白图像拍摄的场景没有纹理,此时可以清楚地观察到微透镜成像的边界信息。如下图所示的正六边形结构:

(白图像宏像素块)

可以看到的是,微透镜下的成像是这种正六边形的网格,类似于蜂窝的结构,感觉很清爽。需要注意的是,该过程并非简单地提取出一张白图像,而是提取几十张白图像对(image pairs),所以这个过程运行起来有点久,以下是运行的截图:

STEP 2
「解码LFP文件」

如果只是单纯地读取lfp/lfr或者raw文件的数据,光场工具包提供的如下函数:LFReadLFP、LFReadRaw。

注意两个函数的返回值不一样。

LFReadLFP返回一个结构体类型的变量,它包含相机的各个信息,我们可以根据自己的需要保留数据。

LFReadRaw返回的是一张uint16的灰度图,还没有经过demosaicing操作。去马赛克操作在malatb中有相应的函数,这点不用担心。

我们在这里不是直接调用的LFReadLFP而是调用了工具箱提供的LFLytroDecodeImage函数。

如果运行有问题(若是直接clone我github上项目的话,不需要修改),将LFLytroDecodeImage中的WhiteImageDatabase路径由以下:

代码语言:javascript复制

改为:

代码语言:javascript复制

经过这样的修改之后,程序应该可以跑了。假如解码成功,我们可以得到类似于这样的图像:

(原始光场图像)

局部放大效果图:

(光场图像局部放大图)

所有视角的图像:

(原始光场多视角图像)

这时候可以看到在边界视角上的图像比较黑,所以我们接下来要进行频域滤波,以及颜色校正。

STEP 3
「频域滤波以及颜色校正」

这部分分别用到了LFFilt4DFFT以及LFColourCorrect函数。

以LYTRO 1.0 为例子,我们得到的光场图像共有11*11个视角,但是这121个视角子孔径图像的质量真的不敢恭维,尤其是边角处的视角(u=1,v=1)时,这个图像时完全变成黑色的。

所以,LFFilt4DFFT这个函数是将这些变成黑色的图像或者质量不好的图像进行校正的,具体原理不作展开。LFColourCorrect这个函数是利用gamma变化对原始图像进行颜色校正的,这一点比较简单。

总之利用这两个函数能够让我们得到的光场图像的质量更好,当然你也可以选择不用。

以下是经过滤波之后的所有子孔径图像,可以发现边界的视角相比于频域滤波之前有了很好的可视性。

(频域滤波之后的光场多视角图像)

以下是经过颜色校正之后的所有所有子孔径图像:

(频域滤波 颜色校正的光场多视角图像)

经过以上的步骤我们可以学习到白图像的处理,以及光场图像的处理等操作。当然我没有列出这个工具包所有的功能介绍,大家可以根据需要建立自己工程,对自己的数据进行测试,以上!

注意事项及测试代码

「参数设置好了再Run」

不少同学是因为设置不当,导致运行错误,以下我列举了可能出现错误的地方。

  • 务必在WhiteImagesPath处写明相机型号,确定好到底是Lytro还是Illum
  • 注意Illum相机的白图像们在相机的SD卡中,那些白图像们拷贝出来放在路径Sample_testCamerasB5151500510下即可
  • 白图像的处理过程比较久,耐心等待就行即可
  • Lytro与Illum的频域滤波调用函数是不同的,我已经把代码添加在了相应位置;这个函数用时较久,耐心等待
  • 结果存放在Results_saving文件夹下
  • 再次提醒,由于Illum图像的分辨率比较大,所以当程序运行到LFLytroDecodeImage以及频域滤波时会造成内存以及磁盘的大量使用,慎重考虑。
  • 如有Bug请及时联系我,请在评论区留言。
「没有相机怎么搞」
  • 下载整个工程(见我的Github: https://github.com/Vincentqyw/light-field-TB);
  • 下载数据集:可以在文末提供的Lytro数据集,该数据集包括白图像以及图像原文件;
  • 然后将工程Sample_test/Cameras/下的文件Axxxxxxxxxxx修改为A303134643,然后将数据集LytroDatasetsn-A303134643文件夹下的data.C.0.1/2/3放在Sample_test/Cameras/A303134643文件夹下;
  • 将LytroDatasetraws文件夹下的图像原文件放在工程Sample_test/Images/B01/文件夹下;
  • 修改Demo.m中的如下命令: WhiteImagesPath = 'Sample_testCamerasAxxxxxxxxxx',以及lfpname='test'改成步骤4中的任何一个图像原文件即可;
  • run起来吧!

「解码效果为何不佳」

另外,很多童鞋问过我一些问题,例如为何光场工具包解码出来的图像质量如此之差,始终达不到Lytro Desktop导出图像的质量。其实该问题是个普遍现象,目前没有一个好的解决方法。光场工具包的发明者Donald Dansereau在Google Plus也是这么认为的,我把原话附在下面:

Q from email: there are differences between the toolbox decoded output and the Lytro Desktop’s image. The differences involve color, intensity and noise. How can I fix this? A: Thanks for the email. There will always be important differences between the Lytro software output and the toolbox output. The toolbox tries to generate a 4D light field that is as close as possible to the raw image measured by the camera, while still being a standard two-plane parameterized 4D light field. The Lytro software has a very different goal. They do not produce a 4D light field, they produce 2D renders. These are optimized to look nice, and evidently look much nicer than any 2D slice taken from the toolbox output. They use sophisticated decoding and denoising techniques to do this. The philosophy of the toolbox is to provide a 4D light field close to the raw image captured by the camera, to allow researchers to explore the characteristics of this kind of signal. It should, in theory, be possible to go from the 4D light field output by the toolbox to nice 2D renderings like those produced by the Lytro software. Making nice 2D renderings can also be accomplished by working directly from the lenslet image, as has been demonstrated in a few papers by researchers at Lytro and elsewhere.

从他的回复可以看到,他公布的光场工具包的目的是尽量恢复出光场相机采集的原汁原味的数据(raw data)用来逼近4D光场信息;同时让研究者去研究这些数据,并为他们所用。但是Lytro公司提供Lytro desktop的目的是渲染出漂亮的2D图像,以供用户使用。以上也反映出研究和商业模式区别,Lytro并未提供他们渲染的方式,属内部机密。

此外我也在google plus上单独问了Donald Dansereau同样的问题,我把他的回复建议的原话附在下面:

If you want to make nice 2D images, I suggest Filter before colour correction. Try a simple planar focus filter (LFFiltShiftSum, or one of the linear filters in the LFDemoBasicFilt* examples). Don’t use the toolbox colour correction, the code is extremely simplistic and is mostly meant to show you where the metadata is. Look into some 4D - to - 2D rendering techniques for light fields. Look into some 2D denoising techniques and apply them to your 2D render, or to the 4D light field slices. If you do find something that works well for you please share, as this is a common question.

说了这么多,讲下我的配置。我习惯的参数设置:颜色校正的参数设为Gamma=0.8或者小于0.8,这个参数你可以不停地试。

另外,我一般不使用频域滤波函数,因为我认为这步操作会很大程度地破坏原始数据。我会选用中心视角邻域的几个视角,例如原来ILLUM提供的是15x15个视角,但是我只用其中的11x11或者更少,这样就可以不用考虑边界视角黑暗的问题了。

当然大家可以尝试下按照Donald Dansereau的说法进行尝试,如果大家有好的方法,也可以告诉我。(PS:以上为回复@lixiaohao同学邮件部分内容)

「测试代码」

以下是Demo文件的代码,仅供学习使用。另外测试代码也放在了我的Github。

代码语言:javascript复制
clc;clear all;clc;addpath(genpath('Sample_test'));addpath(genpath('LFToolbox0.4'));LFMatlabPathSetup;%% Step1: 解压data.C.0/1/2/3--->white,结果存储在Cameras中fprintf('===============Step1: Unpack Lytro Files===============nn ');LFUtilUnpackLytroArchive('Sample_test')%% Step2: 包含刚刚解压出来的文件的目录fprintf('===============Step2: Process WhiteImages===============nn');WhiteImagesPath='Sample_testCamerasB5151500510'; % 务必要设置这个值 B5151500510   A303134427LFUtilProcessWhiteImages( WhiteImagesPath);%% Step3: 解码光场图像.lfpfprintf('=====================Step3: Decode LFP===================nn');cd('Sample_test');  % 进入Sample_test目录lfpname='baby'; %测试图像名称,改成你自己的if WhiteImagesPath(21)=='A'    %找到型号  exist('LYTRO','var')version='F01';elseif WhiteImagesPath(21)=='B'%找到型号  exist('ILLUM','var')version='B01';endInputFname=['Images',version,'',lfpname,'.lfp'];[LF, LFMetadata,WhiteImage,CorrectedLensletImage, ...WhiteImageMetadata, LensletGridModel, DecodeOptions]...=  LFLytroDecodeImage(InputFname);cd('..');imshow(CorrectedLensletImage) %Raw Imagemkdir(['Results_saving',lfpname]);imwrite(CorrectedLensletImage,['Results_saving',lfpname,'',lfpname,'.bmp']);save(['Results_saving',lfpname,'',lfpname,'.mat'],'CorrectedLensletImage');%% =======================频域滤波=========================%---Setup for linear filters---tic% lytroif strcmp(version,'F01')==1LFPaddedSize = [16, 16, 400, 400];BW = 0.03;FiltOptions = [];FiltOptions.Rolloff = 'Butter';Slope1 = -3/9; % LorikeetSlope2 = 4/9;  % Buildingfprintf('Building 4D frequency hyperfan... ');[H, FiltOptionsOut] = LFBuild4DFreqHyperfan( LFPaddedSize, Slope1, Slope2, BW, FiltOptions );fprintf('Applying filter');[LFFilt, FiltOptionsOut] = LFFilt4DFFT( LF, H, FiltOptionsOut );% illumelseif strcmp(version,'B01')==1LFSize = size(LF);LFPaddedSize = LFSize;BW = 0.04;FiltOptions = [];%---Demonstrate 4D Hyperfan filter---Slope1 = -4/15; % LorikeetSlope2 = 15/15; % Far backgroundfprintf('Building 4D frequency hyperfan... ');[H, FiltOptionsOut] = LFBuild4DFreqHyperfan( LFPaddedSize, Slope1, Slope2, BW, FiltOptions );fprintf('Applying filter');[LFFilt, FiltOptionsOut] = LFFilt4DFFT( LF, H, FiltOptionsOut );title(sprintf('Frequency hyperfan filter, slopes %.3g, %.3g, BW %.3g', Slope1, Slope2, BW));drawnowsave(['Results_saving',lfpname,'',lfpname,'5D.mat'],'LFFilt');end%% =======================颜色校正参数设置==========================ColMatrix = DecodeOptions.ColourMatrix;Gamma=DecodeOptions.Gamma;ColBalance=DecodeOptions.ColourBalance;% 对3280*3280的原始彩色图像进行颜色校正ColorCorrectedImage=LFColourCorrect(CorrectedLensletImage, ColMatrix, ColBalance, Gamma);imwrite(ColorCorrectedImage,['Results_saving',lfpname,'',lfpname,'ColorCorrectedImage.bmp']);save(['Results_saving',lfpname,'',lfpname,'ColorCorrectedImage.mat'],'ColorCorrectedImage')imshow(ColorCorrectedImage);title('Corrected Lenslet Image');%% 同样是颜色矫正, 为了得到光场数据。得到5-D LFColorCorrectedImage数据LFColorCorrectedImage=zeros(size(LF,1),size(LF,2),size(LF,3),size(LF,4),size(LF,5));for i=1:size(LF,1)for j=1:size(LF,2)temp =squeeze(LFFilt(i,j,:,:,1:3));temp = LFColourCorrect(temp, ColMatrix, ColBalance, Gamma);LFColorCorrectedImage(i,j,:,:,1:3)=temp;imshow(temp);pause(0.1)endendLFColorCorrectedImage(:,:,:,:,4)=LF(:,:,:,:,4);save(['Results_saving',lfpname,'',lfpname,'RawLFColorCorrectedImage.mat'],'LFColorCorrectedImage');% very importanttoc
「文中的几个链接」

  • Light Field Toolbox光场工具包工程:https://github.com/Vincentqyw/light-field-TB
  • Lytro拍摄的光场数据集:https://www.irisa.fr/temics/demos/lightField/index.html

0 人点赞