[BUG]: "colour.rgb_to_ycbcr" definition can give invalid answers for edge values.
See original GitHub issueIssue Description
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:
- Created 4 months ago
- Comments:7 (5 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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 toTrue
which clamps to the possible range forbit_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.
Thank you @nick-shaw!