将图像的通道顺序从RGB更改为BGR有什么原因吗?

4

我一直在跟随Keras视频分类教程,其中在数据准备部分,他们在load_video函数中通常加载视频的帧,但是吸引我的是这行代码:

frame = frame[:, :, [2, 1, 0]]

这是我第一次遇到这种情况,大多数情况下,您只需将帧“原样”附加到帧列表中,但是在这里,它们改变了通道的顺序(如果我没有错的话)从RGB到BGR,我在网上或他们的文档中找不到任何相关的信息,有人能给我一些关于这个决定的见解吗?


如果你所有的操作都能够协调使用通道,那就没有问题。即使在深度学习训练时交换颜色平面也是无害的,因为系统永远不会知道这些颜色不真实。但是你需要记得保持交换! - user1196549
1个回答

6

根据经验,图像顺序变化的原因取决于您使用的加载图像的框架。特别是OpenCV以BGR格式排序通道,因为大多数历史原因现在已过时。因此,我们不幸地被困在这个设计选择中。常规RGB格式的图像可以使用scikit-image、matplotlib和Pillow查看。

事实上,如果您查看load_video函数,它使用OpenCV打开视频,因此传入的帧是BGR格式。因此,强制交换通道以获取RGB格式是必需的:

def load_video(path, max_frames=0):
    cap = cv2.VideoCapture(path)
    frames = []
    try:
        while True:
            ret, frame = cap.read()
            if not ret:
                break
            frame = crop_center(frame)
            frame = frame[:, :, [2, 1, 0]]
            frames.append(frame)

            if len(frames) == max_frames:
                break
    finally:
        cap.release()
    return np.array(frames)

当然,你不需要反转通道因为神经网络将根据提供的输入数据进行学习,但人们倾向于这样做,以便轻松调试图像,而无需担心不断地颠倒通道以进行显示。具体而言,如果神经网络是在BGR顺序中训练的,如果你以RGB格式加载图像,则需要反转通道,因为这是训练中如何表示图像通道的方式。总之,这取决于框架,但在神经网络训练后使用时需要牢记这一点。如果数据是以BGR格式进行训练的,如果你读入的图像是以RGB格式,则需要在推断之前反转通道。
实际上,这是在使用网络时常见的错误!要非常努力并了解网络的图像数据是如何预处理的。

1
想知道什么情况下需要使用BGR而不是RGB进行优化?为什么BGR比RGB更好? - fmw42
2
@fmw42 很好的问题!这主要是出于历史原因。这是与相机制造商最兼容的格式,因此一旦加载了数据,您就不需要进行任何其他操作以使其达到我们最终熟悉的格式:https://learnopencv.com/why-does-opencv-use-bgr-color-format/ - rayryeng
3
“与相机制造商兼容”这个理由是一个误解。如果他们真的因为这个原因使用了BGR,那就很遗憾了。在小端机器中,将RGB三元组写成 R<<16 + G<<8 + B 的形式时,它以BGR顺序存储在24位字中,所以BRG是有道理的。但是,为什么你要那样写三元组呢?我认为真正的原因是将一些旧代码从大端机器翻译成小端机器的过程中出现了问题。现在OpenCV陷入了这个错误 :/ - Cris Luengo
@ImSo3K 很好。很高兴能帮到你! - rayryeng
3
在这篇博客文章中提到:“在Windows中,当使用COLORREF指定颜色值时,它们使用BGR格式0x00bbggrr。”由于Windows一直在小中型计算机上运行,所以在内存中0x00bbggrr会被存储为"rrggbb00",也就是RGB格式! - Cris Luengo
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接