Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIL to OpenCV MAT causes color shift

When loading a png image with PIL and OpenCV, there is a color shift. Black and white remain the same, but brown gets changed to blue.

I can't post the image because this site does not allow newbies to post images.

The code is written as below rather than use cv.LoadImageM, because in the real case the raw image is received over tcp.

Here is the code:

#! /usr/bin/env python
import sys
import cv
import cv2
import numpy as np
import Image
from cStringIO import StringIO

if __name__ == "__main__":
    # load raw image from file
    f = open('frame_in.png', "rb")
    rawImage = f.read()
    f.close()

    #convert to mat
    pilImage = Image.open(StringIO(rawImage));
    npImage = np.array(pilImage)
    cvImage = cv.fromarray(npImage)

    #show it
    cv.NamedWindow('display')
    cv.MoveWindow('display', 10, 10)
    cv.ShowImage('display', cvImage)
    cv. WaitKey(0)

    cv.SaveImage('frame_out.png', cvImage)

How can the color shift be fixed?

like image 247
Andy Rosenblum Avatar asked Feb 20 '23 19:02

Andy Rosenblum


1 Answers

OpenCV's images have color channels arranged in the order BGR whereas PIL's is RGB. You will need to switch the channels like so:

import PIL.Image
import cv2

... 

image = np.array(pilImage) # Convert PIL Image to numpy/OpenCV image representation
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # You can use cv2.COLOR_RGBA2BGRA if you are sure you have an alpha channel. You will only have alpha channel if your image format supports transparency.
...

@Krish: Thanks for pointing out the bug. I didn't have time to test the code the last time.

Hope this helps.

like image 65
lightalchemist Avatar answered Feb 25 '23 16:02

lightalchemist