【问题标题】:What exactly is BGR color space?BGR色彩空间到底是什么?
【发布时间】:2010-09-26 21:59:58
【问题描述】:

RGB 颜色由三个分量组成:红色 (0-255)、绿色 (0-255) 和蓝色 (0-255)。

究竟什么是 BGR 色彩空间?它与 RGB 颜色空间有何不同?

【问题讨论】:

    标签: colors opencv color-space


    【解决方案1】:

    关于字节序

    RGB 是一个字节顺序。但大多数普通图形库的一个有意实现选择是,它们在内部将颜色视为无符号 32 位整数,并将三个(或四个,通常包括 alpha)分量打包到整数中。

    在 little-endian 机器(例如 x86)上,整数 0x01020304 实际上将作为 0x04030201 存储在内存中。因此 0x00BBGGRR 将被存储为 0xRRGGBB00!

    所以术语 BGR(和 BGRA 等)是一个泄漏的抽象,其中图形库解释整数是如何在逻辑上排序的,以便使您直接访问单独颜色分量的代码更具可读性。

    请记住,位图通常由比处理器更多的硬件部分访问,并且由传统显示适配器指定的字节序不一定与 CPU 的字节序相同。在操作像素中的通道的级别上,CPU 提取字段无论其顺序如何都没有问题;它纯粹是一个了解标签的程序员。

    【讨论】:

    • 但在 Windows 中,必要的字节顺序是 0xBB、0xGG、0xRR - 你如何解释?
    • 我认为这与字节序无关。 Gamegear 使用 BGR 颜色,以及 Wonderswan 颜色,但 Gameboy 颜色和 Advance 使用 RGB 颜色。都是 little-endian 系统(分别基于 Z80、80286、Z80 和 ARM)。
    • 我的理论:他们希望它们按波长递增的顺序排列。
    • 对于现在徘徊的任何人,根据this answer 的说法,BGR 在 PC 平台上的原始使用可以追溯到与原始 IBM VGA 实现中使用的 RAMDAC 交互的便利技巧。使用 BGR 的 Windows 也类似。
    【解决方案2】:

    RGB 代表红绿蓝。大多数情况下,RGB 颜色存储在一个结构或无符号整数中,蓝色占据最低有效“区域”(32 位和 24 位格式的字节),绿色第二少,红色第三少。

    BGR 是相同的,只是区域的顺序颠倒了。红色占据最不重要的区域,绿色第二(仍然),蓝色第三。

    在某些平台上(例如Gamegear),使用了 BGR 模型。但是,通常可能会使用 RGB(尽管许多图形 API 都支持 BGR 以实现兼容性)。我不确定为什么确实使用了它;可能是历史性的。

    示例:#FF0000 在读取为 RGB 十六进制颜色 (#rrggbb) 时为纯红色,因为第三个区域(数字从右到左读取!)为 FF(最大值,全色),其他两个区域为00(最小值,无颜色)。如果 #FF0000 被读取为 BGR 十六进制颜色,它将是纯蓝色。

    【讨论】:

    • 这个答案不正确:见docs.opencv.org/doc/tutorials/core/how_to_scan_images/…。 OpenCV 的约定是 BGR,B 存储在比 R 低的字节地址。B 或 R 是最低有效位取决于机器的字节顺序,而且 24 位 BGR 像素未与 32 位边界对齐一个无符号整数(所以用它来解释没有多大意义)。
    【解决方案3】:

    这是关于颜色分量在内存中的布局方式。对于BGR,顺序是BGRBGRBGRBGR...,对于RGB,顺序是RGBRGBRGB...对于BGR,OpenCV的默认顺序是这样的:

    (请参阅 How the image matrix is stored in the memory? 的 OpenCV 文档)

    请注意,其他答案提到某些颜色最不重要或最重要,但这实际上取决于您机器的字节序。例如,无符号整数中组件的打包顺序实际上取决于您的软件或您正在使用的库。但是,无论您的库或机器的字节序如何,对于 BGR 像素,B 颜色分量的字节地址将比 G 少一个,比 R 少两个(而对于 RGB,情况正好相反)。

    【讨论】:

      【解决方案4】:

      它只是 RGB 的更严格控制的顺序,与字节顺序无关。一旦您知道环境的字节顺序,它们之间的转换就很简单了。

      BGR 是 24 位表示,其中低地址 8 位为蓝色,下一个地址 8 为绿色,高地址 8 为红色。

      RGB 值倾向于写为 RGB(r,g,b),其中 r/g/b 值介于 0 和 255 之间,或者写为 #rrggbb,其中 rr/gg/bb 是 8 位十六进制值。我见过的所有 BGR 值都倾向于是介于 016777215 (0xffffff) 之间的简单整数。

      【讨论】: