首页 > 编程语言 >光场原理及一些算法代码实现

光场原理及一些算法代码实现

时间:2023-03-18 21:55:28浏览次数:37  
标签:光场 阵列 相机 传统相机 算法 透镜 图像 代码

2023.3.18

好久没有写过博客了,感觉自己比以前更菜了\(//∇//)\

好不容易的更新,是为了把最近看的几篇光场论文写个自己的整理和理解,后面可能会写一些用C++实现的光场处理算法代码。这篇应该会慢慢不断补充更新的。

一、光场原理

1.光场概念

个人理解的光场其实就是类似像磁场、电场般,是光线的场分布。

为了描述不同的光线,有一个全光函数。一开始是七维的:入射点空间坐标三维,延伸方向由两个角度描述有两维,还有一维描述光线强度,一维描述时刻。忽略强度(忽略光线传播中的消减),也不考虑时刻,就可以把七维的全光函数降到五维,如下图(a)。但五维依旧复杂,因此后来又降到四维。对于光线的空间位置和方向,用两个平行平面与光线的交点来描述。如下图(b),光线分别与两个平面交于(u,v)和(s,t),于是这四个参数就足以构成全光函数L(s,t,u,v)了。

                                                                                 

两组坐标,一个可以用来记录空间信息,另一个可以用来记录角度信息。

2.光场成像

一般的传统相机成像,从上述全光函数的角度来说明,镜头可以看成(u,v)平面,而像面则可以看成(s,t)平面。但传统相机成像原理是把一点发出的所有经过镜头的光线积分后聚焦在像面的一点上,也就是说,(s,t)坐标信息被记录了下来,然而镜头上的代表不同光线的(u,v)信息被积分了。因此,普通相机只能记录下二维空间信息,而丢失了二维角度信息。

       

在这个基础上,光场成像的主要目的就是要同时把四维信息都记录下来。显而易见,光场信息的完全记录,这会带来很多好处,赋予光场相机一些传统相机所没有的功能,在后面会有详细展开。

完整的光场成像分为两个过程,光场的采集和将光场信息处理为图像。

1)光场采集

为达到采集四维光场信息的目的,有很多种方法。在传统相机的基础上,主要问题是如何记录角度信息,因此可以通过多次从不同角度对同一物体的曝光来实现,进一步改进的话,可以用相机阵列,实现一次曝光采集不同角度光线信息。相机阵列,如下图,倒是很容易理解,但是弊端也很明显,装置过于庞大是其中之一。

                    

                     斯坦福大学搭建的相机阵列之一

目前最通用的是基于微透镜阵列的光场采集。

在传统相机的结构上只需要加入微透镜阵列,就可以实现光场四维信息的采集。所谓微透镜阵列,就是由若干个微小的透镜排列形成的一个装置。为实现最大的角度分辨率,一般将微透镜阵列放置在传统相机中像平面所处位置(即主镜头聚焦点)s,t,然后在微透镜阵列一个焦距处放置图像传感器。这样,微透镜阵列平面可以捕捉到(s,t)空间信息,原本在主镜头处丢失的角度信息(u,v)可以在图像传感器处被记录下来。

            

图像传感器上一小格代表一个像素,一个微透镜阵列对应几个像素即为每个微透镜的分辨率。而每个微透镜后面对应的这几个像素一起便组成了一个子图像(也有被称为宏像素),子图像中每单个像素就对应主镜头中的一个子孔径的采样。物体点发出的不同光线通过主镜头相同子孔径的被图像传感器保存在同一个像素中,而由于像素是成像中最小的单位,所以几乎可以认为这些光线是同一条光线。通俗讲,一个点发出的不同角度的光线被保存在了相同子图像的不同像素中,也可以理解为,一个点被放大成了一个子图像,而子图像的的各个部分探测到的这个点发出的不同角度光线。

