Python OpenCV - imshow 不需要从 BGR 转换为 RGB

Posted

技术标签:

【中文标题】Python OpenCV - imshow 不需要从 BGR 转换为 RGB【英文标题】:Python OpenCV - imshow doesn't need convert from BGR to RGB 【发布时间】:2018-11-30 11:25:51 【问题描述】:

据我所知,OpenCV 以 BGR colorspace 顺序读取图像,我们通常必须将其转换回 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?

【问题讨论】:

在往返 OpenCV 和其他使用 RGB 排序的工具时,您只需将 BGR 转换为 RGB。 OpenCV 有点奇怪。大多数其他工具和格式都按 RGB 顺序排列。从 OpenCV 保存为标准图像格式时,OpenCV 会自动进行转换。但是在来回切换到 matplotlib 或 PIL 或 skimage 时,您可能需要先转换为 RGB 格式,具体取决于您想要在其他软件包中执行的操作以及您是否打算回到 OpenCV。 【参考方案1】:

BGR 和 RGB 不是颜色空间,它们只是不同颜色通道顺序的约定。 cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 不进行任何计算(例如转换为 HSV 会),它只是切换顺序。任何排序都是有效的——实际上,三个值(红色、绿色和蓝色)堆叠在一起形成一个像素。你可以按照你喜欢的方式排列它们,只要你告诉显示器你给它的顺序。

OpenCV imreadimwriteimshow 确实都适用于 BGR 顺序,因此当您使用 cv2.imread 读取图像然后想用 @987654326 显示它时,无需更改顺序@。

虽然 BGR 在整个 OpenCV 中一直使用,但大多数其他图像处理库使用 RGB 排序。如果你想使用matplotlibimshow但是用OpenCV读取图像,你需要从BGR转换为RGB。

【讨论】:

[旁白:当然如果你想使用matplotlibimshow,你需要转换..] 我做了一个实验:我只使用 Open cv 来 imread 和 imshow 但使用 image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB) 图像变成蓝色(BGR)。我无法理解!谁能解释一下?? 任何排序在技术上都是有效的,但我从未遇到任何其他使用 BGR 而不是 RGB 的软件库。 OpenCV 有一个糟糕的 API 的另一种方式。【参考方案2】:
screen = cv2.cvtColor(screen, cv2.COLOR_RGB2BGR)

这一行代码将rgb改为bgr

【讨论】:

【参考方案3】:
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 通道图像。

【讨论】:

【参考方案4】:

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

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

plt.imshow(img)

【讨论】:

这也会将 rgb 转换为 bgr。因此,当他们同时使用这两种类型的图像时,必须小心。【参考方案5】:

如果您不需要使用任何其他图像处理库(例如 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()

【讨论】:

【参考方案6】:

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

【讨论】:

以上是关于Python OpenCV - imshow 不需要从 BGR 转换为 RGB的主要内容,如果未能解决你的问题,请参考以下文章

Python OpenCV imshow 失败

opencv-python 中的 imshow 不起作用

cv2.imshow命令在opencv-python中无法正常工作

使用 imshow + waitKey 显示图像 opencv+python 时出现问题

opencv-python imshow在mac中给出错误

Python Opencv imshow 错误