本文翻译自iOS Application Development with OpenCV 3
正如我们所看到的,OpenCV和iOS SDK使用各种格式的彩色和灰度图像,有时我们需要在格式之间进行转换。 让我们从代码中退一步,讨论格式之间的差异以及如果我们不执行正确的转换可能出现的问题。
RGB, BGR, RGBA, and BGRA
您可能已经学过24位RGB颜色格式,这是您第一次在绘图程序或文字处理器中选择自定义颜色。 像素的颜色由三个值的序列表示,每个值的范围为0到255(即8位或1个字节)。 第一个值是颜色的红色分量或通道,然后是绿色,最后是蓝色。 例如,琥珀色交通灯的颜色是(255,126,0),是许多红色和一些绿色的混合,但没有蓝色。 一系列像素数据产生图像。
24位BGR格式简单地反转了通道顺序。 例如,琥珀色交通灯的颜色为BGR格式的(0,126,255)。
RGBA和BGRA增加了第四个通道alpha。 Alpha表示透明度,其中0表示完全透明,255表示完全不透明(假设每个通道8位或总共32位)。 当然,“透明"不是光的波长,普通的照相机不记录任何数据来区分反射光(从不透明表面反弹)和透射光(透过透明材料)。 因此,未处理的照片可以被认为是不透明的,并且如果它包括alpha通道,则alpha值将全部为255。如果我们想要选择性地混合图像的部分,则透明度或alpha将会有用。
通常,OpenCV使用24位BGR或32位BGRA来显示彩色图像。 但是,iOS SDK通常使用RGBA格式,因此我们必须执行转换,否则红色和蓝色通道将被搞反。
以下是在彩色图像中交换红色和蓝色通道的效果。

YUV and grayscale
假设我们想要使用少于24 bpp的图像,以便我们的图像使用更少的内存,并且可以在更短的时间内处理。 为此,我们必须牺牲24 bpp在RGB或BGR中可以表现的一些微妙的颜色渐变。 但是,我们希望保留表现微妙渐变亮度的能力。 在这里,我们遇到了RGB和BGR的关键限制。 亮度取决于所有三个通道,当我们牺牲任何通道中的位时,我们会失去亮度等级。
YUV颜色模型解决了这个问题。 Y通道只代表亮度。 U通道表示蓝色(与绿色相对),而V通道表示红色(也与绿色相对)。 一些YUV是planar格式,这意味着所有Y数据在存储器中是连续的,接着是所有U和V数据。 其他一些YUV是packed格式,意味着Y,U和V数据是交错的,如RGB或BGR中的R,G和B数据。
planar格式的示例是I420,其具有12bpp。 这包括全分辨率图像中每个像素的8位Y值以及以一半分辨率采样的4位U和4位V值。
packed格式的一个例子是YUYV,它有16 bpp。 这包括全分辨率图像中每个像素的8位Y值以及以一半分辨率采样的8位U和8位V值。 请注意,所有这些值都是字节大小的。 每个Y字节交替地与U或V字节交错,如YUYV所示。
灰度图像等效于平面YUV图像的Y平面。 通常,摄像机的固件或至少其驱动程序可以有效地将捕获的视频转换为平面YUV格式。 然后,如果应用程序只需要灰度数据,它可以读取或复制Y平面。 这种方法比捕获RGB帧并将其转换为灰度的方法更有效。
网友评论