imshow不需要将BGR转换为RGB

97

据我所知,OpenCV以BGR顺序读取图像 颜色空间,我们通常需要将其转换回RGB,方法如下:

按我的理解,OpenCV 以 BGR 顺序读取图像,而我们通常需要将其转换为 RGB。具体做法如下:

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

但是当我尝试仅仅读取并展示一张图片时,颜色看起来很好(无需将BGR转换为RGB):

img_bgr = cv2.imread(image_path)
cv2.imshow('BGR Image',img_bgr)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
cv2.imshow('RGB Image',img_rgb )
cv2.waitkey(0)

imshow()是自动更改函数内的排序(从BGR到RGB),还是一直使用的BGR排序?


4
只有在转换OpenCV和其他使用RGB排序的工具之间时,才需要将BGR转换为RGB。 OpenCV有点不同寻常。大多数其他工具和格式都是按RGB顺序排列的。当从OpenCV保存到标准图像格式时,OpenCV会自动进行转换。但是,当来回转换到matplotlib、PIL或skimage时,根据您想要在这些其他软件包中执行的操作以及是否打算返回OpenCV,您可能需要先转换为RGB格式。 - fmw42
6个回答

109
BGR和RGB不是颜色空间,它们只是不同颜色通道排序的约定。cv2.cvtColor(img, cv2.COLOR_BGR2RGB)并不进行任何计算(比如转换为HSV),它只是调整颜色通道的顺序。实际上,三个值(红、绿、蓝)被堆叠在一起形成一个像素,你可以按任意方式排列它们,只要告诉显示器你给了什么顺序即可。
OpenCV的imreadimwriteimshow都使用BGR顺序,因此在使用cv2.imread读取图像并想用cv2.imshow显示时,无须改变顺序。
虽然OpenCV中始终使用BGR,但大多数其他图像处理库使用RGB顺序。如果你想使用matplotlibimshow函数,但使用OpenCV读取图像,则需要将其从BGR转换为RGB。

5
顺便说一句:如果您想使用matplotlibimshow,您需要进行转换。 - jtlz2
我做了一个实验: 我只使用OpenCV来读取和显示图像,但是使用了 image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB) 图像变成了蓝色(BGR)。我无法理解! 有人能解释一下吗? - THEODOROPOULOS DIMITRIS
1
任何排序方式在技术上都是有效的,但我从未遇到过其他使用BGR而不是RGB的软件库。这是OpenCV又一种糟糕的API。 - qwr
一个注意点:通过HTML画布从OpenCV.js中读取图像时,它是RGB而不是BGR。 - JustAMartin

19
screen = cv2.cvtColor(screen, cv2.COLOR_RGB2BGR)

这一行代码将 RGB 转换为 BGR。


10

对于matplotlib,我们需要将BGR更改为RGB:

img = cv2.imread("image_name")
img = img[...,::-1]

plt.imshow(img)

1
这将同时将 RGB 转换为 BGR。因此,在使用两种类型的图像时,必须小心。 - Senthil Vikram Vodapalli

2
opencv_image_with_bgr_channels = cv2.imread('path/to/color_image.jpg')

matplotlib_compatible_image_with_rgb_channels = opencv_image_with_bgr_channels[:,:, ::-1]

这将通过反转通道将BGR转换为RGB通道图像。


-1

如果您不需要使用其他的图像处理库(例如Matplotlib的imshow),则不需要进行颜色比例转换。以下代码是一个例子,在这个例子中进行了颜色比例转换,但是当图像被加载时,它仍然以BGR格式加载。由于图片是使用cv2.imshow()显示的,因此不需要进行此转换。

import cv2

# read the image #
image = cv2.imread('<<Image Path>>')
                
image_rgb = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)

# write a function to draw circles on the image #
def draw_circle(event,x,y,flags,params):
    if event == cv2.EVENT_RBUTTONDOWN:
        cv2.circle(img=image_rgb,center=(x,y),radius=100,color=(0,0,255),thickness=10)

# Open CV callbacks #
cv2.namedWindow(winname='ImageWindow')
cv2.setMouseCallback('ImageWindow',draw_circle)

# display the image till the user hits the ESC key #
while True:
    cv2.imshow('ImageWindow',image_rgb)
    if cv2.waitKey(20) & 0xFF == 27:
        break
        
cv2.destroyAllWindows()


-3

或者,您可以使用imutils.opencv2matplotlib()函数,它不需要进行BGR到RGB的转换。


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