Opencv Giving Wrong Color to Colored Images on Loading

OpenCV giving wrong color to colored images on loading

OpenCV uses BGR as its default colour order for images, matplotlib uses RGB. When you display an image loaded with OpenCv in matplotlib the channels will be back to front.

The easiest way of fixing this is to use OpenCV to explicitly convert it back to RGB, much like you do when creating the greyscale image.

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

And then use that in your plot.

Wrong color reading an image with OpenCV (Python)

OpenCV does not use RGB, it uses BGR (standing for blue, green, red). You need to swap the order of the red and the blue.

img1 = cv2.imread("tiger.jpg", 3)

b,g,r = cv2.split(img1) # get b, g, r
rgb_img1 = cv2.merge([r,g,b]) # switch it to r, g, b

plt.subplot(121),plt.imshow(rgb_img1),plt.title('TIGER_COLOR')

Also, your grayscale image is fine, but you are using a colormap for it. Make sure to use

plt.imshow(img2, cmap='gray')

imshow colored image, wrongly displayed as blue

The problem is that opencv uses bgr color mode and matplotlib uses rgb color mode. Therefore the red and blue color channels are switched.

You can easily fix that problem by proving matplotlib an rgb image or by using cv2.imshow function.

  1. BGR to RGB conversion:

    for im in images:
    # convert bgr to rgb
    rgb = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
    plt.imshow(rgb, cmap = plt.cm.Spectral)
  2. opencv's imshow function:

    for im in images:
    # no color conversion needed, because bgr is also used by imshow
    cv2.imshow('image',im)

wrong colors when saving image with openCV

As @fmw42 pointed at me in the question comments section,
I was calling np.array() on mss ScreenShot objects and expecting them to it to work out of the box.
It turns out ScreenShot class stores image data on a specific format, and when np.array() manipulates an instance object, it uses a different format for managing image channels, specifically the alpha channel.

So the solution was to first convert mss ScreenShot objects in Image objects that hold image data in compatible way for np.array() to handle them :

def find_diff(before, after):
before = Image.frombytes("RGB", before.size, before.bgra, "raw", "BGRX")
after = Image.frombytes("RGB", after.size, after.bgra, "raw", "BGRX")
before = np.array(before)
after = np.array(after)
...

Image changes color when using cv2 imread

The cv2 module reads in images in BGR format, while the matplotlib module uses RGB. A simple fix would be to use the cv2.cvtColor() method on the image first:

auxImgRGB = cv2.cvtColor(auxImg, cv2.COLOR_BGR2RGB)

The COLOR_BGR2RGB mode is 4.

Displayed image from a time frame of a video has the wrong color

OpenCV uses BGR as its default colour order for images

Use cv2.cvtColor(img, cv2.COLOR_BGR2RGB) before displaying

why cv2.imwrite() changes the color of pics?

Your problem is in the fact that skimage.io.imread loads image as RGB (or RGBA), but OpenCV assumes the image to be BGR or BGRA (BGR is the default OpenCV colour format). This means that blue and red planes get flipped.


3 Channel Images

Let's try this out with the following simple test image:

Input image


First let's try your original algorithm:

import skimage.io
import cv2

img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_1.png', img)

We get the following result:

Result 1

As you can see, red and blue channels are visibly swapped.


The first approach, assuming you want to still use skimage to read and cv2 to write is to use cv2.cvtColor to convert from RGB to BGR.

Since the new OpenCV docs don't mention Python syntax, in this case you can also use the appropriate reference for 2.4.x.

import skimage.io
import cv2

img = skimage.io.imread('sample.png')
cv2.imwrite('sample_out_2.png', cv2.cvtColor(img, cv2.COLOR_RGB2BGR))

Now we get the following output:

Result 2


An alternative is to just use OpenCV -- use cv2.imread to load the image. In this case we're working only with BGR images.

NB: Not providing any flags means cv2.IMREAD_COLOR is used by default -- i.e. image is always loaded as a 3-channel image (dropping any potential alpha channels).

import cv2

img = cv2.imread('sample.png')
cv2.imwrite('sample_out_3.png', img)

Result 3


4 Channel Images

From your screenshot, it appears that you have a 4 channel image. This would mean RGBA in skimage, and BGRA in OpenCV. The principles would be similar.

  • Either use colour conversion code cv2.COLOR_RGBA2BGRA
  • Or use cv2.imread with flag cv2.IMREAD_UNCHANGED

Can't get same color of original image when saving same image in OpenCv, Python

I could solve the problem. I have to convert color of image into RGB color.

cv2.cvtColor(rotate_img, cv2.COLOR_BGR2RGB)

Here is the code :

from scipy.ndimage import rotate
from scipy.misc import imread, imshow
import cv2
count = 0
while True:
if count<230:
filename = 'frame'+str(count)+'.jpg'
print(filename)
img = imread(filename)

rotate_img = rotate(img, 90)
#convert color of image before saving
rgbImg = cv2.cvtColor(rotate_img, cv2.COLOR_BGR2RGB)
cv2.imwrite(filename,rgbImg)
count = count + 1
continue
else :
break


Related Topics



Leave a reply



Submit