The OpenVX Specification  r28647
Color Convert

## Detailed Description

Implementes the Color Conversion Kernel.

This kernel converts an image of a designated vx_df_image_e format to another vx_df_image_e format for those combinations listed in the below table, where the columns are output types and the rows are input types. The API version first supporting the conversion is also listed.

I/O RGB RGBX NV12 NV21 UYVY YUYV IYUV YUV4
RGB 1.0 1.0 1.0 1.0
RGBX 1.0 1.0 1.0 1.0
NV12 1.0 1.0 1.0 1.0
NV21 1.0 1.0 1.0 1.0
UYVY 1.0 1.0 1.0 1.0
YUYV 1.0 1.0 1.0 1.0
IYUV 1.0 1.0 1.0 1.0
YUV4

The vx_df_image_e encoding, held in the VX_IMAGE_ATTRIBUTE_FORMAT attribute, describes the data layout. The interpretation of the colors is determined by the VX_IMAGE_ATTRIBUTE_SPACE (see vx_color_space_e) and VX_IMAGE_ATTRIBUTE_RANGE (see vx_channel_range_e) attributes of the image. OpenVX 1.0 implementations are required only to support images of VX_COLOR_SPACE_BT709 and VX_CHANNEL_RANGE_FULL.

If the channel range is defined as VX_CHANNEL_RANGE_FULL, the conversion between the real number and integer quantizations of color channels is defined for red, green, blue, and Y as:

$value_{real} = \frac{value_{integer}}{256.0}$

$value_{integer} = max(0, min(255, floor(value_{real} * 256.0)))$

For the U and V channels, the conversion between real number and integer quantizations is:

$value_{real} = \frac{(value_{integer} - 128.0)}{256.0}$

$value_{integer} = max(0, min(255, floor((value_{real} * 256.0) + 128)))$

If the channel range is defined as VX_CHANNEL_RANGE_RESTRICTED, the conversion between the integer quantizations of color channels and the continuous representations is defined for red, green, blue, and Y as:

$value_{real} = \frac{(value_{integer} - 16.0)}{219.0}$

$value_{integer} = max(0, min(255, floor((value_{real} * 219.0) + 16.5)))$

For the U and V channels, the conversion between real number and integer quantizations is:

$value_{real} = \frac{(value_{integer} - 128.0)}{224.0}$

$value_{integer} = max(0, min(255, floor((value_{real} * 224.0) + 128.5)))$

The conversions between nonlinear-intensity Y'PbPr and R'G'B' real numbers are:

$R' = Y' + 2(1-K_r)Pr$

$B' = Y' + 2(1-K_b)Pb$

$G' = Y' - \frac{2(K_r(1-K_r)Pr + K_b(1-K_b)Pb)}{1-K_r-K_b}$

