Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6684 Discussions

## RGB to XYZ

New Contributor I
3,041 Views

Referring to "Procedural Elements for Computer Graphics" by David F. Rogers (1985) the ipp headers list the transformation matrix for RGB to XYZ  as follows

X =  0.412453 * R + 0.35758 * G + 0.180423 * B

Y =  0.212671 * R + 0.71516 * G + 0.072169 * B

Z =  0.019334 * R + 0.119193* G + 0.950227 * B

This is listed as the transformation matrix from HDTV (Rec. 709) RGB to CIE XYZ.

Wikipedia shows https://en.wikipedia.org/wiki/CIE_1931_color_space another transformation matrix, which is from CIE RGB to CIE XYZ. Clearly, the RGB to XYZ transformation (and vice versa) depends on the ICC profile of the image. This is true for RGB to LUV and RGB to LAB too, as ipp uses RGB to XYZ as part of those transformations.

Can you confirm the above and is there a special reason why the HDTV color space was chosen ? It seems a logical choice for movies, rather than still images. However, the much used sRGB color space was derived (and is nearly identical) to the HDTV color space.

Regards,

8 Replies
New Contributor I
3,041 Views

In fact, the RGB to XYZ matrix to be used can simply be calculated from the x and y chromaticities that are stored with the ICC profile of an image (see e.g. http://www.brucelindbloom.com/index.html and docs-hoffmann.de/ciexyz29082000.pdf). That matrix can then be used with ippiColorTwist and ippiColorTwist32f to do an RGB to XYZ transformation that is more precise than the rather arbitrary (HDTV-only) transformation used by ippiRGBToXYZ.

Unfortunately, ippiRGBToLUV and ippiRGBToLab are based on ippiRGBToXYZ and therefore are HDTV-only.

To solve this dilemma, I suggest to add ippiXYZtoLab, ippiLabToXYZ, ippiXYZtoLUV and ippiLUVtoXYZ functions to IPP (and also ippiXYZtoYxy and ippiYxytoXYZ).

Regards,

New Contributor I
3,041 Views

Another issue. The comment in the ipp headers with ippRGBtoXYZ says:

Equations are given above in assumption that the X,Y,Z,R,G, and B values are in the range [0..1].

Y, C1, C2, R, G, B - are scaled to the range:

[0..1]                      for the 32f depth,

[0..IPP_MAX_8u]             for the 8u depth,

[0..IPP_MAX_16u]            for the 16u depth,

[IPP_MIN_16s..IPP_MAX_16s]  for the 16s depth.

This is not correct. First, there are no Y, C1 and C2 values here, but X, Y and Z values. Second, by comparing the result with ippiColorTwist32f, I checked that ippiRGBtoXYZ actually applies the given matrix  w i t h o u t  normalizing the resulting X, Y and Z to 0..1. Consequently, the X, Y and Z entry values of ippiXYZto RGB are not in the range 0..1, but in a range that sets the resulting R, G and B to be in the range 0..1. Which X, Y and Z values these are, can be found by adding the row values of the given (HDTV) RGB to XYZ matrix.

I draw your attention again to the complexity (http://www.argyllcms.com/doc/ArgyllCMS_arts_tag.html) of the RGB to XYZ conversion as this is a device to device-independent conversion. The device to device conversions are unproblematic: between RGB, HSL and HSV. Also, the device-independent conversions are unproblematic (but unfortunately missing in IPP): between XYZ, Lab, LUV and xyY. Direct conversions between RGB and Lab, LUV are not recommended, but should instead use the RGB to XYZ conversion as an extra step.

Compare this with the device to device and device-independent conversions available with ColorSync https://developer.apple.com/documentation/applicationservices/colorsync_manager/1805133-cmconvertxyztolab#overview

Regards,

New Contributor I
3,041 Views

And another (related) issue. The headers for ippiGammaFwd and ippiGammaInv say:

Purpose:  Performs gamma-correction of an RGB image (ippiGammaFwd); converts a gamma-corrected RGB image back to the original (ippiGammaInv).

In general, this is not true. The mentioned gamma function is the gamma correction specified by ITU-R Recommendation BT.709, https://en.wikipedia.org/wiki/Rec._709  for HDTV. The related sRGB color space https://en.wikipedia.org/wiki/SRGB uses another gamma correction. No other still image color space uses this gamma correction, so for still images, these functions are of no use.

I think this should at least be mentioned in the headers and the documentation.

Also unmentioned is the fact that RGB to XYZ conversions (see my comments above) require inverse gamma companding first, see http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html

Regards,

New Contributor I
3,041 Views

ping

Employee
3,041 Views

Sorry for long delay, but I still don't know what to reply. The IPP library has long history and the significant part of functions were implemented by some customer requests with fixed matrices of coefficients. It is not a really bug(crash, wrong result and so on). Adding new function to IPP requires some effort from our team(not big) and it means that we cannot add something else in next IPP release. Could you please estimate how it is important for software community to have these new optimized functions  ippiXYZtoLab, ippiLabToXYZ, ippiXYZtoLUV and ippiLUVtoXYZ?  Also what about new API ippiRGBToLab_Twist_8u_C3R(...,const Ipp32f twist[3][4])? May be it will be more appropriate?

Thanks.

New Contributor I
3,041 Views

Andrey,

In my software, I use a long list of IPP functions, among them

ippiRGBToHSV_xx

ippiRGBToHLS_xx

ippiRGBToXYZ_xx

ippiRGBToLUV_xx

ippiRGBToLab_xx

and

ippHSVtoRGB_xx

ippHLStoRGB_xx

ippXYZtoRGB_xx

ippLUVtoRGB_xx

ippLabtoRGB_xx

I relied on these functions doing what they suggest. However, I recently had a better look at the internals of color conversions. And discovered that some of the ippi functions do not do what they should do (or at least not what the docs and the function names suggest they do).

I think there are two possibilities

1. clearly document what the limitations of the current IPP functions are, by describing what they do and especially what they do not do

2. reorganise the IPP color conversion functions to something that is useful and makes sense

I think (1.) is absolute necessary, the documentation for the functions, as they are now, is misleading.

With regard to (2.) this is for Intel to decide. I can only say

- I would use the redesigned functions in my software

- the RGBToXYZ, RGBToLUV and RGBToLab conversions (and back) in the current form only make sense for HDVideo, not for still images

- the same is true for the curremt gamma correction functions in IPP, they only make sense for HDVideo, not for still images

As for the technical aspects

- RGB, HSV and HLS are device color spaces, so conversions between them are unproblematic

- XYZ, LUV, Lab and Yxy are device-independent color spaces, so conversions between them are unproblematic

- RGB to XYZ (and back) is very tricky. It is a device to device-indepent color conversion, dependent on the characteristics of the device, given by an ICC-profile, that is not always unambiguous http://www.argyllcms.com/doc/ArgyllCMS_arts_tag.html. Not to mention that ICC <http://www.color.org> is now promoting LUT-based profiles for workspace color space, which is completely nuts. Image editors, I think, use matrix-based workspaces internally. And not to mention color space white-point conversions, like from D65 to D50 .....

- besides, the conversion from RGB to XYZ requires gamma-corrected RGB, So, an un-gamma function must first be applied to the pixmap RGB. Such a function is (unfortunately) not part of IPP, the gamma function in IPP is for HD video only. Note that sRGB uses a special gamma function of its own <https://en.wikipedia.org/wiki/Gamma_correction>.

So, well, what can I say more to answer your question ? Please follow up if something is not clear. I will be pleased to help to describe or implement new functions or to correct the current documentation.

Regards,

New Contributor I
3,041 Views

Andrey,

The headers for ippiRGBToLUV, ippiLUVToRGB, ippiRGBToLab and ippiLabToRGB document that these conversions are a two step process, first from RGB to XYZ and then from XYZ to LUV or Lab. Same for the reverse operations. I can't look into the IPP source code, but this suggests that ippiXYZToLUV, ippiLUVToXYZ, ippiXYZToLab and ippiLabToXYZ are already part of the internals of IPP. If so, it would just be a matter of making these functions available as global calls.

Regards,