光场1.0——非聚焦型光场相机

这篇具有很好参考价值的文章主要介绍了光场1.0——非聚焦型光场相机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文概要

本文讲主要从光场硬件结构设计以及软件处理方式的层面来介绍一下光场的相关内容,关于光场的优势和具体应用点并不在本文的主要范围内。

光场1.0

1. 结构原理说明

首先来介绍一下光场相机,那么什么是光场相机呢,光场相机经历了两代的发展,首先我们来介绍一下一代光场相机的主要结构及内容,以下简称“光场1.0”。接下来,让我们回到2005年2月,重温以下光场相机刚被发明出来的那篇论文——Light Field Photography with a Hand-held Plenoptic Camera ,该论文第一次提出了光场相机的概念,该论文提到的相机概念示意图如下图所示:

光场相机,matlab,开发语言

 该相机由三部分组成:主镜头、微透镜阵列和对应的CCD(即上图中的Photosensor)。其中MLA(microlens array)放置在主透镜的成像面上(注意是成像面,不是焦平面,这也是很多初学者经常混淆的一个概念),CCD放置在对应的MLA的焦平面上。相机的这种布置有哪些优点呢?它又是如何做到可以记录光线的方向信息的呢?为了便于说明,我在图上添加了一些标记便于后续说明:1,2,3表示三条从物面发出的光线;4表示如果把ccd挪到mla的位置三条光线相交的像素点,5,6,7表示ccd在当前位置上面的三个像素点。

光场相机,matlab,开发语言

我们从上图可以看出:物面的Subject在Main lens的后面呈的是一个实像,假如我们把CCD放在对应的MLA的位置,那么上图中的subject发出的三条光线是不是就交互在了对应的ccd的一个像素4上,这样子通过这个像素4就无法分辨到底是三条光线的哪一条了,也就是一句常说的:传统相机成像是积分成像,可以说是三条光线的信息积分相加最终才是该点的像素的采集到的信息。

如果是把ccd后移到焦距位置,那么会有什么样的效果呢,5,6,7三个像素点分别代表交互在实像面位置的三条光线1,2,3的信息,这样子是不是就还原出了交互在4点的不同方向的光线信息,这就是一种在二维平面捕获光线的三维信息的方法。

但是难道不会出现8那个位置的光线也打到4对应的子透镜后面的像素区域造成混乱么,当然会啦,但是如果控制好对应的数值孔径匹配就行,该论文也提到了这一点内容如下图所示:

光场相机,matlab,开发语言

 主透镜有对应的通光口径,只要保证主透镜的通光孔径正确就可以实现上图的数值孔径匹配的效果,即每个宏像素(指的是上图的每一个小圆形的大的像素块)之间既不重叠,又刚好相切。数值孔径匹配的规则为:

其中:D为主透镜的通光孔径(再直白点叫主透镜的直径),L表示主透镜和MLA的距离(又叫做像距,因为MLA放在主透镜的像面位置。!!!此处千万注意,L不一定是焦距,很多人经常犯得一个错误!!!),d为mla的小透镜的直径,f为小透镜的焦距。

2. 算法处理

接下来我将给大家介绍一下一些图像预处理和五维光场函数处理相关的内容。我们先来找一个光场相机捕获的原始图像吧,这里我们可以访问斯坦福大学的光场相机拍摄的数据集,数据集链接:斯坦福光场数据集主页链接

Step1:

光场相机,matlab,开发语言

 Step2:

光场相机,matlab,开发语言

Step3:

光场相机,matlab,开发语言

 单击可以下载对应的Raw Data,文件比较大,打开后可以看到利用上述的结构拍摄到的原始光场图像(下左),放大后可以看到每一个对应的宏像素(下右)。

光场相机,matlab,开发语言光场相机,matlab,开发语言

 接下来我将告诉大家如何处理这个原始光场图像,提取出对应的五维光场函数。首先我们要确定一下对应的图像参数:7574*5264的图像。接下来先放代码,然后具体讲解代码的含义(个人水平有限,代码仅供参考),此处仅提供部分核心代码。

main.py

def test_StanfordLF():
    '''
    加载并处理斯坦福大学的光场数据集
    '''
    lytroRawImagePath = 'flowers_plants_14_eslf.png'
    if os.path.exists(lytroRawImagePath) is False:
        print('start to download light field png...')
        toolsImageProcess.request_download('http://lightfields.stanford.edu/images/flowers_plants/raw/flowers_plants_1_eslf.png',
                               '', lytroRawImagePath)
        print('png download successfully. ')
    print('start to load Stanford Lytro Light Field Archive image {}'.format(lytroRawImagePath))
    t = time.time()       # load time about 20s
    LF = toolsImageProcess.LFReadRawImage(lytroRawImagePath)
    print("Stanford Lytro Light Field Archive image load successfully, time cost: {}s".format(time.time() - t))
    toolsImageProcess.LFSaveAllSubViewImages(LF, "SubView Images", "")

toolsImageProcess.py

