Python OpenCV - imshow doesn't need convert from BGR to RGB

PythonOpencv

Python Problem Overview


As I'm lead to believe, OpenCV reads images in BGR colorspace ordering and we usually have to convert it back to RGB like this:

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

But when I try to simply read an image and show it, the coloring seems fine (without the need to convert BGR to 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)

So is imshow() changing the ordering within the function automatically (from BGR to RGB) or the ordering has been BGR all along?

Python Solutions


Solution 1 - Python

BGR and RGB are not color spaces, they are just conventions for the order of the different color channels. cv2.cvtColor(img, cv2.COLOR_BGR2RGB) doesn't do any computations (like a conversion to say HSV would), it just switches around the order. Any ordering would be valid - in reality, the three values (red, green and blue) are stacked to form one pixel. You can arrange them any way you like, as long as you tell the display what order you gave it.

OpenCV imread, imwrite and imshow indeed all work with the BGR order, so there is no need to change the order when you read an image with cv2.imread and then want to show it with cv2.imshow.

While BGR is used consistently throughout OpenCV, most other image processing libraries use the RGB ordering. If you want to use matplotlib's imshow but read the image with OpenCV, you would need to convert from BGR to RGB.

Solution 2 - Python

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

this one line code changes rgb to bgr

Solution 3 - Python

for matplotlib we need to change BGR to RGB:

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

plt.imshow(img)

Solution 4 - Python

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

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

This converts BGR to RGB Channels Image by reversing the channels.

Solution 5 - Python

If you do not need to use any other Image processing library (example Matplotlib's imshow), there is no need to do color scale conversion. Below code is an example, where the color scale conversion is done but when the image is loaded, it is still loaded in BGR. This conversion is not needed as the image is displayed using 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()

Solution 6 - Python

Alternatively, you can use imutils.opencv2matplotlib() function, which does not need BGR to RGB conversion.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCypherView Question on Stackoverflow
Solution 1 - Pythonw-mView Answer on Stackoverflow
Solution 2 - PythonSatyam SinghView Answer on Stackoverflow
Solution 3 - PythonIvan M.View Answer on Stackoverflow
Solution 4 - PythonPrasadView Answer on Stackoverflow
Solution 5 - PythonPraksView Answer on Stackoverflow
Solution 6 - PythonVenugopal BukkalaView Answer on Stackoverflow