Skip to content

Conversation

@kimikage
Copy link
Collaborator

@kimikage kimikage commented May 5, 2021

This is a proposed update based on the changes planned for ColorTypes v0.12. (see PR #251)
I think the update should be merged at the final stage of the releasing, since the documentation for ColorTypes (i.e. README.md) is always published in the development. On the other hand, we can apply the parts which are not related to the changes in v0.12 successively.

The important thing is to clarify the default colorspace for YIQ and YCbCr.

xref: JuliaGraphics/Colors.jl#453
xref: https://discourse.julialang.org/t/what-should-the-default-color-space-for-ycbcr-be/60874

Closes #10, Closes #30

@kimikage kimikage added this to the 0.12 milestone May 5, 2021
@codecov

This comment has been minimized.

@kimikage
Copy link
Collaborator Author

kimikage commented May 6, 2021

Default color space and scaling for YCbCr

The transfer function here refers to the one used in the RGB<-->YCbCr conversions.
Note that it does not indicate the property of the RGB colorspace specified by the standards (e.g. ITU-R Recommendation BT.709).

Candidate Color primaries Transfer func. (gamma) Matrix Luma range Chroma range
status quo 8-bit sRGB/Rec.709 - Rec.601 [16, 235] [16, 240]
normalized (a) sRGB/Rec.709 - Rec.601 [0.06, 0.92] [-0.44, 0.44]
normalized (b) sRGB/Rec.709 - Rec.601 [0.06, 0.92] [0.06, 0.94]
JPEG 8-bit sRGB/Rec.709 - Rec.601 [0, 255] [0, 255]
JPEG (a) sRGB/Rec.709 - Rec.601 [0, 1] [-0.5, 0.5]
JPEG (b) sRGB/Rec.709 - Rec.601 [0, 1] [0, 1]
sYCC w/o correction 8-bit sRGB/Rec.709 - Rec.601 [0, 255] [0, 255]
sYCC w/o correction (a) sRGB/Rec.709 - Rec.601 [0, 1] [-0.5, 0.5]
sYCC w/o correction (b) sRGB/Rec.709 - Rec.601 [0, 1] [0, 1]
sYCC w/ correction 8-bit sRGB/Rec.709 w/ measure correction Rec.601 [3.2, 255] [0, 255]
sYCC w/ correction (a) sRGB/Rec.709 w/ measure correction Rec.601 [0.0125, 1] [-0.5, 0.5]
sYCC w/ correction (b) sRGB/Rec.709 w/ measure correction Rec.601 [0.0125, 1] [0, 1]
(linearRGB) Rec.709 8-bit sRGB/Rec.709 - Rec.709 [16, 235] [16, 240]
(linearRGB) Rec.709 (a) sRGB/Rec.709 - Rec.709 [0.06, 0.92] [-0.44, 0.44]
(linearRGB) Rec.709 (b) sRGB/Rec.709 - Rec.709 [0.06, 0.92] [0.06, 0.94]
(sRGB) Rec.709 8-bit sRGB/Rec.709 sRGB (~2.2) Rec.709 [16, 235] [16, 240]
(sRGB) Rec.709 (a) sRGB/Rec.709 sRGB (~2.2) Rec.709 [0.06, 0.92] [-0.44, 0.44]
(sRGB) Rec.709 (b) sRGB/Rec.709 sRGB (~2.2) Rec.709 [0.06, 0.92] [0.06, 0.94]
Rec.709 8-bit sRGB/Rec.709 Rec.709 (~1.9) Rec.709 [16, 235] [16, 240]
Rec.709 (a) sRGB/Rec.709 Rec.709 (~1.9) Rec.709 [0.06, 0.92] [-0.44, 0.44]
Rec.709 (b) sRGB/Rec.709 Rec.709 (~1.9) Rec.709 [0.06, 0.92] [0.06, 0.94]
Rec.1886 10-bit sRGB/Rec.709 Rec.1886 (~2.4) Rec.709 [64, 940] [64, 960]
Rec.1886 (a) sRGB/Rec.709 Rec.1886 (~2.4) Rec.709 [0.06, 0.92] [-0.44, 0.44]
Rec.1886 (b) sRGB/Rec.709 Rec.1886 (~2.4) Rec.709 [0.06, 0.92] [0.06, 0.94]

Other possible candidates are Rec.601 and Rec.2020, but I don't think they are good because their color primaries are different from sRGB.
There are also some weird profiles which claim to be "Rec.709" but use the gamma of 2.2. Of course, they only make things worse. 😅 (The meaning is different from that of "(sRGB) Rec.709" above. The goal is the same, though.)

I also don't like the encoding for 8-bit. It makes sense within UInt8. The relaxation to YCbCr{T <: Fractional} can be done in v0.12, but The relaxation to YCbCr{T <: Real} should wait until v0.13. I recommend keeping the status quo "if" there is no support for scaling changes.

@kimikage
Copy link
Collaborator Author

kimikage commented May 6, 2021

Default color space for YIQ

Candidate Color primaries Transfer func. (gamma) Setup
status quo sRGB - 0 IRE
sRGB w/o setup sRGB sRGB (~2.2) 0 IRE
sRGB w/ setup sRGB sRGB (~2.2) 7.5 IRE
SMPTE C w/o setup SMPTE 170M SMPTE 170M (~1.9) 0 IRE
NTSC (1953) w/o setup NTSC (1953) NTSC (2.2) 0 IRE
NTSC (1953) w/ setup NTSC (1953) NTSC (2.2) 7.5 IRE

NTSC (1953) is sometimes used as a reference for color gamut coverage, but I don't think it is used in an actual video signal anymore.
SMPTE C (SMPTE 170M) is close to sRGB, so we could either ignore the difference or apply a simple correction.

Adding the setup of 7.5 IRE means that areas where Y < 0.075 will be blacked out in RGB space. Perceptually, the impact of the setup is minor, but this is troubling given that YIQ is used in ImageContrastAdjustment. 😕
xref: JuliaImages/ImageContrastAdjustment.jl#48

Edit:
I don't have enough knowledge about SMPTE 170M, but it seems that at least in SMPTE 170M-2004, the setup is applied after the RGB-->YIQ conversion is done. In other words, if SMPTE 170M is selected, no setup is required (i.e. 0 IRE).

Also, if it involves changing color primaries, it does not directly matter what the transfer function is, since the conversion is done in the XYZ space.
sRGB --> linearRGB (sRGB) --> XYZ --> linearRGB (NTSC) --> NTSC RGB --> linearRGB (NTSC) --> YIQ

cf. JuliaGraphics/Colors.jl#372 (comment)

@kimikage
Copy link
Collaborator Author

kimikage commented May 10, 2021

As for YIQ, I think there are few situations where the SMPTE 170M compliant conversion is needed, so I'll keep the current "gamma-ignoring" implementation of Colors.jl and clarify the documentations.

This preserves the compatibility in ImageContrastAdjustment.jl. On the other hand, I am unhappy that the gamma is not accurately taken into account. 😕

@galenlynch
Copy link

Is the status quo linear gamma? it's been a bit since I've thought about this, but I thought YCbCr was just a transformation of some RGB color space with a particular color matrix, and since most commonly used RGB color spaces use gamma (e.g. sRGB which I think is what ColorTypes.jl uses?) then that gamma goes along for the ride in a YCbCr representation of that same color space.

@kimikage
Copy link
Collaborator Author

kimikage commented May 10, 2021

You are right. In fact, I used to indicate "gamma: ~2.2" for them. Edit: I changed it back to the original notation. However, it is still not exact either.
However, in the comparison, it is difficult to distinguish whether the transfer function of gamma 2.2 is applied like in sYCC, so I wrote "linear" to mean that the transfer function is not applied.

@kimikage
Copy link
Collaborator Author

kimikage commented May 11, 2021

The meaning of the transfer function was clarified, and as a result, the Rec. 709 series was divided into three groups.

  • (linearRGB) Rec.709
    • RGB as linear RGB
  • (sRGB) Rec.709
    • RGB as sRGB
  • Rec.709
    • RGB as Rec.709 RGB

@kimikage
Copy link
Collaborator Author

kimikage commented Apr 6, 2024

Perhaps we need to come back here, but for once let's forget about it.
I think this is no longer the appropriate place to discuss the YCbCr etc.

@kimikage kimikage closed this Apr 6, 2024
@kimikage kimikage deleted the readme_v0.12 branch April 6, 2024 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XYZ representation Problems with creating 10bit version of YCbCr

2 participants