PIL旋转图像颜色(BGR - > RGB)

Cla*_*diu 43 python colors python-imaging-library

我有一个颜色是BGR的图像.如何转换我的PIL图像以有效的方式交换每个像素的B和R元素?

Mar*_*ett 92

只是为了添加更新的答案:

随着新的cv2接口加载的图像现在自动为numpy数组.
但是openCV cv2.imread()将图像加载为BGR,而numpy.imread()将它们加载为RGB.

最简单的转换方法是使用openCV cvtColor.

import cv2
srcBGR = cv2.imread("sample.png")
destRGB = cv2.cvtColor(srcBGR, cv2.COLOR_BGR2RGB)
Run Code Online (Sandbox Code Playgroud)

  • 因为最简单的解决方案就是:img = img [...,:: - 1] (9认同)
  • 如果您使用的是OpenCV,那么您拥有BGR图像的唯一原因就在于此.您的解决方案是正确的.另一个最佳答案是功能性的,但在处理大图像时会很慢. (2认同)

Pet*_*192 80

我知道这是一个老问题,但我有同样的问题并解决了它:

img = img[:,:,::-1]
Run Code Online (Sandbox Code Playgroud)

  • img [:,:,:: -1]不等同于img [:,:,[2,1,0]].前者使用基本索引,后者使用高级索引.后者将复制您的图像,而前者则不会. (9认同)
  • 很好,我按照你的笔记和我的测试得到了它.:: - 1`实际上是numpy操作的简写`[start:end:step]`,并且`start` /`end`是自动决定的. (7认同)
  • 为了清楚起见,img = img[:, :, : :-1] 相当于 img = img[:, :, [2,1,0]]。我认为后者更好,因为它更明确。 (4认同)
  • 数据有 3 个维度:宽度、高度和颜色。`::-1` 有效地颠倒了颜色的顺序。宽度和高度不受影响。 (3认同)
  • 这也比上面答案中建议的 cv2.cvtColor 函数性能显着提高。 (2认同)

Joe*_*ton 24

假设没有alpha波段,是不是就这么简单?

b, g, r = im.split()
im = Image.merge("RGB", (r, g, b))
Run Code Online (Sandbox Code Playgroud)

编辑:

嗯......看来PIL在这方面有一些缺陷...... im.split()似乎不适用于最新版本的PIL(1.1.7).它可能(?)仍然适用于1.1.6,但......

或者,如果您有numpy可用,您可以使用它来执行此操作:(再次,我在这里假设RGB图像,而不是 RGBA图像!):

b, g, r = im.split()
im = Image.merge("RGB", (r, g, b))
Run Code Online (Sandbox Code Playgroud)

如果im.split()只是工作,它肯定是一个更简单,更可读的选择!

  • `np.roll`会将BGR转换为RBG,而不是RGB.如果你想在numpy中执行此操作,可以使用`data [...,[2,1,0]]`来交换通道.但是,如果您已经在使用OpenCV或PIL,那么请选择Martin Beckett的回复. (12认同)

小智 12

使用省略号添加解决方案

image = image[...,::-1]

在这种情况下,省略号...相当于:,:while::-1反转最后一个维度(通道)的顺序。


sbe*_*rry 7

这是我最好的答案.顺便说一句,这也适用于Alpha.

from PIL import Image
import numpy as np
import sys 

sub = Image.open(sys.argv[1])
sub = sub.convert("RGBA")
data = np.array(sub) 
red, green, blue, alpha = data.T 
data = np.array([blue, green, red, alpha])
data = data.transpose()
sub = Image.fromarray(data)
Run Code Online (Sandbox Code Playgroud)


小智 6

对于任何编写可能需要处理 4 通道图像的代码并发现简单的 numpy 答案似乎正在吞噬其 alpha 通道的人来说,这只是一个快速脚注。

np_image[:,:,[0,1,2]] = np_image[:,:,[2,1,0]]
Run Code Online (Sandbox Code Playgroud)

如果有第四个通道,将保留 alpha 数据,而

np_image = np_image[:,:,[2,1,0]]
Run Code Online (Sandbox Code Playgroud)

将仅用反转的 3 通道数据覆盖 4 通道图像。(甚至更简单的 numpy 答案,img = img[:,:,::-1],将为您提供 ARGB 数据,这也很糟糕。:)