3. Color space conversion¶
Let try the online demo app!
The terminology and the way equations are constructed are detailed in the documentation.
The available gammas and gamuts are also detailed in the documentation. They come from International Telecommunication Union reports.
[1]:
import numpy as np
import sympy
import torch
from IPython.display import Math, display
import cutcutcodec
[2]:
src = cutcutcodec.Colorspace("y'pbpr", "smpte240m", "smpte240m")
dst = cutcutcodec.Colorspace("y'pbpr", "bt2020", "bt2020")
print(f"Source Colorspace: {src}")
print(f"Target Colorspace: {dst}")
Source Colorspace: Colorspace("y'pbpr", 'ntsc', 'smpte240m')
Target Colorspace: Colorspace("y'pbpr", 'bt2020', 'bt1361e, bt1361')
3.1. Symbolic conversions¶
This allows you to retrieve the passage equations
[3]:
steps = [ # details of each transition stage
src,
cutcutcodec.Colorspace("r'g'b'", src.primaries, src.transfer),
cutcutcodec.Colorspace("rgb", src.primaries),
cutcutcodec.Colorspace("xyz"),
cutcutcodec.Colorspace("rgb", dst.primaries),
cutcutcodec.Colorspace("r'g'b'", dst.primaries, dst.transfer),
dst,
]
for step_n, step_np1 in zip(steps[:-1], steps[1:]):
print(f"{step_n} -> {step_np1}")
eq = step_n.to_equation(step_np1)
display(Math(sympy.latex(eq)))
Colorspace("y'pbpr", 'ntsc', 'smpte240m') -> Colorspace("r'g'b'", 'ntsc', 'smpte240m')
$\displaystyle \left( \frac{430238494 p_{r}}{273127803} + y', \ - \frac{7623978355136 p_{b}}{33806856032607} - \frac{209727006492056 p_{r}}{439489128423891} + y', \ \frac{38383246 p_{b}}{21009831} + y'\right)$
Colorspace("r'g'b'", 'ntsc', 'smpte240m') -> Colorspace('rgb', 'ntsc')
$\displaystyle \left( \begin{cases} 0.25 r' & \text{for}\: r' \leq 0.09128634211778008882172239358977671184 \\\left(0.8996266762239280431763196027708491089 r' + 0.1003733237760719568236803972291508911\right)^{2.222222222222222222222222222222222222} & \text{otherwise} \end{cases}, \ \begin{cases} 0.25 g' & \text{for}\: g' \leq 0.09128634211778008882172239358977671184 \\\left(0.8996266762239280431763196027708491089 g' + 0.1003733237760719568236803972291508911\right)^{2.222222222222222222222222222222222222} & \text{otherwise} \end{cases}, \ \begin{cases} 0.25 b' & \text{for}\: b' \leq 0.09128634211778008882172239358977671184 \\\left(0.8996266762239280431763196027708491089 b' + 0.1003733237760719568236803972291508911\right)^{2.222222222222222222222222222222222222} & \text{otherwise} \end{cases}\right)$
Colorspace('rgb', 'ntsc') -> Colorspace('xyz')
$\displaystyle \left( \frac{4026032 b}{21009831} + \frac{99764014 g}{273127803} + \frac{35828814 r}{91042601}, \ \frac{1818208 b}{21009831} + \frac{191482543 g}{273127803} + \frac{58008556 r}{273127803}, \ \frac{20130160 b}{21009831} + \frac{30572843 g}{273127803} + \frac{1706134 r}{91042601}\right)$
Colorspace('xyz') -> Colorspace('rgb', 'bt2020')
$\displaystyle \left( \frac{21532150939 x}{12543355000} - \frac{4461219061 y}{12543355000} - \frac{3178002061 z}{12543355000}, \ - \frac{1976779337 x}{2965129750} + \frac{4793012913 y}{2965129750} + \frac{46755163 z}{2965129750}, \ \frac{79263327 x}{4492356500} - \frac{192186423 y}{4492356500} + \frac{4233267077 z}{4492356500}\right)$
Colorspace('rgb', 'bt2020') -> Colorspace("r'g'b'", 'bt2020', 'bt1361e, bt1361')
$\displaystyle \left( \begin{cases} 4.5 r & \text{for}\: r \leq 0.01805396851080780733586959258468773494 \\1.099296826809442940347282759215782542 r^{0.45} - 0.099296826809442940347282759215782542 & \text{otherwise} \end{cases}, \ \begin{cases} 4.5 g & \text{for}\: g \leq 0.01805396851080780733586959258468773494 \\1.099296826809442940347282759215782542 g^{0.45} - 0.099296826809442940347282759215782542 & \text{otherwise} \end{cases}, \ \begin{cases} 4.5 b & \text{for}\: b \leq 0.01805396851080780733586959258468773494 \\1.099296826809442940347282759215782542 b^{0.45} - 0.099296826809442940347282759215782542 & \text{otherwise} \end{cases}\right)$
Colorspace("r'g'b'", 'bt2020', 'bt1361e, bt1361') -> Colorspace("y'pbpr", 'bt2020', 'bt1361e, bt1361')
$\displaystyle \left( \frac{826593596 b'}{13942086899} + \frac{9452833643 g'}{13942086899} + \frac{3662659660 r'}{13942086899}, \ \frac{b'}{2} - \frac{859348513 g'}{2384635146} - \frac{166484530 r'}{1192317573}, \ - \frac{413296798 b'}{10279427239} - \frac{9452833643 g'}{20558854478} + \frac{r'}{2}\right)$
3.2. Numerical conversion¶
Offers more flexibility than the FilterVideoColorspace.
Compiled in C, this function optimizes cache and overhead.
[4]:
func = src.to_function(dst) # optimize the full chain
display(Math(str(func)))
$\displaystyle \begin{align}
\textbf{def}~f\left(u, v, y\right): \\
\quad x_0 \leftarrow 0.25 y \\
\quad x_1 \leftarrow 1.575227747868641553126687728674769884 v \\
\quad x_1 \leftarrow x_{1} + y \\
\quad x_1 \leftarrow x_{1} \leq 0.09128634211778008882172239358977671184 \\
\quad x_2 \leftarrow 0.8996266762239280431763196027708491089 y \\
\quad x_2 \leftarrow x_{2} + 0.1003733237760719568236803972291508911 \\
\quad x_3 \leftarrow 1.417116903110769752212105343075630963 v \\
\quad x_3 \leftarrow x_{2} + x_{3} \\
\quad x_3 \leftarrow x_{3}^{2.222222222222222222222222222222222222} \\
\quad x_4 \leftarrow 0.393806936967160388281671932168692471 v \\
\quad x_4 \leftarrow x_{0} + x_{4} \\
\quad x_4 \leftarrow \begin{cases} x_{4} & \text{for}\: x_{1} \\x_{3} & \text{otherwise} \end{cases} \\
\quad x_5 \leftarrow - x_{0} \\
\quad x_6 \leftarrow - y \\
\quad x_7 \leftarrow 0.4772063583101252952258757092198383568 v \\
\quad x_8 \leftarrow 0.2255157459120897865523043115836921751 u \\
\quad x_6 \leftarrow x_{6} + x_{7} + x_{8} \\
\quad x_6 \leftarrow x_{6} \geq -0.09128634211778008882172239358977671184 \\
\quad x_7 \leftarrow 0.8996266762239280431763196027708491089 y \\
\quad x_8 \leftarrow - 0.2028799809310532225771413906512419189 u \\
\quad x_9 \leftarrow - 0.4293075699994628824952572134562781054 v \\
\quad x_7 \leftarrow x_{7} + x_{8} + x_{9} + 0.1003733237760719568236803972291508911 \\
\quad x_7 \leftarrow x_{7}^{2.222222222222222222222222222222222222} \\
\quad x_8 \leftarrow - x_{5} \\
\quad x_9 \leftarrow - 0.1193015895775313238064689273049595892 v \\
\quad x_{10} \leftarrow - 0.05637893647802244663807607789592304378 u \\
\quad x_8 \leftarrow x_{8} + x_{9} + x_{10} \\
\quad x_8 \leftarrow \begin{cases} x_{8} & \text{for}\: x_{6} \\x_{7} & \text{otherwise} \end{cases} \\
\quad x_9 \leftarrow 1.826918360266677061800259126310916066 u \\
\quad x_9 \leftarrow x_{9} + y \\
\quad x_9 \leftarrow x_{9} \leq 0.09128634211778008882172239358977671184 \\
\quad x_{10} \leftarrow 1.643544492179179412130221165880667149 u \\
\quad x_{10} \leftarrow x_{2} + x_{10} \\
\quad x_{10} \leftarrow x_{10}^{2.222222222222222222222222222222222222} \\
\quad x_2 \leftarrow 0.4567295900666692654500647815777290165 u \\
\quad x_2 \leftarrow x_{0} + x_{2} \\
\quad x_2 \leftarrow \begin{cases} x_{2} & \text{for}\: x_{9} \\x_{10} & \text{otherwise} \end{cases} \\
\quad x_{11} \leftarrow x_{1} \wedge x_{6} \wedge x_{9} \\
\quad x_{12} \leftarrow 0.005616235079712466335963477384737015402 u \\
\quad x_{13} \leftarrow 0.1927478152272564917376197799690692823 v \\
\quad x_{14} \leftarrow x_{6} \wedge x_{9} \\
\quad x_{15} \leftarrow 0.5952701227710405783213474436823374812 x_{3} \\
\quad x_{16} \leftarrow - 0.04167368848927251101449620675513716215 v \\
\quad x_{16} \leftarrow x_{15} + x_{16} \\
\quad x_{17} \leftarrow x_{1} \wedge x_{9} \\
\quad x_{18} \leftarrow 0.02531017415011096215842454741477759892 u \\
\quad x_{19} \leftarrow 0.3493137739140495835481416592001061499 x_{7} \\
\quad x_{20} \leftarrow 0.2344215037165290027521159867242064444 v \\
\quad x_{20} \leftarrow x_{19} + x_{20} \\
\quad x_{15} \leftarrow x_{15} + x_{19} \\
\quad x_{19} \leftarrow x_{1} \wedge x_{6} \\
\quad x_{21} \leftarrow 0.05541610331490983813051089711755636883 x_{10} \\
\quad x_{22} \leftarrow - 0.01969393907039849582246107003004058352 u \\
\quad x_{22} \leftarrow x_{21} + x_{22} \\
\quad x_{23} \leftarrow 2.678715552469682602446063496570518666 x_{4} \\
\quad x_{24} \leftarrow 1.571911982613223125966637466400477675 x_{8} \\
\quad x_{25} \leftarrow 0.2493724649170942715872990370290036597 x_{2} \\
\quad x_{23} \leftarrow x_{23} + x_{24} + x_{25} \\
\quad x_{24} \leftarrow x_{0} + x_{12} + x_{13} \\
\quad x_{24} \leftarrow x_{24} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{25} \leftarrow 0.1011824693072398554196631390794156297 y \\
\quad x_{12} \leftarrow x_{12} + x_{16} + x_{25} \\
\quad x_{12} \leftarrow x_{12} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{25} \leftarrow 0.1626715565214876041129645851999734625 y \\
\quad x_{25} \leftarrow x_{18} + x_{20} + x_{25} \\
\quad x_{25} \leftarrow x_{25} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{26} \leftarrow 0.01385402582872745953262772427938909221 y \\
\quad x_{18} \leftarrow x_{15} + x_{18} + x_{26} \\
\quad x_{18} \leftarrow x_{18} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{26} \leftarrow 0.2361459741712725404673722757206109078 y \\
\quad x_{13} \leftarrow x_{13} + x_{22} + x_{26} \\
\quad x_{13} \leftarrow x_{13} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{26} \leftarrow 0.08732844347851239588703541480002653748 y \\
\quad x_{16} \leftarrow x_{16} + x_{22} + x_{26} \\
\quad x_{16} \leftarrow x_{16} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{22} \leftarrow 0.1488175306927601445803368609205843703 y \\
\quad x_{20} \leftarrow x_{20} + x_{21} + x_{22} \\
\quad x_{20} \leftarrow x_{20} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{15} \leftarrow x_{15} + x_{21} \\
\quad x_{15} \leftarrow x_{15} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{15} \leftarrow \operatorname{ITE}\left(x_{1}, x_{20}, x_{15}\right) \\
\quad x_{15} \leftarrow \operatorname{ITE}\left(x_{6}, x_{16}, x_{15}\right) \\
\quad x_{13} \leftarrow \operatorname{ITE}\left(x_{19}, x_{13}, x_{15}\right) \\
\quad x_{13} \leftarrow \operatorname{ITE}\left(x_{9}, x_{18}, x_{13}\right) \\
\quad x_{13} \leftarrow \operatorname{ITE}\left(x_{17}, x_{25}, x_{13}\right) \\
\quad x_{12} \leftarrow \operatorname{ITE}\left(x_{14}, x_{12}, x_{13}\right) \\
\quad x_{12} \leftarrow \operatorname{ITE}\left(x_{11}, x_{24}, x_{12}\right) \\
\quad x_{13} \leftarrow 0.3493137739140495835481416592001061499 x_{8} \\
\quad x_{15} \leftarrow 0.05541610331490983813051089711755636883 x_{2} \\
\quad x_{16} \leftarrow 0.5952701227710405783213474436823374812 x_{4} \\
\quad x_{13} \leftarrow x_{13} + x_{15} + x_{16} \\
\quad x_{13} \leftarrow x_{13}^{0.45} \\
\quad x_{13} \leftarrow 1.099296826809442940347282759215782542 x_{13} \\
\quad x_{13} \leftarrow x_{13} - 0.099296826809442940347282759215782542 \\
\quad x_{12} \leftarrow \begin{cases} x_{23} & \text{for}\: x_{12} \\x_{13} & \text{otherwise} \end{cases} \\
\quad x_{13} \leftarrow 0.07436298549573965448441799964934607902 v \\
\quad x_{15} \leftarrow 0.03781848215812902175715342131049288056 u \\
\quad x_{16} \leftarrow 0.0124438037631045686968790177159063483 u \\
\quad x_{18} \leftarrow 0.8915082309299459767548066740119863528 x_{7} \\
\quad x_{20} \leftarrow 0.03199536357565577701992240690343537089 v \\
\quad x_{20} \leftarrow x_{18} + x_{20} \\
\quad x_{21} \leftarrow 0.1063583490713954315043404065527814499 v \\
\quad x_{22} \leftarrow 0.08124631785834660030870500609373494137 x_{3} \\
\quad x_{18} \leftarrow x_{18} + x_{22} \\
\quad x_{23} \leftarrow 0.05026228592123359045403243902639922886 u \\
\quad x_{24} \leftarrow 0.02724545121170742293648831989427870584 x_{10} \\
\quad x_{25} \leftarrow 4.011787039184756895396630033053938588 x_{8} \\
\quad x_{26} \leftarrow 0.3656084303625597013891725274218072362 x_{4} \\
\quad x_{27} \leftarrow 0.1226045304526834032141974395242541763 x_{2} \\
\quad x_{27} \leftarrow x_{25} + x_{26} + x_{27} \\
\quad x_5 \leftarrow x_{5} + x_{13} + x_{15} \\
\quad x_5 \leftarrow x_{5} \geq -0.01805396851080780733586959258468773494 \\
\quad x_{25} \leftarrow 0.0271229422675135058112983314970034118 y \\
\quad x_{25} \leftarrow x_{16} + x_{20} + x_{25} \\
\quad x_{25} \leftarrow x_{25} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{26} \leftarrow - x_{22} \\
\quad x_{28} \leftarrow - 0.2296884205354133499228237484765662647 y \\
\quad x_{28} \leftarrow x_{15} + x_{21} + x_{26} + x_{28} \\
\quad x_{28} \leftarrow x_{28} \geq -0.01805396851080780733586959258468773494 \\
\quad x_{15} \leftarrow 0.006811362802926855734122079973569676459 y \\
\quad x_{15} \leftarrow x_{15} + x_{16} + x_{18} \\
\quad x_{15} \leftarrow x_{15} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{16} \leftarrow - x_{24} \\
\quad x_{26} \leftarrow - 0.2431886371970731442658779200264303235 y \\
\quad x_{13} \leftarrow x_{13} + x_{16} + x_{23} + x_{26} \\
\quad x_{13} \leftarrow x_{13} \geq -0.01805396851080780733586959258468773494 \\
\quad x_{16} \leftarrow 0.02031157946458665007717625152343373534 y \\
\quad x_{16} \leftarrow x_{16} + x_{20} + x_{24} \\
\quad x_{16} \leftarrow x_{16} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{20} \leftarrow - x_{21} \\
\quad x_{21} \leftarrow - x_{23} \\
\quad x_{23} \leftarrow 0.2228770577324864941887016685029965882 y \\
\quad x_{20} \leftarrow x_{20} + x_{21} + x_{22} + x_{23} + x_{24} \\
\quad x_{20} \leftarrow x_{20} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{18} \leftarrow x_{18} + x_{24} \\
\quad x_{18} \leftarrow x_{18} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{18} \leftarrow \operatorname{ITE}\left(x_{6}, x_{20}, x_{18}\right) \\
\quad x_{16} \leftarrow \operatorname{ITE}\left(x_{1}, x_{16}, x_{18}\right) \\
\quad x_{13} \leftarrow \operatorname{ITE}\left(x_{19}, x_{13}, x_{16}\right) \\
\quad x_{13} \leftarrow \operatorname{ITE}\left(x_{9}, x_{15}, x_{13}\right) \\
\quad x_{28} \leftarrow \operatorname{ITE}\left(x_{14}, x_{28}, x_{13}\right) \\
\quad x_{28} \leftarrow \operatorname{ITE}\left(x_{17}, x_{25}, x_{28}\right) \\
\quad x_{28} \leftarrow \operatorname{ITE}\left(x_{11}, x_{5}, x_{28}\right) \\
\quad x_5 \leftarrow 0.8915082309299459767548066740119863528 x_{8} \\
\quad x_{13} \leftarrow 0.08124631785834660030870500609373494137 x_{4} \\
\quad x_{15} \leftarrow 0.02724545121170742293648831989427870584 x_{2} \\
\quad x_5 \leftarrow x_{5} + x_{13} + x_{15} \\
\quad x_5 \leftarrow x_{5}^{0.45} \\
\quad x_5 \leftarrow 1.099296826809442940347282759215782542 x_{5} \\
\quad x_5 \leftarrow x_{5} - 0.099296826809442940347282759215782542 \\
\quad x_{27} \leftarrow \begin{cases} x_{27} & \text{for}\: x_{28} \\x_{5} & \text{otherwise} \end{cases} \\
\quad x_{28} \leftarrow 0.4076023144074993873444640152111481931 u \\
\quad x_5 \leftarrow 0.003664093591595216860355383337237092768 v \\
\quad x_{13} \leftarrow 0.004619273747905038815867694158849998107 u \\
\quad x_{10} \leftarrow 0.9025506494887533722687808235712819565 x_{10} \\
\quad x_{15} \leftarrow 0.006110597724791278555250393601747546687 v \\
\quad x_7 \leftarrow 0.0819326159106551655887679794018842299 x_{7} \\
\quad x_{16} \leftarrow 0.4122215881554044261603317093699981912 u \\
\quad x_{16} \leftarrow x_{7} + x_{16} \\
\quad x_7 \leftarrow x_{7} + x_{10} \\
\quad x_{18} \leftarrow 0.01551673460059146214245119702683381359 x_{3} \\
\quad x_{20} \leftarrow - 0.009774691316386495415605776938984639455 v \\
\quad x_{20} \leftarrow x_{18} + x_{20} \\
\quad x_{21} \leftarrow 4.061477922699390175209513706070768804 x_{2} \\
\quad x_{22} \leftarrow 0.06982530570266157964103038662075216118 x_{4} \\
\quad x_{23} \leftarrow 0.3686967715979482451494559073084790346 x_{8} \\
\quad x_{21} \leftarrow x_{21} + x_{22} + x_{23} \\
\quad x_{22} \leftarrow - x_{5} \\
\quad x_0 \leftarrow x_{0} + x_{22} + x_{28} \\
\quad x_0 \leftarrow x_{0} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{22} \leftarrow - x_{10} \\
\quad x_{23} \leftarrow - 0.02436233762781165693280479410717951087 y \\
\quad x_5 \leftarrow x_{5} + x_{13} + x_{22} + x_{23} \\
\quad x_5 \leftarrow x_{5} \geq -0.01805396851080780733586959258468773494 \\
\quad x_{22} \leftarrow 0.2295168460223362086028080051495289425 y \\
\quad x_{22} \leftarrow x_{15} + x_{16} + x_{22} \\
\quad x_{22} \leftarrow x_{22} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{23} \leftarrow 0.003879183650147865535612799256708453399 y \\
\quad x_{15} \leftarrow x_{7} + x_{15} + x_{23} \\
\quad x_{15} \leftarrow x_{15} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{23} \leftarrow 0.2461208163498521344643872007432915466 y \\
\quad x_{28} \leftarrow x_{20} + x_{23} + x_{28} \\
\quad x_{28} \leftarrow x_{28} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{13} \leftarrow - x_{13} \\
\quad x_{23} \leftarrow 0.02048315397766379139719199485047105748 y \\
\quad x_{10} \leftarrow x_{10} + x_{13} + x_{20} + x_{23} \\
\quad x_{10} \leftarrow x_{10} \leq 0.01805396851080780733586959258468773494 \\
\quad x_{13} \leftarrow 0.2256376623721883430671952058928204891 y \\
\quad x_{13} \leftarrow x_{13} + x_{16} + x_{18} \\
\quad x_{13} \leftarrow x_{13} \leq 0.01805396851080780733586959258468773494 \\
\quad x_7 \leftarrow x_{7} + x_{18} \\
\quad x_7 \leftarrow x_{7} \leq 0.01805396851080780733586959258468773494 \\
\quad x_7 \leftarrow \operatorname{ITE}\left(x_{9}, x_{13}, x_{7}\right) \\
\quad x_6 \leftarrow \operatorname{ITE}\left(x_{6}, x_{10}, x_{7}\right) \\
\quad x_{28} \leftarrow \operatorname{ITE}\left(x_{14}, x_{28}, x_{6}\right) \\
\quad x_1 \leftarrow \operatorname{ITE}\left(x_{1}, x_{15}, x_{28}\right) \\
\quad x_1 \leftarrow \operatorname{ITE}\left(x_{17}, x_{22}, x_{1}\right) \\
\quad x_1 \leftarrow \operatorname{ITE}\left(x_{19}, x_{5}, x_{1}\right) \\
\quad x_0 \leftarrow \operatorname{ITE}\left(x_{11}, x_{0}, x_{1}\right) \\
\quad x_1 \leftarrow 0.0819326159106551655887679794018842299 x_{8} \\
\quad x_{28} \leftarrow 0.9025506494887533722687808235712819565 x_{2} \\
\quad x_5 \leftarrow 0.01551673460059146214245119702683381359 x_{4} \\
\quad x_1 \leftarrow x_{1} + x_{5} + x_{28} \\
\quad x_1 \leftarrow x_{1}^{0.45} \\
\quad x_1 \leftarrow 1.099296826809442940347282759215782542 x_{1} \\
\quad x_1 \leftarrow x_{1} - 0.099296826809442940347282759215782542 \\
\quad x_0 \leftarrow \begin{cases} x_{21} & \text{for}\: x_{0} \\x_{1} & \text{otherwise} \end{cases} \\
\quad x_1 \leftarrow 0.2627052669039600712074144417509988725 x_{12} \\
\quad x_{28} \leftarrow 0.6780070811119393525736767106632850431 x_{27} \\
\quad x_5 \leftarrow 0.05928765198410057621890884758571608441 x_{0} \\
\quad x_1 \leftarrow x_{1} + x_{5} + x_{28} \\
\quad x_{28} \leftarrow 0.5 x_{0} \\
\quad x_5 \leftarrow - 0.1396310293247686621154916082076398282 x_{12} \\
\quad x_6 \leftarrow - 0.3603689706752313378845083917923601718 x_{27} \\
\quad x_{28} \leftarrow x_{5} + x_{6} + x_{28} \\
\quad x_5 \leftarrow 0.5 x_{12} \\
\quad x_{27} \leftarrow - 0.4597937911917934633089336856193296705 x_{27} \\
\quad x_0 \leftarrow - 0.04020620880820653669106631438067032949 x_{0} \\
\quad x_0 \leftarrow x_{0} + x_{5} + x_{27} \\
\quad x\_ \leftarrow \left( x_{1}, \ x_{28}, \ x_{0}\right) \\
\quad \textbf{return}~x\_
\end{align}$
[5]:
src_yuv = torch.rand(2160, 3840, 3)
src_yuv[..., 1:] -= 0.5
src_yuv *= 0.2 # valid range
[6]:
dst_y, dst_u, dst_v = func(y=src_yuv[..., 0], u=src_yuv[..., 1], v=src_yuv[..., 2])
dst_yuv = torch.cat([dst_y[..., None], dst_u[..., None], dst_v[..., None]], dim=-1)
3.3. Alternatives¶
[7]:
import timeit
import colour # pip install colour-science
[8]:
def colourscience_convert(src_yuv):
src_colourspace = colour.models.RGB_COLOURSPACE_SMPTE_240M
src_k = colour.WEIGHTS_YCBCR["SMPTE-240M"]
dst_colourspace = colour.models.RGB_COLOURSPACE_BT2020
dst_k = colour.WEIGHTS_YCBCR["ITU-R BT.2020"]
src_rgb = colour.YCbCr_to_RGB(src_yuv, src_k, in_range=(0.0, 1.0, -0.5, 0.5), out_range=(0.0, 1.0))
xyz = colour.RGB_to_XYZ(src_rgb, src_colourspace, apply_cctf_decoding=True)
dst_rgb = colour.XYZ_to_RGB(xyz, dst_colourspace, apply_cctf_encoding=True)
dst_yuv = colour.RGB_to_YCbCr(dst_rgb, dst_k, in_range=(0.0, 1.0), out_range=(0.0, 1.0, -0.5, 0.5))
return dst_yuv
dst_yuv_ = colourscience_convert(src_yuv.numpy(force=True))
[9]:
print(abs(dst_yuv[..., 2] - dst_yuv_[..., 2]).mean())
print(abs(dst_yuv[..., 2] - dst_yuv_[..., 2]).max())
/tmp/ipykernel_7812/2375015244.py:1: DeprecationWarning: __array_wrap__ must accept context and return_scalar arguments (positionally) in the future. (Deprecated NumPy 2.0)
print(abs(dst_yuv[..., 2] - dst_yuv_[..., 2]).mean())
tensor(3.3807e-05, dtype=torch.float64)
tensor(0.0001, dtype=torch.float64)
/tmp/ipykernel_7812/2375015244.py:2: DeprecationWarning: __array_wrap__ must accept context and return_scalar arguments (positionally) in the future. (Deprecated NumPy 2.0)
print(abs(dst_yuv[..., 2] - dst_yuv_[..., 2]).max())
[10]:
number = 5
time_cutcutcodec = timeit.repeat(lambda: func(y=src_yuv[..., 0], u=src_yuv[..., 1], v=src_yuv[..., 2]), number=number, repeat=7)
print(f"cutcutcodec convesion take {1000*np.median(time_cutcutcodec)/number:.2f} ms")
time_colourscience = timeit.repeat(lambda: colourscience_convert(src_yuv.numpy(force=True)), number=number, repeat=5)
print(f"colourscience convesion take {1000*np.median(time_colourscience)/number:.2f} ms")
print(f"cutcutcodec is {np.median(time_colourscience)/np.median(time_cutcutcodec)} times faster than colourscience")
cutcutcodec convesion take 1894.23 ms
colourscience convesion take 17219.00 ms
cutcutcodec is 9.09022393862781 times faster than colourscience