RGB 与 BGR 颜色深度、像素和字节之间的关系

be8379c9e11d35aa11b4148d20903ee2.jpeg

在处理图像时,了解 RGB 和 BGR 色彩空间之间的区别非常重要。RGB 和 BGR 都具有三个颜色通道:红色、绿色和蓝色。但是,这些通道在图像文件中的存储顺序可能不同。

  • RGB 通常用于图像编辑和显示应用程序,顺序为红色、绿色和蓝色。

  • BGR 通常用于图像处理应用程序,顺序为蓝色、绿色和红色。

图像数据可以保存在不同的颜色空间(RGB、BGR、Gray等),不同的文件格式可以将图像保存在不同的颜色空间。这取决于图像处理库和软件在保存(或打开)图像时使用的颜色空间。

但是,将图像保存为文件格式时,通常的做法是将其保存在 RGB 颜色空间中。值得注意的是,当你以 BGR 顺序保存图像时,它仍然可以被大多数库和软件读取,但它们会将其视为 RGB 图像并以 RGB 格式显示。(你会看到交换了红色和蓝色通道的图像)

使用exiftool之类的工具查看图片的元数据,可能会得到这样的结果:color mode: RGB或者Color Space Data: RGB

这意味着一张图片有 3 个通道,但并不意味着 3 个颜色通道的顺序是red-green-blue,它也可能是blue-green-red。

读取和解释图像文件的程序决定了如何解释图像的颜色通道:不同的库(例如 OpenCV 和 PIL)对图像文件使用不同的默认解码方法,这可能导致图像被解释为BGRRGB

使用 Python 处理图像文件时,OpenCV 库(cv2)在读取图像时默认使用 BGR 颜色空间,而 PIL 库使用 RGB 颜色空间:

import cv2
from PIL import Image

#reading an image using cv2.imread()
img_bgr = cv2.imread("image.jpg")

#reading an image using plt.imread()
img_rgb = Image.open("image.jpg")

总而言之,当我们说 rgb 图像(有时称为真彩色图像)时,这意味着通过假设该图像的颜色通道顺序为红-绿-蓝来保存图像,而 bgr-image 则通过假设颜色顺序为蓝-绿-红。当我们打开该图像并通过某些软件或库进行绘图时,该软件或库将决定以 RGB 色彩空间还是 BGR 色彩空间显示图像。

使用 PIL 库打开 rgb 图像 :

import numpy as np
from PIL import Image, ImageOps
import matplotlib.pyplot as plt

# Here we show rgb-image in RGB-color-space
rgb_img = Image.open("parrot-org.jpg") 
plt.imshow(rgb_img)
bcf34baf2e917f053dbe003512f64b0e.jpeg

使用 PIL 库打开 bgr 图像 :

BGR 不是实际的颜色空间,它只是图像的表示,其中颜色通道的顺序不同于传统的 RGB 表示。图像中像素的颜色值保持不变,但颜色通道的顺序交换了,第一个通道是蓝色,第二个通道是绿色,第三个通道是红色。

例如,[240,26,0]是左上角的像素值,当你通过 plt.imshow() 绘制图像时,你将在图像的左上角看到一个红点。因此,这意味着 plt.imshow() 使用了RGB-color-space,它确定了255表示红色,0表示绿色,0表示蓝色。然后像这样交换颜色通道:(1,2,3)–>(3,2,1)。

之后,左上角的像素值 ( [240, 26, 0]) 变为[0, 26, 240],然后你再次绘制它。现在你将在图像的左上角看到一个蓝点。因此,这意味着plt.imshow()使用了RGB 颜色空间,它确定0表示红色,0表示绿色,255表示蓝色。

这就是为什么你看到的是蓝点而不是红点。

基于此,我们可以说BGR颜色空间是RGB颜色空间中交换颜色通道的图像的表示。

# Here we show bgr-image in RGB-color-space
rgb_data = np.array(rgb_img)
bgr_data = rgb_data[:, :, ::-1]  # (red,green,blue) --> (blue,green,red)
bgr_img = Image.fromarray(bgr_data)
plt.imshow(bgr_img);
334d2e675206c6b02320d37fb0cb0e10.jpeg

将 3 通道图像转换为 1 通道图像

有多种方法可以将图像从 RGB 颜色空间转换为灰度,但最常用的方法之一是使用红色、绿色和蓝色值的加权平均值。该方法根据人眼对每种颜色的相对敏感度,为三个颜色通道分配不同的权重。

最常用的权重是:gray_weighted_average= 0.299 * R + 0.587 * G + 0.114 * B

另一种转换为灰度的方法是使用光度法,它根据人眼的光度函数分配不同的权重。这是将彩色图像转换为灰度图像的更准确方法:gray_luminosity = 0.2126 * R + 0.7152 * G + 0.0722 * B

OpenCV的cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)采用加权平均法,Pil.ImageOps.grayscale(rgb_img)采用光度法。

gray_img = ImageOps.grayscale(rgb_img)
plt.imshow(gray_img, cmap='gray');
7ac430e2589da676b7a3d218f03d9c74.jpeg

分别查看具有不同色调的 3 个颜色通道

tint_names = ["red", "green", "blue"]

plt.figure(figsize=(12,5))
for i in range(3):
    plt.subplot(1, 3, i+1)
    arr = np.zeros((3,), dtype='int')
    arr[i] = 1
    img1 = rgb_data*arr
    plt.title(f"channel={i+1} in  #{tint_names[i]} tint")
    plt.imshow(img1)    
        
plt.figure(figsize=(12,5))
for i in range(3):
    plt.subplot(1, 3, i+1)
    img1 = rgb_data[:, :, i]
    plt.title(f"channel={i+1} in  #grey tint")
    plt.imshow(img1, cmap='gray')
ab4180d0e9b2f8fd0455283733a91333.jpeg

使用 OpenCV

RGB 图像——假设颜色通道的顺序是红-绿-蓝保存。

  • 当你使用 opencv 读取 RGB 图像时 —>cv2.imread()读取 rgb 图像并通过交换颜色通道将其作为 bgr 图像返回

  • 在通过 opencv 读取 rgb 图像之后,如果你还使用 opencv 绘图 ->cv2.imshow()将在 BGR 颜色空间中绘制图像

因此,当你使用 opencv 打开 rgb 图像并使用 opencv 绘制它时,你将在 BGR 颜色空间中看到 bgr 图像,这看起来与 RGB 颜色空间中的 rgb 图像 相同。

import cv2

# Here we see bgr-image in rgb-color-space
bgr_img_by_cv2 = cv2.imread(img_path)  
plt.imshow(bgr_img_by_cv2);
1cd5fa7ec63dae7123cd2876fe992843.jpeg

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2023年9月1日
下一篇 2023年9月1日

相关推荐