Colour Gamut Expansion
Making HD content use the full colour range of a UHD screen. Research internship, Imaging Systems Lab, Changwon National University, South Korea, 2018.
Your TV is 4K/UHD and can show almost twice the colour range of HD, but most of what you watch is still mastered in HD, so the extra range sits unused. Gamut expansion pushes each pixel’s colour outward so the content fills the screen, keeping its hue and brightness. I implemented a published method, found why it barely changes real images, and fixed it with one extra parameter, β.
Try it
Pick an image, then move α and β. Drag the divider on the image to compare. Everything runs in your browser; uploaded photos never leave your device.
- Pixels expanded
- –
- Mean saturation gain
- –
- UHD gamut in use
- –
The problem
A display can only show colours inside its gamut, the triangle formed by its red, green and blue primaries on the CIE 1931 chromaticity diagram. HD uses BT.709; UHD uses BT.2020, which covers about 1.9× the area. HD content on a UHD panel stays inside the small triangle, leaving almost half of the panel’s colour unused.
The published method
Azimi et al. (IEEE ICC 2017) move each pixel along the line from the white point through its own colour, so hue never changes. Colours inside an inner gamut (HD scaled by α) stay put to protect skin tones and neutrals; everything outside it is stretched to the UHD border:
x = xm + (D − d) · (xm − dα) / (d − dα), with dα = α · d
Here xm is the pixel’s distance from the white point, and D and d are the distances to the UHD and HD borders along the same line.
What I changed
Real images sit in a small cloud near the white point, far inside the HD border. So almost no pixel lies outside the inner gamut until α drops below about 0.6, and the pixels that do move are measured against the full HD distance d, so they barely shift.
I added β, which shrinks the reference HD gamut towards the white point until it hugs the image’s own colours, and used this β·HD gamut in place of HD everywhere:
dβ = (1 − β) · d dα = α · dβ x = xm + (D − dβ) · (xm − dα) / (dβ − dα)
With β = 0 it is exactly the published method. With β > 0, every α does something, expansion is several times stronger, and colours spread more evenly towards the UHD border. I presented the results to the lab and Korean graduate students, and a paper was submitted to IET Electronics Letters (2018).
Details
- Where: International research internship, Imaging Systems Lab, Changwon National University, South Korea, May–July 2018, funded by the Government of South Korea, under Prof. Oh-Seol Kwon.
- Built with: MATLAB (original research code); Python/NumPy reference implementation; this page recreates the algorithm in JavaScript.
- Code: github.com/cyberdrk/Color, with the MATLAB scripts, Python port, figures and full write-up.
- Test images: Kodak Lossless True Color Image Suite and a standard ski-scene colour test image.