question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG]: "colour.rgb_to_ycbcr" definition can give invalid answers for edge values.

See original GitHub issue

Description

rgb_to_ycbcr can give cb and cr values outside the defined out bit range when outputting to full range. If I feed it with 100% red the function return 1024 for the red channel, which is of course outside the range of 10 bits.

I believe that this is caused by these lines of code: ycbcr.py:147

    if is_int and not is_legal:
        ranges[3] = 2**bits

I think the fix would be just to remove these lines, but since it looks so intentional I’ll leave it to the maintainer.

Actually, thinking about it again, the correct solution would be to set ranges[2] to 1. Rec.2100, which addresses full range on page 10. https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-E.pdf

Which means my suggestion is that we should make this fix: ycbcr.py:147

    if is_int and not is_legal:
        ranges[2] = 1

Code for Reproduction

import colour

rgb = (1.0, 0, 0)
y, cb, cr = colour.RGB_to_YCbCr(rgb, in_int=False, in_legal=False, out_bits=10, out_legal=False, out_int=True)
print(y, cb, cr)
# >> 217 395 1024

Exception Message

No response

Environment Information

>>> import colour; colour.utilities.describe_environment()
===============================================================================
*                                                                             *
*   Interpreter :                                                             *
*       python : 3.9.6 (default, Sep 26 2022, 11:37:49)                       *
*                [Clang 14.0.0 (clang-1400.0.29.202)]                         *
*                                                                             *
*   colour-science.org :                                                      *
*       colour : 0.4.1                                                        *
*                                                                             *
*   Runtime :                                                                 *
*       imageio : 2.22.3                                                      *
*       numpy : 1.23.4                                                        *
*       scipy : 1.9.3                                                         *
*                                                                             *
===============================================================================
defaultdict(<class 'dict'>, {'Interpreter': {'python': '3.9.6 (default, Sep 26 2022, 11:37:49) \n[Clang 14.0.0 (clang-1400.0.29.202)]'}, 'colour-science.org': {'colour': '0.4.1'}, 'Runtime': {'imageio': '2.22.3', 'numpy': '1.23.4', 'scipy': '1.9.3'}})

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
nick-shawcommented, Nov 8, 2022

I have been experimenting with a modification which I think now accurately reflects the intent of ITU-T T.871.

You are right that BT.2100 also defines full range Y’CbCr. I had forgotten that. The quantisation function would appear to match that of ITU-T T.871, but defined for arbitrary bit depth n. I think my modified code is still therefore correct for this. I have also added a clamp_int argument, defaulting to True which clamps to the possible range for bit_depth integers. SDI reserved code value handling as mentioned in BT.2100 is “application specific” and would need to be dealt with in application specific code.

I am not confident that changing the range to 1 to (2**bits)-1 would yield correct answers in all cases. I have not tested either, but it feels intuitively as if there may be cases where the rounding would go in a different direction for some code values. 0.5 to 2**bits - 0.5 exactly matches the spec.

Edit: I also changed over to using the BT.2100 rounding function.

0reactions
KelSolaarcommented, Nov 11, 2022

Thank you @nick-shaw!

Read more comments on GitHub >

github_iconTop Results From Across the Web

ycbcr to rgb color conversion error on edge cases
I have some problems converting a rgb photo to ycbcbr, modifying the y channel and converting back to rgb, generally it works perfect...
Read more >
Color Models - Intel
The colors are the points on or inside the cube, defined by vectors extending from the origin. Thus, images in the RGB color...
Read more >
How To Fix STATUS_INVALID_IMAGE_HASH Microsoft Edge ...
... Microsoft Edge Browser Error Code Status Invalid Image Hash. ... invalid image hash chrome windows 10 This tutorial will apply for ...
Read more >
MATLAB rgb2ycbcr - MathWorks
This MATLAB function converts the red, green, and blue values of an RGB image to luminance (Y) and chrominance (Cb and Cr) values...
Read more >
Image Processing with Python - Data Carpentry
When we process images, we can access, examine, and / or change the colour of any pixel we wish. To do this, we...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found