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

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

125674 次浏览

您应该能够使用 ImageMath模块完成这项工作。

编辑:

乔的解决办法更好,我想多了。 :)

假设没有阿尔法波段,不就这么简单吗?

b, g, r = im.split()
im = Image.merge("RGB", (r, g, b))

编辑:

嗯... 似乎 PIL 在这方面有一些错误... im.split()似乎不与最近版本的 PIL (1.1.7)工作。有可能不过仍然是1.1.6。

这是我最好的答案,顺便说一句,这个对 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)

再补充一个最新的答案:

使用新的 cv2接口加载的映像现在是自动的数组。
但 openCV cv2.imread ()以 BGR 格式加载图像,numpy.imread ()以 RGB 格式加载图像。

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

import cv2
srcBGR = cv2.imread("sample.png")
destRGB = cv2.cvtColor(srcBGR, cv2.COLOR_BGR2RGB)
import cv2
srcBGR = cv2.imread("sample.png")
destRGB = cv2.cvtColor(srcBGR,cv2.COLOR_BGR2RGB)

只是为了澄清马丁贝克特的解决方案,因为我无法发表评论。 在颜色常数之前需要 cv2。

使用之前解释过的想法... 使用麻木你可以。

bgr_image_array = numpy.asarray(bgr_image)
B, G, R = bgr_image_array.T
rgb_image_array = np.array((R, G, B)).T
rgb_image = Image.fromarray(rgb_image_array, mode='RGB')

此外,它可以删除阿尔法通道。

assert bgra_image_array.shape == (image_height, image_width, 4)
B, G, R, _ = bgra_image_array.T
rgb_image_array = np.array((R, G, B)).T

我知道这是个古老的问题,但我也遇到了同样的问题,并用以下方法解决了它:

img = img[:,:,::-1]
im = Image.frombuffer('RGB', (width, height), bgr_buf, 'raw', 'BGR', 0, 0)

使用省略号添加解决方案

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

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

其他解决方案的应用。只是暂时的措施。

import numpy


im = Image.fromarray(numpy.array(im)[:,:,::-1])

对于那些编写可能必须处理4通道图像的代码的人来说,这只是一个简单的脚注,并且发现简单的麻木的答案似乎正在吞噬他们的 alpha 通道。

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

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

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

将只使用反向的3通道数据覆盖4通道图像。(更简单的数字式答案 img = img [ : : : : :-1]会给出 ARGB 数据,这也是不好的。:)

TLDR : 如果已经导入了 cv2,则使用 cv2.cvtColor(img, cv2.COLOR_BGR2RGB))


速度比较:

%%timeit
img_ = Image.fromarray(img[...,::-1])
# 5.77 ms ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


%%timeit
img_ = Image.fromarray(img[...,[2,1,0]])
# 6.2 ms ± 2.43 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


%%timeit
img_ = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 442 µs ± 4.84 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

问题是,OP 询问 img是否已经是 PIL图像格式,而 cv2.cvtColor(img, cv2.COLOR_BGR2RGB))要求 imgnumpy数组格式。

但是,cv2.imread()很可能是你获得 BGR 图像的原因,而不是 Image.open()

如果你有阿尔法波段,使用这个:

img = img[:,:, [2, 1, 0, 3]]