由此,光场相机中微透镜的个数(即子图像的个数)反映了空间分辨率,而子图像中的像素数(即微透镜的分辨率)反映了角度分辨率。显然,光场相机相较于传统相机来讲,能记录角度信息是以牺牲了空间分辨率为代价的(通俗讲,一个点被放大成一个子图像,肯定变模糊了,也就是空间分辨率降低)。想象微透镜阵列与图像传感器间的距离从一个焦距逐渐减为零的过程中,空间分辨率不断增大,而角度分辨率不断减小直至0,这时就几乎可以等同于一个传统相机了。

每个子图像一起便构成了光场相机的原始白图像。为了使像素利用率最大,而各个子图像间又不串扰,达到一种微透镜图像几乎接触但比并不重叠的理想条件,需要调整主镜头的光圈大小。同时,一个子图像的形状是由主镜头光圈的形状决定的。如下图,MLA是微透镜阵列,pm代表光圈直径。

 图源:Development and Application of Light-Field Cameras in Fluid Measurements—Shengxian Shi,T.H.New Editors

 

上述类型的光场相机被称为非聚焦式光场相机,另外也有聚焦式光场相机,主要区别在于微透镜阵列放置的位置不同,可以在主镜头像平面前面实现提前聚集,或者放置在后面实现二次聚焦。聚焦式光场相机能提升空间分辨率,但相应的,角度分辨率也为降低。

2)光场信息处理

光场相机在采集到光场信息的基础上,通过计算机算法的一系列处理,可以得到一系列传统相机所没有的功能。

  • 视角变换  
  • 重聚焦
  • 扩大景深
  • 深度估计

①视角变换:

上文有提到,每个子图像中的不同像素保存了一个点不同角度的光线信息,很显然,不同子图像中相同位置的像素保存的就是各个点经过主镜头同一子孔径的光线。于是,如果我们把每个子图像中相同位置的像素单独提取出来,重新组成一幅图像,那么我们就能得到不同视角的物体图像。这类图像被称为子孔径图像,个数为子图像的像素数。也就是说,假如一个微透镜对应15*15个像素组成的子图像,那么我们能得到225张子孔径图像,相当于一个15*15的相机阵列拍摄下来的图片。从这个功能来说,光场相机相较于上述相机阵列的改进是巨大的。

具体计算是,遍历每个(s,t),对限定范围内的(u,v)进行积分。这里的限定范围也就是限定子孔径的范围。

②重聚焦:

在传统相机中,聚焦一直是一个难以解决的问题。一般拍照中,很容易出现聚焦点与需求不一致的情况,反复调整焦距也较为麻烦。而光场相机由于保存下了光场信息,经过一次曝光后,无论需要何处聚焦的照片,都能通过计算机处理而得到。

传统相机中,聚焦一般通过改变像面和主镜头的位置来实现。光场成像中,由于已知光场信息,光线的位置和方向都是已知的,所以可以实现将采集到的光场重新投影到新的像平面的操作,从而得到重聚焦的图片。如图,微透镜阵列处于原像面的位置,u,s,l信息都已知,易得到l‘像面上的s’信息。其中,u代表(u,v)角度信息,s代表(s,t)空间信息,l代表距离。

也就是说,将(s,t)空间信息在位置上进行平移后,对(u,v)角度信息进行积分。

③扩大景深

首先要介绍景深的概念。聚焦在某一物体点上时,在这个点前后都能清晰聚焦的距离范围即为景深。扩大景深就能扩大聚焦的范围,甚至将整个画面所有的物体都清晰成像。

既然已经实现对各个位置的重聚焦,那么,只要把聚焦在目标位置的各个图像提取合成便能得到目标景深的图像。

④深度估计

通过后期的计算机光场处理,可以估计物体深度,得到深度图。分别从重聚焦和视角变换两个方面都能实现。

