摄像头工程师说 Camera - 数据格式 RAW、RGB(1)

Camera 数据格式-RAW、RGB

概述:
本文主要讲述与 Camera 输出数据格式相关的基础知识,通过本文,你可以了解关于相机项目中摄像头输出格式的选择与原理。

从摄像头工作的基本原理说起

摄像头是一个包含感光芯片的光学器件。如下所示是一个典型的摄像头元器件的组成。其整体结构类似一个凸透镜成像原理。当相机的快门按下时,光线经过镜头组、滤光片,将收集到的光线照射在 CMOS 感光芯片的的感光矩阵上,感光芯片记录此时的光照情况。
在这里插入图片描述

摄像头组成(图片来自网络wiki)

感光芯片中有一些列感光元器件。每个感光元器件可以简称为一个像素点。它主要的作用是在相机快门按下的那一刻对视野内的光线进行采样,然后对采样的光线进行量化,形成一个量化值。 下图的每一个小方格都是一个感光芯片中的像素点,这些像素点集合在一起就可以对一片区域的光照情况进行采样,进而记录该片视野内的图像,照片就被记录下来了。

在这里插入图片描述

回归本质-图像色彩的几种表示方法

RGB 三原色

物理老师告诉我们。自然界的颜色都可以通过红色、绿色、蓝色,即 Red、Green、Blue 三原色组合得到:

在这里插入图片描述

三原色(图片来自网络wiki)

因此,只要我们采集的光线记录了视野范围内的 R\G\B 值,就可以还原该像素点对应的实际物体的颜色。

如何记录每个像素点的 RGB 值?

RAW RGB 格式诞生

这需要用到上述相机组成中的一个元器件-滤光片。物理老师告诉我们,指定颜色的透镜只能通过与其颜色相同的。比如,红色透镜只能透过红色光:
在这里插入图片描述

(红色透镜只能通过红色光线-图片来自网络wiki)

因此,每个像素点前面都放置了不同颜色的滤光片。即图示的每个像素点只能通过一种颜色,如坐标(0,0)的像素点只能记录红色、坐标(0,1)的像素点只能记录绿色:

在这里插入图片描述
为了恢复坐标(0,0)处实际的颜色,其需要 R\G\B 三个值,但是坐标(0,0)处只有红色滤光片,只能得到此处的红色数据。怎么办?
因此在生成该像素点的颜色值时其需要借用坐标(0,1)的像素点的绿色、借用坐标(1,1)处的蓝色,这样就组合成了R、G、B 三个值(不用担心啦,这种借用是经过考证的,恢复该点的颜色虽然有小小的误差,但完全没问题的)。

这里我们就引出了第一种数据格式的定义-RAW RGB。RAW RGB 是指经过上述滤光片过滤后形成的采样数据,即每个像素点只输出一种颜色对应的值,这种原始的R\G\B 数据称为 RAW RGB 格式。此时每个像素点对应的 RAW RGB 值为:

  • 坐标(0,0): R00(后缀为横纵坐标)
  • 坐标(0,1): G01
  • 坐标(1,1): B11

RAW8 VS RAW10

如果上述 R00 用 8bit 的数值来表示,就是 RAW8。类似的,如果上述 R00 用 10bit 的数值来表示,就是 RAW10.
对于 8bit 数据的取值范围,也有不同的标准。

  • 如果是 0~255,就是 full range 标准。
  • 如果是 16 ~240,就是 limited range 标准。

真彩色-RGB888、BGR888 格式的引入

在这样的原始数据 RAW-RGB 生成后,摄像头可以通过软件或者硬件对其进行组合,还原该像素点的颜色。典型的采样是每个R、G或B 值用 8bit 的数据进行表示。这就引出了 RGB888 格式,即每个像素点的输出其对应的三原色的值(借用其他像素点的颜色喽)此时坐标(0,0)像素点对应的值为:

  • 像素坐标(0,0)处用的 R\G\B 值为: R00+G01+B11
    当然,你可以改变R\G\B 数据的排列顺序,比如: B11+G01+R00,这样就变成了 BGR888 格式的数据。
    一些专业工具可以从图像中提取R、G、B三个分量的值:
    在这里插入图片描述

(从图像中分离R、G、B-图片来自网络wiki)

数据量小点的 RGB 格式-RGB565、RGB555

在 RGB888 格式下,一个像素对应的数据大小是 8bit +8bit + 8bit,其可以形成 2^8*3 种颜色。尽管色彩更加无损,但数据量太大了。
允许一点误差,来减小下数据的大小吧。
每个像素的低 bit 位相比高 bit 位对整体数据的影响较小。比如舍掉 8bit 位的最后两位,对于该 8bit 位整体数据的误差不过是加减 {0,4} 。准寻这种规则,因此有了 RGB565 格式,它的数据相比与 RGB888 作了裁剪,但整体的数据量,从 24bits/pixel 降低到 16bits/pixel。后台在使用这种作了裁剪的数据时可以根据这种约定的裁剪规则,再恢复出 24bits 的 RGB888 值:
在这里插入图片描述

RGB888与 RGB565 对应的 bit 图(图片来自网络wiki)

之所以让绿色相比其他颜色多一个 bit,是因为有的图像主要用来人眼观看,有研究表明人眼对绿色更为敏感,所以让 绿色保留的多一些。 无独有偶,一些应用场景的图片并不是给人眼观看,也许是机器直接对数据进行了处理,抑或拍摄的场景本身绿色的物体就不多,这样可以对数据进行更加均匀的裁剪,比如这种 RGB555 格式,使得三种颜色均占据 5bits,最高位的 bit 缺省:

