8

I am trying to read and write jpegs wth Adobe RGB colorspace in OpenCV. OpenCV assumes the jpeg has sRGB colorspace and when displaying or writing to file, the image loses some of its color intensity. I found this intensity loss was due to colorspace difference by answers given to my previous question.

Is there anyway I can make OpenCV to read Adobe RGB colorspace without casting it to sRGB?

zindarod
  • 6,328
  • 3
  • 30
  • 58
  • 1
    You need to apply the conversion yourself. [Here](http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf) on page 12 seems to explain how to apply the conversion. Unfortunately I don't have enough time to test it. Hope it helps. – Miki Oct 16 '15 at 11:10
  • @Miki I can write the conversion code if I have to but the problem is that how do I know if the image has Adobe RGB or sRGB colorspace? OpenCV gives no such indication. cv::imread already assumes the image is sRGB. – zindarod Oct 16 '15 at 11:14
  • The image header will contain that information. I think that the only option is to extract such information from there. This is just a speculation, though. I'll come back on this as soon as I have actually tested something, if no other answers arrive in the meantime. – Miki Oct 16 '15 at 11:19
  • @Miki Thanks, I appreciate it. – zindarod Oct 16 '15 at 11:21
  • Just a [proof of concept](http://imgur.com/mHSHEMC) (on your frog image) that checking the header could actually work. – Miki Oct 16 '15 at 11:25
  • @Miki I have used both GIMP and ImageMagick. ImageMagick: "identify -verbose ./treefrog.jpg" shows colorspace as sRGB while GIMP on opening the image for display, gives a warning that the colorspace is Adobe RGB. ImageMagick does not understand AdobeRGB. – zindarod Oct 16 '15 at 11:32

1 Answers1

4

Some information that is hopefully useful for anyone looking for a work-around for dealing with ICC and other profiles...


You can see what profiles are present in an image using ImageMagick which is installed on most Linux distros and is available for macOS and Windows. In the Terminal, or Command Prompt on Windows, run:

magick identify -verbose frog.jpg | grep 'Profile-.*bytes'
Profile-icc: 578 bytes

That tells you this image has a 578 byte ICC profile embedded.

If you are on Windows and don't have grep, you can equally use the following, though you may need to double up the percent sign, or prefix it with a caret (^) or somehow escape it:

magick identify -format "%[profiles]" frog.jpg
icc

You can extract that profile from the image, using this command:

magick frog.jpg frog.icc

And, you'll get a 578 byte ICC profile:

ls -l *icc
-rw-r--r--   1 mark  staff       578 24 Apr 10:36 frog.icc

You can check that the profile looks correct using the file command:

file *icc
frog.icc: ColorSync color profile 2.1, type ADBE, RGB/XYZ-mntr device by ADBE, 560 bytes, 11-8-2000 19:51:59 "Adobe RGB (1998)"

You can apply that profile to some other file like this:

magick other.jpg -profile "icc:frog.icc" otherWithProfile.jpg

Once you have extracted the profile using the above method, you can apply it to an image that you plan to use with OpenCV using PIL/Pillow's ImageCMS Module.

For that, I think you need to use these steps or something very similar, though I have not tested it:

from PIL import Image, ImageCMS
import numpy as np

# Open frog with PIL/Pillow
im = Image.open('frog.jpg')

iccp = PIL.ImageCms.getOpenProfile("profile.icc")
rgbp = ImageCms.createProfile("sRGB")

icc2rgb = ImageCms.buildTransformFromOpenProfiles(rgbp, iccp, "RGB", "RGB")
result = ImageCms.applyTransform(im, icc2rgb)

You should then be able to convert the resulting image to a Numpy array that OpenCV can work with using:

OpenCVim = np.array(result)

and remember to then convert from RGB ordering to BGR with cv2.cvtColor().


Rather than detect and extract the ICC profile with ImageMagick, you could equally use PIL/Pillow like this:

from PIL import Image

im = Image.open('frog.jpg')

# Now look at "im.info"

{'jfif': 257,
 'jfif_version': (1, 1),
 'dpi': (72, 72),
 'jfif_unit': 1,
 'jfif_density': (72, 72),
 'icc_profile': b'\x00\x00\x020ADBE\x02\x10\x00\x00mntrRGB XYZ \x07\xd0\x00\x08\x00\x0b\x00\x13\x003\x00;acspAPPL\x00\x00\x00\x00none\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xd6\x00\x01\x00\x00\x00\x00\xd3-ADBE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ncprt\x00\x00\x00\xfc\x00\x00\x002desc\x00\x00\x010\x00\x00\x00kwtpt\x00\x00\x01\x9c\x00\x00\x00\x14bkpt\x00\x00\x01\xb0\x00\x00\x00\x14rTRC\x00\x00\x01\xc4\x00\x00\x00\x0egTRC\x00\x00\x01\xd4\x00\x00\x00\x0ebTRC\x00\x00\x01\xe4\x00\x00\x00\x0erXYZ\x00\x00\x01\xf4\x00\x00\x00\x14gXYZ\x00\x00\x02\x08\x00\x00\x00\x14bXYZ\x00\x00\x02\x1c\x00\x00\x00\x14text\x00\x00\x00\x00Copyright 2000 Adobe Systems Incorporated\x00\x00\x00desc\x00\x00\x00\x00\x00\x00\x00\x11Adobe RGB (1998)\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XYZ \x00\x00\x00\x00\x00\x00\xf3Q\x00\x01\x00\x00\x00\x01\x16\xccXYZ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00curv\x00\x00\x00\x00\x00\x00\x00\x01\x023\x00\x00curv\x00\x00\x00\x00\x00\x00\x00\x01\x023\x00\x00curv\x00\x00\x00\x00\x00\x00\x00\x01\x023\x00\x00XYZ \x00\x00\x00\x00\x00\x00\x9c\x18\x00\x00O\xa5\x00\x00\x04\xfcXYZ \x00\x00\x00\x00\x00\x004\x8d\x00\x00\xa0,\x00\x00\x0f\x95XYZ \x00\x00\x00\x00\x00\x00&1\x00\x00\x10/\x00\x00\xbe\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'}

Here's the frog.jpg image:

enter image description here

Keywords: Python, ImageMagick, image, image processing, profile, ICC profile, extract, insert, apply, transform, PIL, Pillow, OpenCV, CMS, pyCMS.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432