'''
根据对应的子孔径图像重构光场原始图片
参数:
    LF 五维光场函数
返回值:
    LF_Raw 原始的光场采集图像
'''
def LFReadRawImage(imgPath, width=None, height=None):
    if os.path.exists(imgPath) is False:
        return None
    LF_Raw = np.array(Image.open(imgPath))
    imgShape = LF_Raw.shape
    if width is None or height is None:
        maxCD = maxCommonDivisor(imgShape[0], imgShape[1])
        uRange = int(imgShape[0] / maxCD)
        vRange = int(imgShape[1] / maxCD)
    else:
        maxCD = imgShape[0]/width
        if maxCD == imgShape[1]/height:
            uRange = width
            vRange = height
            maxCD = int(maxCD)
        else:
            print("data check faild, process finished. ")
            return None

    LF = np.zeros((maxCD, maxCD, uRange, vRange, imgShape[2]))
    print("light field data dimension: LF({},{},{},{},{})".format(maxCD, maxCD, uRange, vRange,imgShape[2]))
    totalSubViewCount = maxCD*maxCD
    start = time.time()  # 下载开始时间
    for x in range(maxCD):
        for y in range(maxCD):
            print('\rloading process: {:.2f}%'.format((x * maxCD + y)*100/totalSubViewCount), end=' ')
            for u in range(uRange):
                for v in range(vRange):
                    LF[x, y, u, v, :] = LF_Raw[u*maxCD+x, v*maxCD+y, :]

    print('\rloading process: 100.00%')
    print('the 4D light field load successfully, time cost: %.2fs' % (time.time() - start))  #输出下载用时时间
    return LF.astype(np.uint8)
def LFSaveAllSubViewImages(LF, dir, dir_name):
    # 首先判断 LF 数据类型,如果是 float 类型需要预处理
    LFShape = LF.shape
    totalSubViewCount = LFShape[0]*LFShape[1]
    path_save = os.path.join(dir, dir_name)
    if dir != "" and os.path.exists(dir) is False:
        os.mkdir(dir)
    if os.path.exists(path_save) is False:
        os.mkdir(path_save)
    for i in range(LFShape[0]):
        for j in range(LFShape[1]):
            img = LF[i, j, :, :, :]
            # plt.subplot(LFShape[2], LFShape[3], i*LFShape[2]+j+1)
            # plt.imshow(img)
            cv2.imwrite(os.path.join(path_save, "{}_{:0>2d}_{:0>2d}.png".format(dir_name, i, j)), img)
            print('\rprocess progress: {}/{} image'.format(i*LFShape[1]+j+1, totalSubViewCount), end=' ')

    print('\nall sub view images has been saved to {} successfully. '.format(path_save))
'''
参数:
    url: 下载的链接
    path: 下载的文件存放路径
    filename: 下载的文件名
    # 可以可视化的动态显示下载进度,便于使用
'''
def request_download(url, path, filename):
    if path!='' and (not os.path.exists(path)):  # 看是否有该文件夹,没有则创建文件夹
        os.mkdir(path)
    start = time.time() #下载开始时间
    response = requests.get(url, stream=True) #stream=True必须写上
    size = 0    #初始化已下载大小
    chunk_size = 1024  # 每次下载的数据大小
    content_size = int(response.headers['content-length'])  # 下载文件总大小
    try:
        if response.status_code == 200:   #判断是否响应成功
            print('Start download,[File size]:{size:.2f} MB'.format(size = content_size / chunk_size /1024))   #开始下载,显示下载文件大小
            filepath = os.path.join(path, filename)
            with open(filepath, 'wb') as file:   #显示进度条
                for data in response.iter_content(chunk_size = chunk_size):
                    file.write(data)
                    size +=len(data)
                    print('\r'+'[下载进度]:%s%.2f%%' % ('>'*int(size*50/ content_size), float(size / content_size * 100)) ,end=' ')
        end = time.time()   #下载结束时间
        print('\nDownload completed!,times: %.2f秒' % (end - start))  #输出下载用时时间
    except:
        print('download error! ')

部分代码的逻辑说明:

LFReadRawImage:

由于所有宏像素的长宽是相等的(圆形和方形的光阑必相等,其他形状目前没见过,不太可能),所以首先是如果不清楚图像解码的光场的LF(x,y,u,v)参数会首先计算图像长宽的最大公约数,以最大公约数作为对应的u和v的值,上述斯坦福大学的光场数据格式为LF(14,14,376,541,4)。

正常的运行结果(控制台输出):

start to download light field png...
Start download,[File size]:178.75 MB
[下载进度]:>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>100.00% 
Download completed!,times: 60.19秒
png download successfully. 
start to load Stanford Lytro Light Field Archive image flowers_plants_14_eslf.png
light field data dimension: LF(14,14,376,541,4)
loading process: 100.00%
the 4D light field load successfully, time cost: 32.53s
Stanford Lytro Light Field Archive image load successfully, time cost: 35.881481885910034s
process progress: 196/196 image 
all sub view images has been saved to SubView Images\ successfully. 

结果输出的多视角图像效果(采用gif录制了一下不同图像之间连续变化的效果): 

