手机从拍照到成像,到底经历了什么?
在计算机网络中,有一个经典问题:从浏览器地址栏输入 url 后到出现网页,中间经历了什么?那么,对于计算摄影而言,同样有一个问题:从手机上按下拍照按钮到拍出一张照片,中间经历了什么?这是学习计算摄影首先要了解的问题。也是很多做 low level vision 的同学不怎么关注但其实很重要的问题。
本文就从一个小白的角度来介绍一下这个过程,由于网上的中文资料比较零散,本文主要参考 Michael S. Brown 在 ICCV2019 上的讲座以及 CMU 的计算摄影课程,参考链接在文章末尾获取。
手机成像的基本原理
人眼能看到周围的世界,是因为有光子打在我们的视网膜上,并刺激视网膜上的神经细胞发射电信号和化学信号到大脑,从而使大脑的神经元受到刺激,产生画面。
手机成像的基本原理也非常类似。
首先,手机的摄像头也存在类似眼球和视网膜的组件。大家在高中的时候都学过,爱因斯坦在 1921 年因为光电效应获得诺贝尔奖。
这些电信号经过一些电子元件的转换之后,最终可以得到数字信号,也就是通常意义上可以存储在内存或者硬盘上的原始图片 (raw image)。为什么叫原始图片呢?因为它是直接通过传感器得到的、没有做任何后处理的数字信号。
这种图片有这些特点:噪声很大、颜色很奇怪、亮度比较低,它们的格式甚至不是我们熟知的 RGB 格式。
很显然,这种图片是没法看的,因此,之后会有一种称为图像信号处理器 (ISP,Image Signal Processor) 的设备来专门做一些图像处理操作。其实,对于人眼来说,进入我们视网膜的光线也是一种很原始的信号,但经过大脑处理后,这种信号就变成多姿多彩的图像。因此,我们也可以说,ISP 是相机的「大脑」。
ISP 一般集成在手机的芯片中,有些厂商 (比如高通) 可能会把 ISP 和 CPU 做成一块统一的芯片,毕竟对于现代手机来说,拍照和其他运算功能都是不可或缺的一部分了。对于专业相机、监控摄像头等具备拍摄功能的设备来说,ISP 也是必须的。
ISP 本质上是一种用于图像处理的芯片,因此说白了,它也是提供一系列图像处理算法,使得原始的 raw 图变成正常的图片。
整个拍照出图的流程可以归纳为下图:
下面,我就重点介绍一下传感器和 ISP 的一些工作原理。
传感器Sensor
严格来说,传感器前面还有镜头,为了控制文章篇幅,我们暂时略过这部分,直接从传感器讲起。
前面说了,传感器的基本原理是光电效应,因此,这其中有一个重要的模块,用于接受光子,并激发出电子。但自然界中的光有各种颜色 (频率),每一束光也有强弱亮暗,如何让传感器感知到这些信息,是很关键的一步。
牛顿在十七世纪的时候,通过实验发现光可以被分解为多种颜色,
因此,只要让传感器捕获到每一束光的红、蓝、绿三部分信息,再叠加每一部分的强度 (或者说亮度),线性组合后就可以得到这束光原本的颜色信息了。
在这种设想下,柯达公司的拜耳大师 (Bayer) 发明了可以接收三种色光的传感器
这种过滤不同色光的组件又称为 Color filter arrays (CFA)。
当然,除了这种并排的方式,还可以把它们叠在一起:
目前主要的传感器有 CMOS 和 CCD 两种电路结构,由于 CMOS 性能更好,因此大部分摄像头都采用了 CMOS 结构。
下图是 CMOS 中一种常见 CFA 排列方式
除此之外,还有其他许多不同的排列方式:
而且,随着技术的成熟,有很多设计已经不拘泥于红绿蓝三种颜色了。
在将光信号转换为电信号后,会有专门的电路负责把这些电信号进行放大,并将这些电信号 (又称模拟信号) 进一步转换为数字信号:
最后一点,我们要如何获取这些 raw 图呢?在单反相机中,通常可以得到一种 DNG 格式 (也可能有其他格式) 的数据,这种就是直接通过传感器获得的 raw 图。而在安卓手机上,Google 提供了一套接口 android.hardware.camera2
,可以在不需要 root 手机的情况下,在应用层接口上获取 sensor 输出的结果,具体可以参考:https://developer.android.com/reference/android/hardware/camera2/package-summary
ISP:相机的「大脑」
好了,现在我们通过 sensor 得到一张原始图片数据了,但它非常的辣眼睛,一般人根本看不下去
这种 raw 图一般长这个样子 (左图是 raw 图,右图是正常的 rgb 图):
因此,接下来就需要用相机的大脑,ISP,来把这些原始图片进一步处理成人眼可以观看的图片信息。
我在前面已经放了一张 ISP 大致的处理流程图:
坏点校正 (BPC, bad point correction)
Sensor 作为一种物理器件,难免存在一些坏点 (在全黑的环境下会输出一些亮点),而随着器件老化,这种坏点只会越来越多。因此,ISP 中有一步 BPC 会专门检测出这种坏点,并用类似中值滤波的方式来「消灭」这种坏点。
黑点平校正 (BLC, black level correction)
在 ISP 中有两个很常见的名词:黑电平、白电平。
所谓黑点平,指的是全黑 (外界没有光子进入相机) 的情况下的电流值。因为传感器本身也是一种电器,难免存在自由电子逸出的情况 (也就是漏电),因此我们会做一下校正,测出镜头在全黑情况下的数字信号大小,并将这个信号值标记为黑电平。常见做法是将黑电平标记为 64,意味着像素值 64 以下的数值都是黑色的。
与之对应的白电平则是 ISP 能处理的最大亮度,可以认为是纯白色。如果用 10 比特存储图片数据,则白电平的数值为 1023 ()。
镜头阴影校正 (LSC, lens shading correction)
由于光在进入镜头后,会从中心向四周扩散,因此我们实际得到的 raw 图可能长左图这个样子 (右图是校正过的):
LSC 就是希望让亮度均匀些,使中心不会过亮、四个角不会过暗。
白平衡 (WB, white balance)
提问:对于同一张白纸,在不同颜色的光照下,分别是什么颜色的?
但 sensor 只会忠实地记录真实的情况,因此你会看到,相机拍出来的图在橘光下偏橙,在白炽灯下偏青。而白平衡要做的,就是让不同色温光线下拍出来的白色物体都接近白色。
白平衡可以手工完成,也可以用算法自动白平衡 (AWB)。这里介绍一种 AWB 算法的典型算法案例:灰度世界算法 (Gary World algorithm)。
灰度世界算法基于一个简单的观察:我们拍的大部分场景的图片中,对所有像素值取均值,结果应该是灰色的 (这是有人通过实验发现的)。灰色是介于黑色和白色之间的颜色,这意味着,R、G、B 三个通道的能量是大致相等的:R = G = B。
因此,我们可以先求出全图中每个通道的均值:
最终得到的图片就更接近肉眼的感知:
白平衡目前仍然是研究热点之一。对于同样的场景,不同手机拍出来的色温也不尽相同,这里面主要就是不同产商的白平衡算法导致的差异。一般而言,越接近人眼的感知,白平衡算法越好。
去马赛克 (Demosaic)
前面说了,相机传感器得到的图片是一张 Bayer 格式的图片,要想得到正常的 RGB 图片,我们还要做一步去马赛克 (demosaic) 操作。
一种最简单朴素的做法就是根据周围的像素值进行插值。
除此之外,还有其他更加复杂但效果更好的算法,可以提高清晰度,同时降低噪声等,这里不再展开介绍。
去噪 (Denoise)
去噪可能是大家最熟悉的步骤 (不管之前是否了解整个成像流程)。
ISP 中的去噪算法可能会在 Bayer 图上进行,也可能做完 demosaic 后在 RGB 图上进行,但去噪原理没有本质不同。去噪算法的本质都是根据周围的像素值,对当前像素的数值进行修正:
针对不同的噪声类型 (形态),滤波器的选择至关重要。而不管是传统的去噪算法,还是用神经网络的去噪算法,本质上都是在找一个更合适的滤波器而已。不过,神经网络模型由于包含海量滤波器,而且可以通过大量数据总结出经验,因此现在效果较好的去噪普遍都是基于神经网络的方案。
在神经网络学习去噪的过程中,噪声形态的影响非常大,不同传感器表现出来的噪声形态差异巨大,因此,如果可以估计出正确的噪声模型,我们就可以仿真出更加真实的噪声数据用于训练模型,这对模型效果的影响至关重要。这一点我们在之后的文章中再细讲。
通常来说,将 ISP 的去噪模块中直接使用神经网络进行去噪,比做完整个 ISP 流程再去噪效果更好,因为 ISP 中有些步骤会破坏噪声模型,而这种破坏是很难模拟的。
颜色变换 (Color Transforms)
前面提到的白平衡算法主要是对白色进行校准,而这一步则是对除白色以外的其他颜色进行校正。
人眼能看到不同颜色的光,是因为不同色光的光谱各不相同。科学家通过实验发现,人眼所接收的光谱大概是这个样子的:
然而,传感器由于本身工艺上的差异,不可能百分之百和人眼一致。比如下面这张图,左边显示了尼康、索尼等不同产商的传感器接收到的光谱图差异:
校准方面很简单的做法是,用已有的相机拍标准色卡:
求出这里面的 和 后,对相机的颜色做一个线性变换,就大致校准到标准颜色空间了。
大部分情况下,我们会省略 ,直接用 来拟合数据,求解出来的矩阵 是一个 的矩阵,通常把这个矩阵叫作颜色校准矩阵 (CCM,Color Correction Matrix)。
颜色是一个相当复杂的课题,可以专门开一个 topic 长篇大论讲下去,限于笔者学识有限,一些很重要的点暂时无法深入介绍。
色调映射 (Tone mapping)
人眼的视觉系统是一种很神奇的构造。在光线较差的暗环境中,人眼会自动调节对比度,从而对暗区的细节更加敏感 (这是进化中形成的能力,可以帮助人类躲避危险)。
但传感器可没这么智能,它只会忠实记录环境的亮度。下图里面,左边就是传感器实拍的环境光亮度,右边是人眼感知的亮度:
tone mapping 要做的事情,就是让图片的亮度或者色调尽可能接近人眼,把暗区的亮度提上来,增加对比度,同时压低亮区的亮度,防止过曝。
tone mapping 的基本做法是用不同的函数曲线,对原图的像素值重新做映射 (和 gamma correction 很类似):
一般来说,会根据映射曲线计算一个查找表格,我们可以直接从这个表格中找出原像素值对应的映射后的像素值。如果是针对 RGB 三种颜色的映射曲线,那么查找表格就是 3D 的,否则一把是 1D 的。
在这一思路指导下,tone mapping 通常有两种实现方法:global tone mapping 和 local tone mapping。
global tone mapping 的思路就是全图采用统一的映射曲线:
而 local tone mapping 则是不同区域采用不同的映射曲线,比如,在下图所示的算法中,我们会根据边缘和色彩信息来决定哪些区域需要提高对比度,哪些区域应该保持原始亮度 (结构信息):
Tone mapping 算法也是研究热点,目前还没有哪种 tone mapping 算法可以 hold 住所有情况,针对特定的场景,一般都还需要选择或者设计针对性的 tone mapping 算法。
图像压缩
图像压缩想必学过图像处理的同学都不会陌生了。由于图片数据量比较大,为了减小存储空间,通常会把图片数据进行压缩,丢弃那些肉眼无法识别的信息,再用一些编码技术来提高信息利用率。最常用的编码格式当然就是 JPG 格式了。
除了以上提到的步骤外,还有其他模块,比如 HDR、自动曝光控制 (AEC)、锐化、gamma 校正等,也是 ISP 中比较重要的模块,对最终成像效果有比较大的影响。限于篇幅这里不展开介绍了,我们以后有机会再讲。
总结
这篇文章简单介绍了手机成像的整个流程。总的来说,硬件和软件的协同,共同影响着成像质量的好坏。但目前来看,硬件 (传感器) 仍然决定着图像质量的上限。
大家也看到了,整个成像的流程非常复杂,但我们在用手机拍照的瞬间几乎是无感秒拍出图,这主要得益于 ISP 芯片的加持,这种芯片经过这么多年的发展,技术已经相当成熟,很多算法直接固化 (汇编代码编写) 在芯片里面,因此速度非常快。
但这并不意味着这里面每个算法都很成熟了,大家如果在晚上拍照,不管使用哪种高端手机,都会发现要么噪声很大,要么色彩失真,总之在你眼中如诗如画的景象,到了手机上就是渣画质了。
近些年随着深度学习的优化,计算摄影有了一些新的突破,很多以前实现不了的功能,现在几乎是标配了 (比如背景虚化这个功能,随着人像分割愈发成熟,效果有了质的飞跃),有些效果在画质上也正在逐渐逼近单反的效果,而后者可是通过昂贵的硬件实现的。
不过,有些同学 (尤其是还在读书的同学) 可能觉得,为啥要了解这么复杂的成像过程呢?直接在最终输出的图片上再跑算法不就好了?
确实,如果是做一些 high level 的任务 (识别、检测、分割等),那完全没必要了解这么复杂的流程,但对于计算摄影这样的 low level 任务 (去噪、超分辨率等) 来说,好的数据源是非常重要的。
就拿某公司非常成熟的超分方案来说,由于 ISP 中某些步骤会破坏细节纹理,因此,只有在 ISP 中集成进超分算法,和 ISP 的功能联调后,才可能做出满足工业界要求的图像或者视频超分辨率产品。另外,对于去噪来说,噪声模型尤其重要,而 ISP 中的去噪模块会破坏噪声形态,因此也必须对整个成像过程有比较深刻地理解才能做好去噪。(这一点我们在之后介绍噪声模型的文章中再细聊)。
这篇文章只是简单介绍了一下整个成像流程,忽略了很多细节,权当是给小白快速入门准备的。我自己也还在学习研究当中,如有错误,欢迎大家指正。
后面也会介绍一些我觉得比较重要的知识,感兴趣的同学欢迎关注一波^0^