在这里插入图片描述
不管哪种方式,我们再应用这些RGB数据类型时,都可以根据约定的规则,还原出其对应的 R、G、B 颜色。比如根据 RGB555 的存储方式,提取得到获取R,G,B分量的值。可以使用:

R = color & 0x7C00, (获取高字节的5个bit) 
G = color & 0x03E0, (获取中间5个bit)
B = color & 0x001F, (获取低字节5个bit)

再比如根据 RGB888中的8bit R、G、B 分量转换得到 RGB565:

short int rgb565_pixel; 
rgb565_pixel = ((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3);

用位数表示的 RGB 格式

除了上述的 RGB888、RGB555、RGB565 这种按照颜色对应的 Bit 位来描述的方法外,也有一些国家喜欢用总的位数来表示对应的 RGB 值(世界这么大,大家提一个自己喜欢的格式称呼也OK啦)。

RGB24:

RGB24, 一个像素用24个bit == 3个字节来表示,R, G,B分量分别用8个bit来表示。典型的就是上述 RGB888了。

RGB32

一些处理器在处理数据时需要 32bits 对齐,以快速处理图像数据。因此便有了 RGB32:
在这里插入图片描述

RGB4、RGB16

有的拍摄场景需要识别的颜色本来就不多,其表示颜色的方法,可以通过缺省一些颜色的 bit,来减小数据量。这些类型的方法与上述表示方法的原理类似。具体的表示方法可以咨询摄像头厂商来进一步确认。

当3D效果、或者阴影变得重要-RGBA

一些游戏设计或者图像处理时,会使用到带物体轮廓的颜色格式。典型的就是 ARGB 格式,其中:
在这里插入图片描述

ARGB 数据组成(图片来自网络wiki)

确切地说,ARGB 格式是 ARGB8888 格式(也称为 ARGB32)。ARGB 其分别是Alpha、Red、Green、Blue的缩写,因为其包含了该像素附近的4个信息,也被称为 4通道 表示方法。其中 alpha 是物体轮廓、透明度的意思。只有 alpha 的图像是灰度图像(灰度图像的示例我们将在下面的讨论中讲到),这在一些 3D 游戏或者图像处理中有额外的用处。比如使用 RGB888,与使用 ARGB8888 的图像区别:
在这里插入图片描述

ARGB 数据与 RGB 数据的比较(图片来自网络wiki)

相比 RGB888,ARGB8888 图中,小树的下面显示了树的阴影。3D 立体感来了没有,老铁们?

小问题:了解 ARGB8888 后,相信大家应该知道 RGBA32 代表的意思了。牛皮!

总结

1)本文从摄像头工作的基本原理说起,Camera sensor 通过滤光片采集不同颜色的数据,生成 RAW 数据。
2)RAW 格式的数据,根据对每种颜色的表示使用几个 bit,也可以分为 RAW8、RAW10、RAW12 等类型。
3)RGB 数据是 RAW 数据组合得到的,根据组合顺序,可以组合得到 RGB、BGR 等格式的数据。
4)一些应用场景需要的数据带宽小、或者需要采集的颜色类型不多,这种情况下可以使用数据量更小的 RGB565、RGB555 等格式。
5)一些以总的数据长度命名的 RGB 格式的数据有 RGB24、RGB16、RGB32 等。
6)一些特别的应用场景还带有 Alpha 值,因此有 ARGB、RGBA 这种类型的 RGB 数据。
(码字不易,感谢点赞或收藏,谢绝未经授权的转载)

  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
斐波那契查找算法是一种基于二分查找算法的查找算法,它利用了斐波那契数列的特性来确定查找的位置。下面是斐波那契查找算法的设计步骤: 1. 首先,需要确定斐波那契数列的长度,使得它大于等于待查找数组的长度。假设斐波那契数列的长度为n,那么有:F(n) = F(n-1) + F(n-2),其中F(0) = 0,F(1) = 1。 2. 然后,需要将待查找数组扩展到长度为n,扩展的部分用原数组的最后一个元素填充。 3. 接着,需要定义两个指针:low和high。初始时,low指向待查找数组的第一个元素,high指向斐波那契数列中第一个大于等于n的元素的下标减1。 4. 然后,需要计算mid的值,mid的值为low加上斐波那契数列中第k-1个元素的值,其中k为满足F(k)-1 >= n的最小值。 5. 然后,比较待查找数组中第mid个元素和要查找的元素的大小。如果待查找数组中第mid个元素小于要查找的元素,则将low指向mid+1;如果待查找数组中第mid个元素大于要查找的元素,则将high指向mid-1;否则,找到了要查找的元素,返回mid。 6. 重复步骤4和步骤5,直到low大于high为止。 下面是一个Python实现的斐波那契查找算法的例子: ```python def fibonacci_search(arr, x): n = len(arr) fib_k2 = 0 # F(k-2) fib_k1 = 1 # F(k-1) fib_k = fib_k1 + fib_k2 # F(k) while fib_k < n: fib_k2 = fib_k1 fib_k1 = fib_k fib_k = fib_k1 + fib_k2 offset = -1 while fib_k > 1: i = min(offset+fib_k2, n-1) if arr[i] < x: fib_k = fib_k1 fib_k1 = fib_k2 fib_k2 = fib_k - fib_k1 offset = i elif arr[i] > x: fib_k = fib_k2 fib_k1 = fib_k1 - fib_k2 fib_k2 = fib_k - fib_k1 else: return i if fib_k1 and arr[offset+1] == x: return offset+1 return -1 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网老王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值