光场相机,matlab,开发语言

现在已经拿到了五维光场函数,后续的许多操作例如EPI和重聚焦等操作就可以通过对LF操作来实现,本文讨论重心不在光场1.0,因此此内容此处不做过多赘述。文章来源地址https://www.toymoban.com/news/detail-767697.html

到了这里,关于光场1.0——非聚焦型光场相机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 海康威视相机SDK二次开发(JAVA语言)

    前言 有个项目需要使用java程序读取海康威视的相机图片。相机通过以太网连接服务器,部署在服务器上的java程序将相机拍摄的画面保存在指定路径下。 海康威视提供了sdk开发包,可以在官网中下载,windows和linux系统都有。但是开发包中给出的示例代码,无法满足实际需要,

    2024年04月29日
    浏览(46)
  • 低代码开发ERP:精打细算,聚焦核心投入

    企业数字化转型已经成为现代商业环境中的一项关键任务。如今,企业面临着日益激烈的竞争和不断变化的市场需求。在这样的背景下,数字化转型不仅是企业生存的必然选择,也是取得竞争优势和实现可持续发展的关键因素。 在数字化转型的过程中,企业资源规划(ERP)系

    2024年02月12日
    浏览(35)
  • 微信小程序开发(学习记录1.0)

    首先,把遇到的问题贴出来,主要是这个解决问题的思路,供大家参考。 现在的问题是将下面的导航栏做出来,但是在自己做的时候 遇到的问题 在app.json文件中输入tarBar,就会生成模板代码,默认会生成一个list的模板代码,几个list就是下面的导航栏有几部分,我们想要分成

    2024年02月09日
    浏览(38)
  • 聚焦云计算、大数据、人工智能等开源技术,这场开源开发者的盛会不容错过!...

    COSCon\\\'22 开源社/KAIYUANSHE    作为业界具有广泛影响力的开源年度盛会,2022 第七届中国开源年会 (COSCon\\\'22) 将于 10 月 29 日 - 30 日 在线上(元宇宙+传统线上直播渠道) 线下(10+ 线下分会场)同步拉开帷幕。 大会共设有 1 个主论坛和 16 个分论坛 ,包含人工智能、云计算、大数

    2024年02月02日
    浏览(48)
  • 自然语言处理 Paddle NLP - 快递单信息抽取 (ERNIE 1.0)

    基础 自然语言处理(NLP) 自然语言处理PaddleNLP-词向量应用展示 自然语言处理(NLP)-前预训练时代的自监督学习 自然语言处理PaddleNLP-预训练语言模型及应用 自然语言处理PaddleNLP-文本语义相似度计算(ERNIE-Gram) 自然语言处理PaddleNLP-词法分析技术及其应用 自然语言处理Pa

    2024年02月09日
    浏览(80)
  • 使用C语言实现通讯录管理系统1.0版本(持续更新)

    本篇文章会教大家用C语言实现一个通讯录系统,此程序将会持续更新优化。觉得博主写的不错的朋友可以关注点赞收藏一波,支持一下博主,感谢大家! 此通讯录系统可以存储1000个联系人的:姓名,性别,年龄,电话号码,家庭地址。 主要实现的系统功能有:添加联系人,

    2024年02月03日
    浏览(53)
  • matlab相机标定求得相机内参

    可以去官网下载标定板,然后使用我们的相机进行拍照(10~15张即可): 下载请点击这里:here 在拍摄照片之前,先量取对应的每个方格的长度: 如下: 打开MATLAB的命令行: 输入 cameraCalibrator #调用标定的工具箱 添加的是刚刚我们拍照标定板的图片。 点击运行按钮 参数导出

    2024年02月09日
    浏览(44)
  • Matlab 相机标定

    详细的原理可以看这篇 计算机视觉-相机标定,写的很赞 Step1.  准备 首先准备打印好的黑白棋盘格图片,并且保证表面的平整,例如35*35的棋盘格,贴在亚克力板上。 Step2.  拍摄 用相机拍摄棋盘格分别在取景框左上角、右上角、左下角、右下角和中间的照片(也可以多拍一

    2024年02月09日
    浏览(40)
  • matlab标定相机内参

    在APP中选择Camera Calibrator,如下: 点击 Add Images,导入拍照图片。标定20张左右就够了,然后角度变一下,但不需要变太大,太大了会影响标定效果。标定板最好在视场中心,且占据较大面积。 修改棋盘格大小为27*27mm(我的A4纸测量是这样) 对于标准相机,菜单栏的option里选

    2024年02月05日
    浏览(47)
  • 【双目相机】基于matlab的参数标定2-使用matlab标定

    使用双目相机拍照并分割图片: 【双目相机】基于matlab的参数标定1-使用双目相机拍照 照片拍摄好后,进入matlab标定工具箱,如下图所示。可以使用matlab2020a版本。 进入工具箱以后,选择Add Images。 选择左右相机照片的路径,Size of checkerboard square为棋盘中每一个方格的长度,

    2024年02月15日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包