$Y' = (K_r * R') + (K_b * B') + (1-K_r-K_b)G'$

$Pb = \frac{B'}{2} - \frac{(R' * K_r) + G'(1-K_r-K_b)}{2(1-K_b)}$

$Pr = \frac{R'}{2} - \frac{(B' * K_b) + G'(1-K_r-K_b)}{2(1-K_r)}$

The means of reconstructing Pb and Pr values from chroma-downsampled formats is implementation-defined.

In VX_COLOR_SPACE_BT601_525 or VX_COLOR_SPACE_BT601_625:

$K_r = 0.299$

$K_b = 0.114$

In VX_COLOR_SPACE_BT709:

$K_r = 0.2126$

$K_b = 0.0722$

In all cases, for the purposes of conversion, these colour representations are interpreted as nonlinear in intensity, as defined by the BT.601, BT.709, and sRGB specifications. That is, the encoded colour channels are nonlinear R', G' and B', Y', Pb, and Pr.

Each channel of the R'G'B' representation can be converted to and from a linear-intensity RGB channel by these formulae:

$value_{nonlinear} = 1.099 * {value_{linear}}^{0.45} - 0.099 \;\;\; for \;\;\; 1 \geq value_{linear} \geq 0.018$

$value_{nonlinear} = 4.500 * value_{linear} \;\;\; for \;\;\; 0.018 > value_{linear} \geq 0$

$value_{linear} = {\left(\frac{value_{nonlinear} + 0.099}{1.099}\right)}^\frac{1}{0.45} \;\;\; for \;\;\; 1 \geq value_{nonlinear} > 0.081$

$value_{linear} = \frac{value_{nonlinear}}{4.5} \;\;\; for \;\;\; 0.081 \geq value_{nonlinear} \geq 0$

As the different color spaces have different RGB primaries, a conversion between them must transform the color coordinates into the new RGB space. Working with linear RGB values, the conversion formulae are:

$R_{BT601\_525} = R_{BT601\_625} * 1.112302 + G_{BT601\_625} * -0.102441 + B_{BT601\_625} * -0.009860$

$G_{BT601\_525} = R_{BT601\_625} * -0.020497 + G_{BT601\_625} * 1.037030 + B_{BT601\_625} * -0.016533$

$B_{BT601\_525} = R_{BT601\_625} * 0.001704 + G_{BT601\_625} * 0.016063 + B_{BT601\_625} * 0.982233$

$R_{BT601\_525} = R_{BT709} * 1.065379 + G_{BT709} * -0.055401 + B_{BT709} * -0.009978$

$G_{BT601\_525} = R_{BT709} * -0.019633 + G_{BT709} * 1.036363 + B_{BT709} * -0.016731$

$B_{BT601\_525} = R_{BT709} * 0.001632 + G_{BT709} * 0.004412 + B_{BT709} * 0.993956$

$R_{BT601\_625} = R_{BT601\_525} * 0.900657 + G_{BT601\_525} * 0.088807 + B_{BT601\_525} * 0.010536$

$G_{BT601\_625} = R_{BT601\_525} * 0.017772 + G_{BT601\_525} * 0.965793 + B_{BT601\_525} * 0.016435$

$B_{BT601\_625} = R_{BT601\_525} * -0.001853 + G_{BT601\_525} * -0.015948 + B_{BT601\_525} * 1.017801$

$R_{BT601\_625} = R_{BT709} * 0.957815 + G_{BT709} * 0.042185$

$G_{BT601\_625} = G_{BT709}$

$B_{BT601\_625} = G_{BT709} * -0.011934 + B_{BT709} * 1.011934$

$R_{BT709} = R_{BT601\_525} * 0.939542 + G_{BT601\_525} * 0.050181 + B_{BT601\_525} * 0.010277$

$G_{BT709} = R_{BT601\_525} * 0.017772 + G_{BT601\_525} * 0.965793 + B_{BT601\_525} * 0.016435$

$B_{BT709} = R_{BT601\_525} * -0.001622 + G_{BT601\_525} * -0.004370 + B_{BT601\_525} * 1.005991$

$R_{BT709} = R_{BT601\_625} * 1.044043 + G_{BT601\_625} * -0.044043$

$G_{BT709} = G_{BT601\_625}$

$B_{BT709} = G_{BT601\_625} * 0.011793 + B_{BT601\_625} * 0.988207$

A conversion between one YUV color space and another may therefore consist of the following transformations:

1. Convert quantized Y'CbCr (“YUV”) to continuous, nonlinear Y'PbPr.
2. Convert continuous Y'PbPr to continuous, nonlinear R'G'B'.
3. Convert nonlinear R'G'B' to linear-intensity RGB (gamma-correction).
4. Convert linear RGB from the first color space to linear RGB in the second color space.
5. Convert linear RGB to nonlinear R'G'B' (gamma-conversion).
6. Convert nonlinear R'G'B' to Y'PbPr.
7. Convert continuous Y'PbPr to quantized Y'CbCr (“YUV”).

The above formulae and constants are defined in the ITU BT.601 and BT.709 specifications. The formulae for converting between RGB primaries can be derived from the specified primary chromaticity values and the specified white point by solving for the relative intensity of the primaries.

## Functions

vx_node vxColorConvertNode (vx_graph graph, vx_image input, vx_image output)
[Graph] Creates a color conversion node. More...

vx_status vxuColorConvert (vx_context context, vx_image input, vx_image output)
[Immediate] Invokes an immediate Color Conversion. More...

## Function Documentation

 vx_node vxColorConvertNode ( vx_graph graph, vx_image input, vx_image output )

[Graph] Creates a color conversion node.

Parameters
 [in] graph The reference to the graph. [in] input The input image from which to convert. [out] output The output image to which to convert.
VX_KERNEL_COLOR_CONVERT
Returns
vx_node.
Return values
 0 Node could not be created. * Node handle..
 vx_status vxuColorConvert ( vx_context context, vx_image input, vx_image output )

[Immediate] Invokes an immediate Color Conversion.

Parameters
 [in] context The reference to the overall context. [in] input The input image. [out] output The output image.
Returns
A vx_status_e enumeration.
Return values
 VX_SUCCESS Success * An error occurred. See vx_status_e.