LV01-图像-01-bayer格式
本文主要是bayer格式图像的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 | Windows | Windows11 |
Ubuntu | Ubuntu20.04.6的64位版本 | |
VMware® Workstation 17 Pro | 17.0.0 build-20800274 | |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) | |
Win32DiskImager | Win32DiskImager v1.0 | |
Linux开发板环境 | Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) | |
linux内核 | linux-4.15(NXP官方提供) |
点击查看本文参考资料
- 通用
参考资料 | 相关链接 |
相机拍出彩色照片的原理 | 为什么数码相机可以拍出彩色照片? - 阮一峰的网络日志 (ruanyifeng.com) |
点击查看相关文件下载
--- | --- |
这篇文章主要还是参考了阮一峰的《为什么数码相机可以拍出彩色照片?》,主要是写个笔记方便自己查看,推荐看原文。
一、照片的起源
其实并没有找全历史,时间线好像并不明确,大概了解一下吧。
1. 第一张照片?
1825年,法国人涅普斯(Joseph Nicéphore Nièpce),用感光的方式复制了一个17世纪的荷兰版画——牵马人,这是最早的可保存感光影像。
他原本对做石版画非常感兴趣,但是因为在石板上雕刻画面实在是太累了,他就想试试看能不能找到让光帮他自动画画的方法。结果发现了沥青在感光之后会硬化,然后把涂抹了沥青的载体放入溶液中之后,溶解掉因为感光硬化以外的部分,图像就显现出来了。
实验出了这个结果,他就想赶快把这个沥青的锡板做出来放在暗箱内拍一张试试,结果因为失误放在自家窗前曝光了 8 个小时,就这样,一张可保存的照片,就阴差阳错的诞生了,名叫《窗外的风景》,这幅作品被很多文献认作人类最早的的照片。从 1826 年保存至今,现在原版被被保存在美国德克萨斯大学奥斯汀分校。
2. 黑白照片?
那黑白照片呢?好像没有找到完整的发展历史,但是查阅资料,有资料说黑白照片是使用氯化银(silver chloride)作为感光剂。当光线照射氯化银,后者会分解成纯银和氯气,银金属颗粒呈现黑色。因此,底片颜色越深代表光线越强,颜色越浅代表光线越弱,黑白照片就是这样拍出来。
3. 胶片?
胶片(Film)是一种用于记录图像的成像介质,也是一种摄影耗材。胶片又称菲林(英文音译),包装好的在盒中的胶片又称为胶卷。常见的胶片通常由一侧涂覆含微小光敏卤化银晶体的明胶乳剂的条状或片状透明薄膜片基构成。卤化银晶体的大小和其他特性决定了胶片的感光度、对比度和分辨率[1]。
当暴露在光线下时,胶片所含有卤化银中的银离子会逐渐还原为金属银,乳剂因而逐渐变黑。不过若没有外界条件的干预,过程将极其缓慢且不完整,因而该方法没得到实际应用。取而代之的是对镜头成像的极短时间曝光,可以产生与每个晶体所吸收的光量成比例的极轻微化学变化,并在乳剂中产生不可见的潜像,化学显影之后即可成为可见的图像[2]。
黑白胶片通常只含有一层感光层。曝光后的卤化银晶体显影时,银离子被还原为金属银,阻挡光线而表现为负片胶片中的黑色部分。彩色胶片至少含有三层感光层,并结合了不同组合的增感染料。通常,蓝光感光层位于最上方,随后是黄色滤光层,以阻止任何剩余蓝光影响随后的感光层,其下分别是绿光-蓝光感光层和红光-蓝光感光层,分别记录绿色和蓝色图像。在显影过程中,就像黑白胶片一样,银离子被还原为金属银。但显影过程中的副产品同时也与胶片或显影液中的彩色耦合剂结合,形成彩色染料。由于显影副产品的产生量与曝光和显影的量成正比,因此形成的彩色染料也与曝光和显影的量成正比。显影后,金属银经过漂白步骤重新转化为卤化银,并在定影步骤中给除去。定影步骤后,胶片上只留下形成的彩色染料,组合在一起即构成可见的彩色图像。
4. 彩色照片产生
19世纪中期,人们发现,人眼的圆锥细胞对三种颜色:红、绿、蓝特别敏感。伟大的英国物理学家麦克斯韦因此假设,红绿蓝作为基色,可以拍出彩色照片。
1861年,在麦克斯韦的指导下,人类的第一张彩色照片诞生了。采用的方法是在镜头前,分别用红丝带、绿丝带、蓝丝带过滤光线,曝光形成三张底片,然后用三部放映机向同一处投影这三张底片,每部放映机的镜头前都拧上对应颜色的镜头,它们的合成效果就是一张彩照。
而真正意义上的彩色胶卷,1933年诞生于柯达公司,底片之上依次有三个感光层,分别对红、绿、蓝三种颜色进行曝光,最后叠加形成一张彩色底片。
5. 图像传感器的诞生
二战后,计算机诞生,科学家发现图像可以用数字形式表示。如果将光信号转变成电信号,就可以直接拍出数码照片。这意味着,照相机不再需要胶卷,而是需要一个图像传感器(image sensor)。
图像传感器将光线转化成电流,光线越亮,电流的数值就越大;光线越暗,电流的数值就越小。所以,如果用0到255的范围,表示光线的亮度,最亮的光线是白光,数值是十六进制的FF,最暗的光线是黑光(没有光),数值是十六进制的00。
图像传感器的表面,分成若干个捕捉点,每个点都会产生一个数值,表示该点感受到的光线亮度,这就叫做”像素”。像素越多,图像细节就越丰富。如果一台相机的像素是1600x1200,就说明图像传感器横向有1600个捕捉点,纵向有1200个,合计192万个。
6. 缺陷与解决方案
但是,图像传感器有一个很严重的缺陷:它只能感受光的强弱,无法感受光的波长。由于光的颜色由波长决定,所以图像传播器无法记录颜色,也就是说,它只能拍黑白照片,这肯定是不能接受的。
一种解决方案是照相机内置三个图像传感器,分别记录红、绿、蓝三种颜色,然后再将这三个值合并。这种方法能产生最准确的颜色信息,如果要采集RGB三个基本色,则需要三块滤镜,这样价格昂贵,且不好制造,因为三块滤镜都必须保证每一个像素点都对齐,所以这种方案就无法投入实用。
7. 滤光层的出现
1974年,柯达公司的工程师布赖斯·拜尔提出了一个全新方案,只用一块图像传感器,就解决了颜色的识别。他的做法是在图像传感器前面,设置一个滤光层(Color filter array),上面布满了滤光点,与下层的像素一一对应。也就是说,如果传感器是1600x1200像素,那么它的上层就有1600x1200个滤光点。
每个滤光点只能通过红、绿、蓝之中的一种颜色,这意味着在它下层的像素点只可能有四种颜色:红、绿、蓝、黑(表示没有任何光通过)。
不同颜色的滤光点的排列是有规律的:每个绿点的四周,分布着2个红点、2个蓝点、4个绿点。这意味着,整体上,绿点的数量是其他两种颜色点的两倍。这是因为研究显示人眼对绿色最敏感,所以滤光层的绿点最多。
接下来的问题就是,如果一个像素只可能有四种颜色,那么怎么能拍出彩色照片呢?这就是布赖斯·拜尔聪明的地方,前面说了,每个滤光点周围有规律地分布其他颜色的滤光点,那么就有可能结合它们的值,判断出光线本来的颜色。以黄光为例,它由红光和绿光混合而成,那么通过滤光层以后,红点和绿点下面的像素都会有值,但是蓝点下面的像素没有值,因此看一个像素周围的颜色分布,有红色和绿色,但是没有蓝色,这样就可以推测出来这个像素点的本来颜色应该是黄色。
这种计算颜色的方法,就叫做“去马赛克”(demosaicing)。一般采用插值的方法进行色彩还原,经典的算法有:2x2邻域复制插值法、3x3邻域双线性插值法和5x5邻域高质量插值法。上图的下半部分是图像传感器生成的”马赛克”图像,所有的像素只有红、绿、蓝、黑四种颜色;上半部分是”去马赛克”后的效果,这是用算法处理的结果。
8. 广泛应用
虽然,每个像素的颜色都是算出来的,并不是真正的值,但是由于计算的结果相当准确,因此这种做法得到广泛应用。目前,绝大部分的数码相机都采用它,来生成彩色数码照片。高级的数码相机,还提供未经算法处理的原始马赛克图像,这就是raw格式(raw image format)。为了纪念发明者布赖斯·拜尔,它被称作”拜尔模式”或“拜尔滤光法” (Bayer filter)。
二、bayer格式
1. 格式简介
经过上边的了解,再来看一看Bayer格式是什么,图片源自拜耳阵列,拜耳阵列是CCD或CMOS传感器拍摄彩色图像的主要技术之一。拜耳阵列是由伊士曼·柯达公司科学家Bryce Bayer发明的,被广泛运用数字图像。
Bayer格式是相机内部的原始图片, 一般后缀名为.raw,有时候也会称这种格式为RAW 格式的,RAW全称是 RAW Image Format,在编程中称之为原始。 RAW文件几乎是未经过处理而直接从CCD或CMOS上得到的信息。我们相机拍照下来存储在存储卡上的.jpeg或者其他格式的图片, 都是从.raw格式转化过来的。 raw格式内部的存储方式有多种,但不管如何, 都是前两行的排列不同,后面都是重复前两行。
RGB三原色是组成彩色图片的基本要素。最简单的采集方法就是通过对应的透镜去采集,红色的滤镜透过红色的波长,绿色的滤镜透过绿色的波长,蓝色的滤镜透过蓝色的波长。但是这样成本很高,且不好制造,因为三块滤镜都必须保证每一个像素点都对齐。
bayer 格式图片在一块滤镜上设置的不同的颜色,通过分析人眼对颜色的感知发现,人眼对绿色比较敏感,所以一般bayer格式的图片绿色格式的像素是是r和g像素的和。也就是类似与现在的ISP的工作原理,通过算法对RGB的原色进行补充,然后得更好的原色图。下图为bayer色彩滤波阵列,由一半的G,1/4的R,1/4的B组成。
2. 图像传感器硬件
图像传感器的结构如下所示,每一个感光像素之间都有金属隔离层,光纤通过显微镜头,在色彩滤波器过滤之后,投射到相应的漏洞式硅的感光元件上。
假设一个sensor的像素是8*8(分辨率为8*8),那么这个sensor就有8*8个感光点。当Image Sensor往外逐行输出数据时,像素的序列为GRGRGR…/BGBGBG…(顺序RGB)。这样阵列Sensor设计,使得RGB传感器减少到了全色传感器的1/3(三原色中绿色占比1/2 蓝色和红色分别为 1/4和1/4,整体就是采集的三原色是原本的1/3。),如下所示。
3. bayer格式算法实现
3.1 四种bayer格式
在Bayer颜色滤波阵列中,RGB三色的感光单元不是平均分布。基于人眼对绿色比较敏感,绿色(G)占50%,红色(R)和蓝色(B)各占25%。根据彩色滤波阵列的排列不同,Bayer彩色图像可分为BGGR、GBRG、GRBG和RGGB四种格式。
从bayer转换成rgb图的算法, RGB图, 即为三色图, 一个像素点就由RGB三种颜色构成的混合色, 而bayer图一个像素就只有一个颜色, 或R或G或B。因为bayer一个像素点只有一种颜色, 需要借助这个像素点周围的颜色对它进行插值(填充)另外的两种颜色, 它本身的颜色就不用插了。
3.2 插值红蓝算法
每一个像素仅仅包括了光谱的一部分,必须通过插值来实现每个像素的RGB值。为了从Bayer格式得到每个像素的RGB格式,我们需要通过插值填补缺失的2个色彩。插值的方法有很多(包括领域、线性、3*3等),速度与质量权衡,最好的是线性插值补偿算法。其中算法如下:
在(1)(2)中,我们知道了G元素,因此需要插值补全出R和B元素。中间像素的R跟B值分别取左右邻域(或上下邻域)的平均值。
$$
\begin{flalign}
(1) :
R(G22)&=\frac{R21+R23}{2} \newline
G(G22)&=G22 \newline
B(G22)&=\frac{B12+B32}{2}
\end{flalign}
$$
$$
\begin{flalign}
(2):R(G22)&=\frac{R12+R32}{2} \
G(G22)&=G22 \
B(G22)&=\frac{B21+B23}{2}
\end{flalign}
$$
在(3)和(4)中,中间本身就不存在G元素(不知道为啥,网上资料都这么写的,后续知道了再来补充),只存在B或者R元素,因此只需要插值补全R或者B元素。中间像素的B或R值取对角邻域的平均值。
$$
\begin{flalign}
(3) :
R(R22)&=R22 \newline
B(R22)&=\frac{B11+B13+B31+B33}{4}
\end{flalign}
$$
$$
\begin{flalign}
(4) :
R(B22)&=\frac{R11+R13+R31+R33}{4} \newline
B(B22)&=B22
\end{flalign}
$$
3.3 插值绿算法实现
由于人眼对绿光反应最敏感,对紫光和红光则反应较弱,因此为了达到更好的画质,需要对G特殊处理。在上述(3)与(4)中,扩展开来就是上图的(5)与(6)中间像素G的取值,者也有一定的算法要求,不同的算法效果上会有差异。经过相关的研究,(5)和(6)其实就是之前的(3)和(4)中的G分量:
$$
(3):G(R22)=
\begin{cases}
\frac{G12+G32}{2} & |R1-R3|<|R2-R4| \newline
\frac{G32+G21}{2} & |R1-R3|>|R2-R4| \newline
\frac{G12+G21+G23+G32}{4} & |R1-R3|=|R2-R4|
\end{cases}
$$
$$
(4):G(B22)=
\begin{cases}
\frac{G12+G32}{2} & |B1-B3|<|B2-B4| \newline
\frac{G32+G21}{2} & |B1-B3|>|B2-B4| \newline
\frac{G12+G21+G23+G32}{4} & |B1-B3|=|B2-B4|
\end{cases}
$$
CMOS摄像头这部分转换是在内部用ADC或者ISP完成的,生产商为了降低成本必然会使得图像失真。当然用外部处理器来实现转换,如果处理器的速度足够快,能够胜任像素的操作,用上面的算法来进行转换,皆大欢喜。不过上述算法将直接成倍提高了算法的复杂度,速度上将会有所限制。因此为了速度的提成,可以直接通过来4领域G取均值来中间像素的G值,将会降低一倍的速率,而在性能上差之甚微,算法如下:
$$
(3):G(R22)=\frac{G12+G21+G23+G32}{4}
$$
$$
(4):G(B22)=\frac{G12+G21+G23+G32}{4}
$$
如果能够通过损失图像的质量,来达到更快的速度,还可以取G1、G2的均值来实现,但是这样的做法会导致边沿以及跳变部分的失真。
4. RAW的存储格式
raw图目前遇到的有2种存储格式,一种是经过压缩的MIPI raw,另一种是未经过压缩的unpacked raw,通常采集的raw图是10bit的,需要用2个字节来存储,两个字节有16个bit位,这样就有6个bit位为空。
- MIPI raw
MIPI raw就充分利用了这6个bit位,每5个字节存储4个像素值,如图下图所示:
每格代表两个bit位,前4个红色的格子存储的是第一个像素的高8位,接着4个黄色的格子存储的是第二个像素的高8位,接着4个绿色的格子存储的是第三个像素的高8位,接着4个蓝色的格子存储的第四个像素的高8位,接着1个蓝色的格子存储的是第4个像素的低2位,接着一个绿色的格子存储的是第3个像素的低2位,接着一个个黄色的格子存储的是第2个像素的低2位,最后一个红色的格子存储的是第1个像素的低2位。
- unpacked raw
unpacked raw的存储格式如下图所示,每个格子代表1个bit,绿色格子代表低10位被占用,白色格子表示高6位为空。
5. RAW格式的位数
常见的RAW格式位数有8、10、12位等:
- RAW8
用8bit表示G/R/G/B中的一个分量。
- RAW10
用10bit表示G/R/G/B中的一个分量,但是数据中是16bit,高6位没用,对应上面的unpacked raw的存储方式。
- RAW12
用12bit表示G/R/G/B中的一个分量,但是数据中是16bit,高4位没用。
这里要注意的是, bayer每个像素的值是8位的。但是有的相机的bayer格式却有10位, 12位以及14位, 16位的, 那么则需要将高于8位的数据转换为8位数据。 拿12位数据来说, 有的是取高8位或是低8位, 那么这样就会出现一个问题, 这张图像会有一个斜度, 不是偏亮就是偏暗, 或是出现其它颜色问题,需要后期进行校正。
三、MIPI简介
有的时候我们会看到MIPI接口,这是啥呢?MIPI(移动行业处理器接口)是Mobile Industry Processor Interface的缩写。MIPI是MIPI联盟发起的为移动应用处理器制定的开放标准,目的是把手机内部的接口如摄像头、显示屏接口、射频/基带接口等标准化,从而减少手机设计的复杂程度和增加设计灵活性。其中CSI(Camera Serial Interface)规定摄像头接口。