二、校准算法

 引起最终成像偏差的原因主要是两个,一个是镜头畸变引起的偏差,另一个是微透镜阵列误差引起的图像偏差。前者是在传统相机中就不可避免的偏差,而后者是光场相机独有的偏差。为弥补这些偏差,在处理图像时有一些校准算法。

1.镜头畸变

在传统相机中,为了弥补这种偏差,通常有两种手段:缩小镜头光圈和增加镜头元件。

而在光场相机中,由于记录下了光场信息,于是就有可能通过后期的计算机算法处理,来进行补偿校准。算法的核心思想是:将光场中的光线重新调整到理想中希望它聚集的地方。这和上述重聚焦的思想实际上是类似相同的。

2.微透镜阵列误差

在微透镜阵列的加工和安装上,不可避免会产生一些系统误差,可分为微透镜阵列本身的误差和微透镜阵列安装的位置误差两类。

用有误差的微透镜阵列相机和标准相机分别拍出失真图和标准图,对比两图的信息,求解出可将误差点信息转换成理想信息的中间桥梁,即可描述微透镜阵列的误差状态,直接运用于该相机之后拍摄图像的校准补偿。一般从图片结构信息和灰度信息两方面进行补偿校准。

 

 


2023.3.18

以上仅是今天对光场的一些整理,含有大量我自己的通俗理解在里面,很多细节和公式化定义化的东西并没有给出来,包括校准算法的具体步骤也并没有列出来。

后面可能会慢慢地把补充完整,更多内容会放进去。

标签:光场,阵列,相机,传统相机,算法,透镜,图像,代码
From: https://www.cnblogs.com/mgtnb/p/17226485.html

相关文章

  • 分治算法总结(未完结)
    分治思想:将一个问题分解成若干个结构与原问题相同的子问题。(划分子问题+后处理)一、经典问题1.最大子段和思路:计算左边的最大子段和、右边的最大子段和以及跨越......
  • 表格代码
    <html><head><title>表格</title><linkrel="stylesheet"href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"......
  • webpack原理(1):Webpack热更新实现原理代码分析
    热更新,主要就是把前端工程文件变更,即时编译,然后通知到浏览器端,刷新代码。服务单与客户端通信方式有:ajax轮询,EventSource、websockt。客户端刷新一般分为两种:整体页面刷新,......
  • 算法刷题记录
    http://acm.hdu.edu.cn/showproblem.php?pid=1094#include<iostream>#include<vector>intmain(){usingnamespacestd;vector<int>vecrow;......
  • 008爬虫之短短20行代码下载周杰伦所有歌曲
    今天废话不多说直接上代码。下载周杰伦所有歌曲。#下载周杰伦歌曲importrequestsimportreforiinrange(36):url=f"http://search.kuwo.cn/r.s?all=%E5%91......
  • 代码随想录算法训练营Day46 动态规划
    代码随想录算法训练营代码随想录算法训练营Day46动态规划|● 139.单词拆分关于多重背包,你该了解这些!背包问题总结篇!139.单词拆分题目链接:139.单词拆分给定一......
  • vscode怎么开启代码提示
    1.点击设置---在搜索框里搜索“prevent”--将勾上的去掉  ......
  • 算法 -- 分割两个字符串得到回文串
    分割两个字符串得到回文串提示中等114相关企业给你两个字符串a和b,它们长度相同。请你选择一个下标,将两个字符串都在相同的下标分割开。由a可以得到两个字符......
  • webpack原理(1):Webpack热更新实现原理代码分析
    热更新,主要就是把前端工程文件变更,即时编译,然后通知到浏览器端,刷新代码。服务单与客户端通信方式有:ajax轮询,EventSource、websockt。客户端刷新一般分为两种:整体页......
  • 摘抄学习之--前端架构设计优化:构建可扩展的带代码平台
    低代码发展概述什么是低代码?艾瑞咨询在3月2号发布的中国低代码行业生态发展洞察报告上面是这么说的:低代码开发平台是通过为开发者提供可视化的应用开发环境,降低或去除应用......