-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathindex.html
More file actions
7 lines (7 loc) · 202 KB
/
index.html
File metadata and controls
7 lines (7 loc) · 202 KB
1
2
3
4
5
6
7
<!DOCTYPE html><html domain="github.io" lang="en"><head><meta charset="utf-8"><meta content="width=device-width,initial-scale=1" name="viewport"><meta content="default-src 'self' ; object-src 'none' ; style-src 'unsafe-inline' ; img-src 'self' ; connect-src 'self' https://cloudflareinsights.com ; script-src 'self' 'sha256-Ky9qZOPnMhQV/s7Fdb9TYAOfU4KtWNqCZaFK8tSzXa0=' 'sha256-ktarjbJmNtF8IylbwgjSQoKrcQSdXJkqf60bj4nusHA=' https://static.cloudflareinsights.com" http-equiv="Content-Security-Policy"><link href="/img/favicon/favicon-32x32.png?hash=d763fc1b07" rel="icon" sizes="32x32" type="image/png"><link href="/img/favicon/favicon-16x16.png?hash=ee8f8c9160" rel="icon" sizes="16x16" type="image/png"><link href="/img/favicon/favicon-192x192.png?hash=98293e6f87" rel="icon" sizes="192x192" type="image/png"><link href="/img/favicon/favicon-192x192.png?hash=98293e6f87" rel="icon" sizes="512x512" type="image/png"><link href="/img/favicon/apple-touch-icon.png?hash=624ca04e47" rel="apple-touch-icon" sizes="180x180"><meta content="#FFFFFF" name="theme-color"><meta content="max-snippet:-1, max-image-preview: large, max-video-preview: -1" name="robots"><title>A perceptual color space for image processing</title><meta content="A perceptual color space for image processing" property="og:title"><meta content="A perceptual color space for image processing A perceptual color space is desirable when doing many kinds of image processing. It is useful..." name="description"><meta content="A perceptual color space for image processing A perceptual color space is desirable when doing many kinds of image processing. It is useful..." property="og:description"><meta content="@bjornornorn" name="twitter:site"><meta content="@bjornornorn" name="twitter:creator"><link href="https://bottosson.github.io/posts/oklab/" rel="canonical"><meta content="no-referrer-when-downgrade" name="referrer"><link href="/feed/feed.xml" rel="alternate" type="application/atom+xml" title="Björn Ottosson"><link href="/" rel="preconnect" crossorigin=""><script defer="" src="/js/min.js?hash=b945678541" async=""></script><script defer="" src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{"token": "337ad83ce1ba4683a5142d6291735976"}"></script><script csp-hash="sha256-Ky9qZOPnMhQV/s7Fdb9TYAOfU4KtWNqCZaFK8tSzXa0=">if (/Mac OS X/.test(navigator.userAgent))document.documentElement.classList.add('apple')</script><style>.content img{display:block;margin-left:auto;margin-right:auto}main img{content-visibility:auto}header nav{z-index:1}:root{--main-width: calc(100vw - 3em)}@media (min-width:37.5em){:root{--main-width: calc(37.5em - 3em)}}#posts li{margin-bottom:.5em}.anchor-link{fill:#d9d9d9;stroke:none}.anchor-link:active,.anchor-link:hover{fill:#4a4a4a}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}button,hr{overflow:visible}hr{box-sizing:content-box;height:0}code,pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}b,strong{font-weight:bolder}img{border-style:none}button{font-family:inherit;font-size:100%;line-height:1.15;margin:0;text-transform:none}[type=button],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}
/*! bulma.io v0.9.1 | MIT License | github.com/jgthms/bulma */
@-webkit-keyframes spinAround{0%{transform:rotate(0deg)}to{transform:rotate(359deg)}}@keyframes spinAround{0%{transform:rotate(0deg)}to{transform:rotate(359deg)}}.button{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding:calc(.5em - 1px) calc(.75em - 1px);position:relative;vertical-align:top}.content:not(:last-child),.table:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.button:active,.button:focus,.is-active.button{outline:0}
/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */
@-webkit-keyframes moveIndeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}blockquote,body,h1,h2,h3,h4,h5,hr,html,li,p,pre,ul{margin:0;padding:0}h1,h2,h3,h4,h5{font-size:100%;font-weight:400}ul{list-style:none}button{margin:0}html{box-sizing:border-box;background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}*,::after,::before{box-sizing:inherit}img{height:auto;max-width:100%}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.content table th:not([align]),table td:not([align]),table th:not([align]),td:not([align]),th:not([align]){text-align:inherit}article,header,section{display:block}body,button{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue","Helvetica","Arial",sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body,code{font-weight:400}body{color:#4a4a4a;font-size:1em;line-height:1.5}a{color:#3273dc;cursor:pointer;text-decoration:none}a strong,pre code{color:currentColor}code{color:#da1039;font-size:.875em;padding:.25em .5em}code,hr,pre{background-color:#f5f5f5}hr{border:0;display:block;height:2px;margin:1.5rem 0}span{font-style:inherit;font-weight:inherit}strong{font-weight:700}pre{-webkit-overflow-scrolling:touch;color:#4a4a4a;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;font-size:1em;padding:0}table td,table th{vertical-align:top}.button,a:hover,strong,table th{color:#363636}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;cursor:pointer;justify-content:center;padding-bottom:calc(.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.5em - 1px);margin-right:calc(-.5em - 1px)}.button:hover{border-color:#b5b5b5;color:#363636}.button:focus{border-color:#3273dc;color:#363636}.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-white,.button.is-white:hover{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white:hover{background-color:#f9f9f9}.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-small{border-radius:2px;font-size:.75rem}.button.is-medium{font-size:1.25rem}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}@media screen and (min-width:1024px){.container{max-width:960px}}@media screen and (min-width:1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width:1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}.content li+li{margin-top:.25em}.content blockquote:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.8888em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:.5em}.content ul ul ul{list-style-type:square}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:1.25em 1.5em;white-space:pre;word-wrap:normal}.content table{width:100%}.content table td,.content table th,.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th,.table th{color:#363636}.content table thead td,.content table thead th,.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.content table tbody tr:last-child td,.content table tbody tr:last-child th,.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.content.is-small{font-size:.75rem}.content.is-medium{font-size:1.25rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.table{background-color:#fff;color:#363636}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table th:not([align]){text-align:inherit}.table tbody,.table thead{background-color:transparent}.title{word-break:break-word;color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title em,.title span,.title strong{font-weight:inherit}.title strong{color:inherit}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand>.navbar-item,.navbar.is-white .navbar-burger{color:#0a0a0a}.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}@media screen and (min-width:1024px){.navbar.is-white .navbar-end>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}}.navbar-brand,.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem}.navbar>.container{width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30;top:0}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}.navbar-brand{flex-shrink:0}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-burger{color:#4a4a4a;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color,opacity,transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,.05)}.navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item{color:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative;flex-grow:0;flex-shrink:0}.navbar-item .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}a.navbar-item{cursor:pointer}a.navbar-item.is-active,a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover{background-color:#fafafa;color:#3273dc}.navbar-item img{max-height:1.75rem}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#3273dc}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#3273dc;border-bottom-style:solid;border-bottom-width:3px;color:#3273dc;padding-bottom:calc(.5rem - 3px)}@media screen and (max-width:1023px){.navbar>.container{display:block}.navbar-brand .navbar-item{align-items:center;display:flex}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,.1);padding:.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-top .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}}@media screen and (min-width:1024px){.navbar,.navbar-end,.navbar-menu{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar-burger{display:none}.navbar-item{align-items:center;display:flex}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-end{justify-content:flex-end;margin-left:auto}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .navbar-menu{margin-right:-.75rem}a.navbar-item.is-active{color:#0a0a0a}a.navbar-item.is-active:not(:focus):not(:hover){background-color:transparent}}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}@media screen and (min-width:769px),print{.columns:not(.is-desktop){display:flex}}.has-background-white-ter{background-color:#f5f5f5!important}.is-size-3{font-size:2rem!important}.is-size-5{font-size:1.25rem!important}.has-text-weight-semibold{font-weight:600!important}.section{padding:3rem 1.5rem}@media screen and (min-width:1024px){.section.is-medium{padding:9rem 1.5rem}}@font-face{font-family:KaTeX_Main;src:url(/fonts/KaTeX_Main-Bold.eot);src:url(/fonts/KaTeX_Main-Bold.eot#iefix) format('embedded-opentype'),url(/fonts/KaTeX_Main-Bold.woff2) format('woff2'),url(/fonts/KaTeX_Main-Bold.woff) format('woff'),url(/fonts/KaTeX_Main-Bold.ttf) format('ttf');font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(/fonts/KaTeX_Main-Italic.eot);src:url(/fonts/KaTeX_Main-Italic.eot#iefix) format('embedded-opentype'),url(/fonts/KaTeX_Main-Italic.woff2) format('woff2'),url(/fonts/KaTeX_Main-Italic.woff) format('woff'),url(/fonts/KaTeX_Main-Italic.ttf) format('ttf');font-weight:400;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(/fonts/KaTeX_Main-Regular.eot);src:url(/fonts/KaTeX_Main-Regular.eot#iefix) format('embedded-opentype'),url(/fonts/KaTeX_Main-Regular.woff2) format('woff2'),url(/fonts/KaTeX_Main-Regular.woff) format('woff'),url(/fonts/KaTeX_Main-Regular.ttf) format('ttf');font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Math;src:url(/fonts/KaTeX_Math-Italic.eot);src:url(/fonts/KaTeX_Math-Italic.eot#iefix) format('embedded-opentype'),url(/fonts/KaTeX_Math-Italic.woff2) format('woff2'),url(/fonts/KaTeX_Math-Italic.woff) format('woff'),url(/fonts/KaTeX_Math-Italic.ttf) format('ttf');font-weight:400;font-style:italic}@font-face{font-family:KaTeX_Size1;src:url(/fonts/KaTeX_Size1-Regular.eot);src:url(/fonts/KaTeX_Size1-Regular.eot#iefix) format('embedded-opentype'),url(/fonts/KaTeX_Size1-Regular.woff2) format('woff2'),url(/fonts/KaTeX_Size1-Regular.woff) format('woff'),url(/fonts/KaTeX_Size1-Regular.ttf) format('ttf');font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size4;src:url(/fonts/KaTeX_Size4-Regular.eot);src:url(/fonts/KaTeX_Size4-Regular.eot#iefix) format('embedded-opentype'),url(/fonts/KaTeX_Size4-Regular.woff2) format('woff2'),url(/fonts/KaTeX_Size4-Regular.woff) format('woff'),url(/fonts/KaTeX_Size4-Regular.ttf) format('ttf');font-weight:400;font-style:normal}.katex-display{display:block;margin:1em 0;text-align:center}.katex .katex-html,.katex-display>.katex{display:inline-block}.katex{font:400 1.21em KaTeX_Main;line-height:1.2;white-space:nowrap;text-indent:0}.katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .base,.katex .strut{display:inline-block}.katex .mathit{font-family:KaTeX_Math;font-style:italic}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .textstyle>.mord+.mop{margin-left:.16667em}.katex .textstyle>.mord+.mbin{margin-left:.22222em}.katex .textstyle>.mord+.mrel{margin-left:.27778em}.katex .textstyle>.mop+.mop,.katex .textstyle>.mop+.mord,.katex .textstyle>.mord+.minner{margin-left:.16667em}.katex .textstyle>.mop+.mrel{margin-left:.27778em}.katex .textstyle>.mop+.minner{margin-left:.16667em}.katex .textstyle>.mbin+.minner,.katex .textstyle>.mbin+.mop,.katex .textstyle>.mbin+.mopen,.katex .textstyle>.mbin+.mord{margin-left:.22222em}.katex .textstyle>.mrel+.minner,.katex .textstyle>.mrel+.mop,.katex .textstyle>.mrel+.mopen,.katex .textstyle>.mrel+.mord{margin-left:.27778em}.katex .textstyle>.mclose+.mop{margin-left:.16667em}.katex .textstyle>.mclose+.mbin{margin-left:.22222em}.katex .textstyle>.mclose+.mrel{margin-left:.27778em}.katex .textstyle>.mclose+.minner,.katex .textstyle>.minner+.mop,.katex .textstyle>.minner+.mord,.katex .textstyle>.mpunct+.mclose,.katex .textstyle>.mpunct+.minner,.katex .textstyle>.mpunct+.mop,.katex .textstyle>.mpunct+.mopen,.katex .textstyle>.mpunct+.mord,.katex .textstyle>.mpunct+.mpunct,.katex .textstyle>.mpunct+.mrel{margin-left:.16667em}.katex .textstyle>.minner+.mbin{margin-left:.22222em}.katex .textstyle>.minner+.mrel{margin-left:.27778em}.katex .mclose+.mop,.katex .minner+.mop,.katex .mop+.mop,.katex .mop+.mord,.katex .mord+.mop,.katex .textstyle>.minner+.minner,.katex .textstyle>.minner+.mopen,.katex .textstyle>.minner+.mpunct{margin-left:.16667em}.katex .reset-textstyle.textstyle{font-size:1em}.katex .reset-textstyle.scriptstyle{font-size:.7em}.katex .fontsize-ensurer.reset-size5.size1,.katex .reset-textstyle.scriptscriptstyle,.katex .sizing.reset-size5.size1{font-size:.5em}.katex .reset-scriptstyle.textstyle{font-size:1.42857em}.katex .fontsize-ensurer.reset-size5.size5,.katex .reset-scriptstyle.scriptstyle,.katex .sizing.reset-size5.size5{font-size:1em}.katex .reset-scriptstyle.scriptscriptstyle{font-size:.71429em}.katex .style-wrap{position:relative}.katex .fontsize-ensurer,.katex .mspace,.katex .sizing,.katex .vlist,.katex .vlist>span>span{display:inline-block}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist .baseline-fix{display:inline-table;table-layout:fixed}.katex .mfrac>span>span,.katex .mtable .col-align-c>.vlist{text-align:center}.katex .mfrac .frac-line{width:100%}.katex .mfrac .frac-line:after,.katex .mfrac .frac-line:before{border-bottom-style:solid;border-bottom-width:1px;content:"";display:block}.katex .mfrac .frac-line:after{border-bottom-width:.04em;margin-top:-1px}.katex .mspace.qquad{width:2em}.katex .sqrt>.sqrt-sign{position:relative}.katex .sqrt .sqrt-line{width:100%}.katex .sqrt .sqrt-line:after,.katex .sqrt .sqrt-line:before{border-bottom-style:solid;border-bottom-width:1px;content:"";display:block}.katex .sqrt .sqrt-line:after{border-bottom-width:.04em;margin-top:-1px}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .mtable .arraycolsep{display:inline-block}.resp-sharing-button__icon{stroke:#fff;fill:none}.resp-sharing-button__icon--solid{fill:#fff;stroke:none}.resp-sharing-button--hackernews:focus,.resp-sharing-button--hackernews:hover{background-color:#fb6200}.resp-sharing-button--facebook{background-color:#3b5998;border-color:#3b5998}.resp-sharing-button--facebook:active,.resp-sharing-button--facebook:hover{background-color:#2d4373;border-color:#2d4373}.resp-sharing-button--twitter{background-color:#55acee;border-color:#55acee}.resp-sharing-button--twitter:active,.resp-sharing-button--twitter:hover{background-color:#2795e9;border-color:#2795e9}.resp-sharing-button--email{background-color:#777;border-color:#777}.resp-sharing-button--email:active,.resp-sharing-button--email:hover{background-color:#5e5e5e;border-color:#5e5e5e}.resp-sharing-button--linkedin{background-color:#0077b5;border-color:#0077b5}.resp-sharing-button--linkedin:active,.resp-sharing-button--linkedin:hover{background-color:#046293;border-color:#046293}.resp-sharing-button--reddit{background-color:#5f99cf;border-color:#5f99cf}.resp-sharing-button--reddit:active,.resp-sharing-button--reddit:hover{background-color:#3a80c1;border-color:#3a80c1}.resp-sharing-button--hackernews{background-color:#f60;border-color:#f60}.resp-sharing-button--hackernews:hover .resp-sharing-button--hackernews:active{background-color:#fb6200;border-color:#fb6200}code[class*=language-],pre[class*=language-]{color:#5c6e74;font-size:13px;text-shadow:none;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::mozselection,code[class*=language-]::selection,pre[class*=language-]::mozselection,pre[class*=language-]::selection{text-shadow:none}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}.token.punctuation{color:#999}.token.constant,.token.number,.token.property{color:#905}.token.inserted{color:#690}.token.operator,.token.url{color:#a67f59}.token.keyword{color:#07a}.token.function{color:#dd4a68}.token.important{color:#e90;font-weight:700}.token.bold{font-weight:700}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}</style></head><body class="has-navbar-fixed-top"><header class="container is-max-desktop"><nav class="has-shadow is-fixed-top navbar"><div class="container"><div class="navbar-brand"><a href="/" class="navbar-item has-text-weight-semibold is-size-3">Björn Ottosson </a><a class="navbar-burger" data-target="navMenu" role="button"><span></span> <span></span> <span></span></a></div><div class="navbar-menu" id="navMenu"><div class="is-active navbar-end"><a href="/" class="navbar-item has-text-weight-semibold is-size-5 is-tab">Blog </a><a href="/about/" class="navbar-item has-text-weight-semibold is-size-5 is-tab">About</a><div class="navbar-item"><div class="buttons"><a href="https://twitter.com/bjornornorn" class="is-small button is-white" rel="noopener" target="_blank"><span class="icon"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24" role="img"><title>Twitter icon</title><path d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z" style="fill:hsl(0, 0%, 29%)"></path></svg> </span></a><a href="https://www.linkedin.com/in/bjorn-ottosson" class="is-small button is-white" rel="noopener" target="_blank"><span class="icon"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24" role="img"><title>LinkedIn icon</title><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" style="fill:hsl(0, 0%, 29%)"></path></svg></span></a></div></div></div></div></div></nav></header><main class="container is-max-desktop"><article class="section"><div class="content is-medium"><h1 id="a-perceptual-color-space-for-image-processing">A perceptual color space for image processing <a href="#a-perceptual-color-space-for-image-processing" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h1><p>A perceptual color space is desirable when doing many kinds of image processing. It is useful for things like:</p><ul><li>Turning an image grayscale, while keeping the perceived lightness the same</li><li>Increasing the saturation of colors, while maintaining perceived hue and lightness</li><li>Creating smooth and uniform looking transitions between colors</li></ul><p>Unfortunately, as far as I am aware, while there are color spaces that aim to be perceptually uniform, none are without significant drawbacks when used for image processing.</p><p>For this reason I have designed a new perceptual color space, designed to be simple to use, while doing a good job at predicting perceived lightness, <a href="https://en.wikipedia.org/wiki/Colorfulness">chroma</a> and hue. It is called the <strong>Oklab color space</strong>, because it is an OK Lab color space.</p><p>Before diving into the details of why a new color space is needed and how it was derived, here is the everything needed to use the color space:</p><blockquote><h5 id="oklab-implementations">Oklab implementations <a href="#oklab-implementations" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h5><p>Here is a list of Oklab implementations that I am aware of. The list will be updated as I’m made aware of more implementation. These are all implemented by other people and I have not verified their correctness myself.</p><ul><li>Python – <a href="https://github.com/colour-science/colour"><strong>Colour</strong></a>, <a href="https://github.com/nschloe/colorio"><strong>colorio</strong></a></li><li>Javascript – <a href="https://github.com/Evercoder/culori"><strong>culori</strong></a></li><li>TypeScript – <a href="https://github.com/thi-ng/umbrella/tree/develop/packages/color"><strong>thi.ng/color</strong></a></li><li>C++ – <a href="https://github.com/thomasp85/farver"><strong>farver</strong></a></li><li>Matlab – <a href="https://github.com/alecjacobson/gptoolbox"><strong>Geometry Processing Toolbox</strong></a></li><li>Java – <a href="https://github.com/tommyettinger/colorful-gdx"><strong>colorful-gdx</strong></a></li><li>Various – <a href="https://gmic.eu/"><strong>G’MIC</strong></a></li><li><a href="https://en.wikipedia.org/wiki/Nuke_(software)">Nuke</a> – <a href="https://github.com/jedypod/nuke-colortools"><strong>Nuke Color Tools</strong></a></li></ul><p>There are also a few experiments available to play around with Oklab online at <a href="https://observablehq.com/search?query=oklab"><strong>Observable</strong></a> and <a href="https://www.shadertoy.com/results?query=oklab"><strong>Shadertoy</strong></a></p></blockquote><h1 id="the-oklab-color-space">The Oklab color space <a href="#the-oklab-color-space" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h1><p>A color in Oklab is represented with three coordinates, similar to how <a href="https://en.wikipedia.org/wiki/CIELAB_color_space">CIELAB</a> works, but with better perceptual properties. Oklab uses a D65 whitepoint, since this is what sRGB and other common color spaces use. The three coordinates are:</p><ul><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi></mrow><annotation encoding="application/x-tex">L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span></span></span></span> – perceived lightness</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.43056em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">a</span></span></span></span> – how green/red the color is</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">b</span></span></span></span> – how blue/yellow the color is</li></ul><p>For many operations, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi><mi>a</mi><mi>b</mi></mrow><annotation encoding="application/x-tex">Lab</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span><span class="mord mathit">a</span><span class="mord mathit">b</span></span></span></span>-coordinates can be used directly, but they can also be transformed into polar form, with the coordinates lightness, chroma and hue, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi><mi>C</mi><mi>h</mi></mrow><annotation encoding="application/x-tex">LCh</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span><span class="mord mathit" style="margin-right:0.07153em;">C</span><span class="mord mathit">h</span></span></span></span>:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>C</mi><mo>=</mo><mrow><msqrt><mrow><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup></mrow></msqrt></mrow><mo separator="true">,</mo><mspace width="2em"></mspace><msup><mi>h</mi><mrow><mo>∘</mo></mrow></msup><mo>=</mo><mtext><mi mathvariant="normal">a</mi><mi mathvariant="normal">t</mi><mi mathvariant="normal">a</mi><mi mathvariant="normal">n</mi><mn>2</mn></mtext><mo>(</mo><mi>b</mi><mo separator="true">,</mo><mi>a</mi><mo>)</mo></mrow><annotation encoding="application/x-tex">C={\sqrt {a^2+b^2}}, \qquad h^{\circ}=\text{atan2}(b,a)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:1.0622690000000001em;"></span><span class="strut bottom" style="height:1.3122690000000001em;vertical-align:-0.25em;"></span><span class="uncramped textstyle displaystyle base"><span class="mord mathit" style="margin-right:0.07153em;">C</span><span class="mrel">=</span><span class="mord uncramped textstyle displaystyle"><span class="mord sqrt"><span class="sqrt-sign" style="top:-0.17226900000000012em;"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing size1">√</span></span></span><span class="vlist"><span style="top:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:1em;"></span></span><span class="mord textstyle displaystyle cramped"><span class="mord"><span class="mord mathit">a</span><span class="vlist"><span style="top:-0.289em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathrm">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mbin">+</span><span class="mord"><span class="mord mathit">b</span><span class="vlist"><span style="top:-0.289em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathrm">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:-0.9822690000000001em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:1em;"></span></span><span class="uncramped textstyle reset-textstyle sqrt-line"></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:1em;"></span></span></span></span></span></span><span class="mpunct">,</span><span class="mord mspace qquad"></span><span class="mord"><span class="mord mathit">h</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord">∘</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mrel">=</span><span class="mord uncramped textstyle displaystyle text"><span class="mord mathrm">a</span><span class="mord mathrm">t</span><span class="mord mathrm">a</span><span class="mord mathrm">n</span><span class="mord mathrm">2</span></span><span class="mopen">(</span><span class="mord mathit">b</span><span class="mpunct">,</span><span class="mord mathit">a</span><span class="mclose">)</span></span></span></span></span></p><p>From <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>C</mi></mrow><annotation encoding="application/x-tex">C</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07153em;">C</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msup><mi>h</mi><mrow><mo>∘</mo></mrow></msup></mrow><annotation encoding="application/x-tex">h^{\circ}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord"><span class="mord mathit">h</span><span class="vlist"><span style="top:-0.363em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord">∘</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span>, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.43056em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">a</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">b</span></span></span></span> can be computed like this:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi><mo>=</mo><mi>C</mi><mi>cos</mi><mo>(</mo><msup><mi>h</mi><mrow><mo>∘</mo></mrow></msup><mo>)</mo><mo separator="true">,</mo><mspace width="2em"></mspace><mi>b</mi><mo>=</mo><mi>C</mi><mi>sin</mi><mo>(</mo><msup><mi>h</mi><mrow><mo>∘</mo></mrow></msup><mo>)</mo></mrow><annotation encoding="application/x-tex">a=C\cos(h^{\circ}),\qquad b=C\sin(h^{\circ})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1em;vertical-align:-0.25em;"></span><span class="uncramped textstyle displaystyle base"><span class="mord mathit">a</span><span class="mrel">=</span><span class="mord mathit" style="margin-right:0.07153em;">C</span><span class="mop">cos</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">h</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord">∘</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mord mspace qquad"></span><span class="mord mathit">b</span><span class="mrel">=</span><span class="mord mathit" style="margin-right:0.07153em;">C</span><span class="mop">sin</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">h</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord">∘</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mclose">)</span></span></span></span></span></p><p>Lets look at a practical example to see how Oklab performs, before looking at how the <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi><mi>a</mi><mi>b</mi></mrow><annotation encoding="application/x-tex">Lab</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span><span class="mord mathit">a</span><span class="mord mathit">b</span></span></span></span> coordinates are computed.</p><blockquote><h4 id="comparing-oklab-to-hsv">Comparing Oklab to HSV <a href="#comparing-oklab-to-hsv" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h4><p>Here’s an Oklab color gradient with varying hue and constant lightness and chroma.</p><p><img alt="Oklab varying hue plot" decoding="async" height="169" loading="lazy" src="/img/oklab/hue_oklab.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 1130px) min(calc(var(--main-width) * 0.1495575221238938), 169px);" width="1130"></p><p>Compare this to a similar plot of a HSV color gradient with varying hue and constant value and saturation (HSV using the sRGB color space).</p><p><img alt="HSV varying hue plot" decoding="async" height="169" loading="lazy" src="/img/oklab/hue_hsv.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 1130px) min(calc(var(--main-width) * 0.1495575221238938), 169px);" width="1130"></p><p>The gradient is quite uneven and there are clear differences in lightness for different hues. Yellow, magenta and cyan appear much lighter than red and blue.</p><p>Here is lightness of the HSV plot, as predicted by Oklab:</p><p><img alt="HSV varying hue plot lightness" decoding="async" height="169" loading="lazy" src="/img/oklab/hue_hsv_lightness.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 1130px) min(calc(var(--main-width) * 0.1495575221238938), 169px);" width="1130"></p></blockquote><h3 id="implementation">Implementation <a href="#implementation" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h3><h4 id="converting-from-xyz-to-oklab">Converting from XYZ to Oklab <a href="#converting-from-xyz-to-oklab" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h4><p>Given a color in <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>X</mi><mi>Y</mi><mi>Z</mi></mrow><annotation encoding="application/x-tex">XYZ</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07847em;">X</span><span class="mord mathit" style="margin-right:0.22222em;">Y</span><span class="mord mathit" style="margin-right:0.07153em;">Z</span></span></span></span> coordinates, with a D65 whitepoint and white as Y=1, Oklab coordinates can be computed like this:</p><p>First the <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>X</mi><mi>Y</mi><mi>Z</mi></mrow><annotation encoding="application/x-tex">XYZ</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07847em;">X</span><span class="mord mathit" style="margin-right:0.22222em;">Y</span><span class="mord mathit" style="margin-right:0.07153em;">Z</span></span></span></span> coordinates are converted to an approximate cone responses:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>l</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>m</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>s</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">1</mn></msub></mrow><mo>×</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>X</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>Y</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>Z</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{pmatrix} l \\ m \\ s \end{pmatrix} = \mathbf{M_1} \times \begin{pmatrix} X \\ Y \\ Z \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.05002em;"></span><span class="strut bottom" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="uncramped textstyle displaystyle base"><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.01968em;">l</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">m</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">s</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mbin">×</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.07847em;">X</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.22222em;">Y</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.07153em;">Z</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p>A non-linearity is applied:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><msup><mi>l</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>m</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>s</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><msup><mi>l</mi><mrow><mfrac><mn>1</mn><mn>3</mn></mfrac></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>m</mi><mrow><mfrac><mn>1</mn><mn>3</mn></mfrac></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>s</mi><mrow><mfrac><mn>1</mn><mn>3</mn></mfrac></mrow></msup></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{pmatrix} l' \\ m' \\ s' \end{pmatrix} = \begin{pmatrix} l^{\frac 1 3} \\ m^{\frac 1 3} \\ s^{\frac 1 3} \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.3500249999999996em;"></span><span class="strut bottom" style="height:4.200049999999999em;vertical-align:-1.850025em;"></span><span class="uncramped textstyle displaystyle base"><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">m</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">s</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:1.2050049999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:0.049995000000000074em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎜</span></span></span><span style="top:-1.1950249999999998em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.29551em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord uncramped scriptstyle reset-scriptstyle"><span class="reset-size5 size5 nulldelimiter reset-scriptstyle sizing textstyle uncramped"></span><span class="mfrac"><span class="vlist"><span style="top:0.345em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="cramped reset-scriptstyle scriptscriptstyle"><span class="mord mathrm">3</span></span></span><span style="top:-0.22142857142857142em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped textstyle reset-scriptstyle frac-line"></span></span><span style="top:-0.394em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-scriptstyle scriptscriptstyle"><span class="mord mathrm">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="reset-size5 size5 nulldelimiter reset-scriptstyle sizing textstyle uncramped"></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:0.07551000000000024em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">m</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord uncramped scriptstyle reset-scriptstyle"><span class="reset-size5 size5 nulldelimiter reset-scriptstyle sizing textstyle uncramped"></span><span class="mfrac"><span class="vlist"><span style="top:0.345em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="cramped reset-scriptstyle scriptscriptstyle"><span class="mord mathrm">3</span></span></span><span style="top:-0.22142857142857142em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped textstyle reset-scriptstyle frac-line"></span></span><span style="top:-0.394em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-scriptstyle scriptscriptstyle"><span class="mord mathrm">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="reset-size5 size5 nulldelimiter reset-scriptstyle sizing textstyle uncramped"></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:1.4465299999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">s</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord uncramped scriptstyle reset-scriptstyle"><span class="reset-size5 size5 nulldelimiter reset-scriptstyle sizing textstyle uncramped"></span><span class="mfrac"><span class="vlist"><span style="top:0.345em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="cramped reset-scriptstyle scriptscriptstyle"><span class="mord mathrm">3</span></span></span><span style="top:-0.22142857142857142em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped textstyle reset-scriptstyle frac-line"></span></span><span style="top:-0.394em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-scriptstyle scriptscriptstyle"><span class="mord mathrm">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="reset-size5 size5 nulldelimiter reset-scriptstyle sizing textstyle uncramped"></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:1.2050049999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:0.049995000000000074em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎟</span></span></span><span style="top:-1.1950249999999998em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p>Finally, this is transformed into the <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi><mi>a</mi><mi>b</mi></mrow><annotation encoding="application/x-tex">Lab</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span><span class="mord mathit">a</span><span class="mord mathit">b</span></span></span></span>-coordinates:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>L</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>a</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>b</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">2</mn></msub></mrow><mo>×</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><msup><mi>l</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>m</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>s</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{pmatrix} L \\ a \\ b \end{pmatrix} = \mathbf{M_2} \times \begin{pmatrix} l' \\ m' \\ s' \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.05002em;"></span><span class="strut bottom" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="uncramped textstyle displaystyle base"><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">L</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">a</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">b</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mbin">×</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">m</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">s</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p>with the following values for <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">1</mn></msub></mrow></mrow><annotation encoding="application/x-tex">\mathbf{M_1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68611em;"></span><span class="strut bottom" style="height:0.83611em;vertical-align:-0.15em;"></span><span class="uncramped textstyle base"><span class="mord uncramped textstyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">2</mn></msub></mrow></mrow><annotation encoding="application/x-tex">\mathbf{M_2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68611em;"></span><span class="strut bottom" style="height:0.83611em;vertical-align:-0.15em;"></span><span class="uncramped textstyle base"><span class="mord uncramped textstyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span>:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">1</mn></msub></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>8</mn><mn>1</mn><mn>8</mn><mn>9</mn><mn>3</mn><mn>3</mn><mn>0</mn><mn>1</mn><mn>0</mn><mn>1</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>3</mn><mn>6</mn><mn>1</mn><mn>8</mn><mn>6</mn><mn>6</mn><mn>7</mn><mn>4</mn><mn>2</mn><mn>4</mn></mrow></mtd><mtd><mrow><mo>−</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>1</mn><mn>2</mn><mn>8</mn><mn>8</mn><mn>5</mn><mn>9</mn><mn>7</mn><mn>1</mn><mn>3</mn><mn>7</mn></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>0</mn><mn>3</mn><mn>2</mn><mn>9</mn><mn>8</mn><mn>4</mn><mn>5</mn><mn>4</mn><mn>3</mn><mn>6</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>9</mn><mn>2</mn><mn>9</mn><mn>3</mn><mn>1</mn><mn>1</mn><mn>8</mn><mn>7</mn><mn>1</mn><mn>5</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>0</mn><mn>3</mn><mn>6</mn><mn>1</mn><mn>4</mn><mn>5</mn><mn>6</mn><mn>3</mn><mn>8</mn><mn>7</mn></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>0</mn><mn>4</mn><mn>8</mn><mn>2</mn><mn>0</mn><mn>0</mn><mn>3</mn><mn>0</mn><mn>1</mn><mn>8</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>2</mn><mn>6</mn><mn>4</mn><mn>3</mn><mn>6</mn><mn>6</mn><mn>2</mn><mn>6</mn><mn>9</mn><mn>1</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>6</mn><mn>3</mn><mn>3</mn><mn>8</mn><mn>5</mn><mn>1</mn><mn>7</mn><mn>0</mn><mn>7</mn><mn>0</mn></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{M_1} = \begin{pmatrix} +0.8189330101 & +0.3618667424 & -0.1288597137 \\ +0.0329845436 & +0.9293118715 & +0.0361456387 \\ +0.0482003018 & +0.2643662691 & +0.6338517070 \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.05002em;"></span><span class="strut bottom" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="uncramped textstyle displaystyle base"><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mrel">=</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">8</span><span class="mord mathrm">1</span><span class="mord mathrm">8</span><span class="mord mathrm">9</span><span class="mord mathrm">3</span><span class="mord mathrm">3</span><span class="mord mathrm">0</span><span class="mord mathrm">1</span><span class="mord mathrm">0</span><span class="mord mathrm">1</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">0</span><span class="mord mathrm">3</span><span class="mord mathrm">2</span><span class="mord mathrm">9</span><span class="mord mathrm">8</span><span class="mord mathrm">4</span><span class="mord mathrm">5</span><span class="mord mathrm">4</span><span class="mord mathrm">3</span><span class="mord mathrm">6</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">0</span><span class="mord mathrm">4</span><span class="mord mathrm">8</span><span class="mord mathrm">2</span><span class="mord mathrm">0</span><span class="mord mathrm">0</span><span class="mord mathrm">3</span><span class="mord mathrm">0</span><span class="mord mathrm">1</span><span class="mord mathrm">8</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">3</span><span class="mord mathrm">6</span><span class="mord mathrm">1</span><span class="mord mathrm">8</span><span class="mord mathrm">6</span><span class="mord mathrm">6</span><span class="mord mathrm">7</span><span class="mord mathrm">4</span><span class="mord mathrm">2</span><span class="mord mathrm">4</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">9</span><span class="mord mathrm">2</span><span class="mord mathrm">9</span><span class="mord mathrm">3</span><span class="mord mathrm">1</span><span class="mord mathrm">1</span><span class="mord mathrm">8</span><span class="mord mathrm">7</span><span class="mord mathrm">1</span><span class="mord mathrm">5</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">2</span><span class="mord mathrm">6</span><span class="mord mathrm">4</span><span class="mord mathrm">3</span><span class="mord mathrm">6</span><span class="mord mathrm">6</span><span class="mord mathrm">2</span><span class="mord mathrm">6</span><span class="mord mathrm">9</span><span class="mord mathrm">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">−</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">1</span><span class="mord mathrm">2</span><span class="mord mathrm">8</span><span class="mord mathrm">8</span><span class="mord mathrm">5</span><span class="mord mathrm">9</span><span class="mord mathrm">7</span><span class="mord mathrm">1</span><span class="mord mathrm">3</span><span class="mord mathrm">7</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">0</span><span class="mord mathrm">3</span><span class="mord mathrm">6</span><span class="mord mathrm">1</span><span class="mord mathrm">4</span><span class="mord mathrm">5</span><span class="mord mathrm">6</span><span class="mord mathrm">3</span><span class="mord mathrm">8</span><span class="mord mathrm">7</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">6</span><span class="mord mathrm">3</span><span class="mord mathrm">3</span><span class="mord mathrm">8</span><span class="mord mathrm">5</span><span class="mord mathrm">1</span><span class="mord mathrm">7</span><span class="mord mathrm">0</span><span class="mord mathrm">7</span><span class="mord mathrm">0</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">2</mn></msub></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>2</mn><mn>1</mn><mn>0</mn><mn>4</mn><mn>5</mn><mn>4</mn><mn>2</mn><mn>5</mn><mn>5</mn><mn>3</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>7</mn><mn>9</mn><mn>3</mn><mn>6</mn><mn>1</mn><mn>7</mn><mn>7</mn><mn>8</mn><mn>5</mn><mn>0</mn></mrow></mtd><mtd><mrow><mo>−</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>0</mn><mn>0</mn><mn>4</mn><mn>0</mn><mn>7</mn><mn>2</mn><mn>0</mn><mn>4</mn><mn>6</mn><mn>8</mn></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>1</mn><mi mathvariant="normal">.</mi><mn>9</mn><mn>7</mn><mn>7</mn><mn>9</mn><mn>9</mn><mn>8</mn><mn>4</mn><mn>9</mn><mn>5</mn><mn>1</mn></mrow></mtd><mtd><mrow><mo>−</mo><mn>2</mn><mi mathvariant="normal">.</mi><mn>4</mn><mn>2</mn><mn>8</mn><mn>5</mn><mn>9</mn><mn>2</mn><mn>2</mn><mn>0</mn><mn>5</mn><mn>0</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>4</mn><mn>5</mn><mn>0</mn><mn>5</mn><mn>9</mn><mn>3</mn><mn>7</mn><mn>0</mn><mn>9</mn><mn>9</mn></mrow></mtd></mtr><mtr><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>0</mn><mn>2</mn><mn>5</mn><mn>9</mn><mn>0</mn><mn>4</mn><mn>0</mn><mn>3</mn><mn>7</mn><mn>1</mn></mrow></mtd><mtd><mrow><mo>+</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>7</mn><mn>8</mn><mn>2</mn><mn>7</mn><mn>7</mn><mn>1</mn><mn>7</mn><mn>6</mn><mn>6</mn><mn>2</mn></mrow></mtd><mtd><mrow><mo>−</mo><mn>0</mn><mi mathvariant="normal">.</mi><mn>8</mn><mn>0</mn><mn>8</mn><mn>6</mn><mn>7</mn><mn>5</mn><mn>7</mn><mn>6</mn><mn>6</mn><mn>0</mn></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{M_2} = \begin{pmatrix} +0.2104542553 & +0.7936177850 & -0.0040720468 \\ +1.9779984951 & -2.4285922050 & +0.4505937099 \\ +0.0259040371 & +0.7827717662 & -0.8086757660 \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.05002em;"></span><span class="strut bottom" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="uncramped textstyle displaystyle base"><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mrel">=</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">2</span><span class="mord mathrm">1</span><span class="mord mathrm">0</span><span class="mord mathrm">4</span><span class="mord mathrm">5</span><span class="mord mathrm">4</span><span class="mord mathrm">2</span><span class="mord mathrm">5</span><span class="mord mathrm">5</span><span class="mord mathrm">3</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">1</span><span class="mord mathrm">.</span><span class="mord mathrm">9</span><span class="mord mathrm">7</span><span class="mord mathrm">7</span><span class="mord mathrm">9</span><span class="mord mathrm">9</span><span class="mord mathrm">8</span><span class="mord mathrm">4</span><span class="mord mathrm">9</span><span class="mord mathrm">5</span><span class="mord mathrm">1</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">0</span><span class="mord mathrm">2</span><span class="mord mathrm">5</span><span class="mord mathrm">9</span><span class="mord mathrm">0</span><span class="mord mathrm">4</span><span class="mord mathrm">0</span><span class="mord mathrm">3</span><span class="mord mathrm">7</span><span class="mord mathrm">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">7</span><span class="mord mathrm">9</span><span class="mord mathrm">3</span><span class="mord mathrm">6</span><span class="mord mathrm">1</span><span class="mord mathrm">7</span><span class="mord mathrm">7</span><span class="mord mathrm">8</span><span class="mord mathrm">5</span><span class="mord mathrm">0</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">−</span><span class="mord mathrm">2</span><span class="mord mathrm">.</span><span class="mord mathrm">4</span><span class="mord mathrm">2</span><span class="mord mathrm">8</span><span class="mord mathrm">5</span><span class="mord mathrm">9</span><span class="mord mathrm">2</span><span class="mord mathrm">2</span><span class="mord mathrm">0</span><span class="mord mathrm">5</span><span class="mord mathrm">0</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">7</span><span class="mord mathrm">8</span><span class="mord mathrm">2</span><span class="mord mathrm">7</span><span class="mord mathrm">7</span><span class="mord mathrm">1</span><span class="mord mathrm">7</span><span class="mord mathrm">6</span><span class="mord mathrm">6</span><span class="mord mathrm">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">−</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">0</span><span class="mord mathrm">0</span><span class="mord mathrm">4</span><span class="mord mathrm">0</span><span class="mord mathrm">7</span><span class="mord mathrm">2</span><span class="mord mathrm">0</span><span class="mord mathrm">4</span><span class="mord mathrm">6</span><span class="mord mathrm">8</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">+</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">4</span><span class="mord mathrm">5</span><span class="mord mathrm">0</span><span class="mord mathrm">5</span><span class="mord mathrm">9</span><span class="mord mathrm">3</span><span class="mord mathrm">7</span><span class="mord mathrm">0</span><span class="mord mathrm">9</span><span class="mord mathrm">9</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord">−</span><span class="mord mathrm">0</span><span class="mord mathrm">.</span><span class="mord mathrm">8</span><span class="mord mathrm">0</span><span class="mord mathrm">8</span><span class="mord mathrm">6</span><span class="mord mathrm">7</span><span class="mord mathrm">5</span><span class="mord mathrm">7</span><span class="mord mathrm">6</span><span class="mord mathrm">6</span><span class="mord mathrm">0</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p>The inverse operation, going from Oklab to XYZ is done with the following steps:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><msup><mi>l</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>m</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>s</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><msup><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">2</mn></msub></mrow><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>×</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>L</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>a</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>b</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo separator="true">,</mo><mspace width="2em"></mspace><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>l</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>m</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>s</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><msup><mrow><mo>(</mo><msup><mi>l</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup><mo>)</mo></mrow><mrow><mn>3</mn></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mrow><mo>(</mo><msup><mi>m</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup><mo>)</mo></mrow><mrow><mn>3</mn></mrow></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mrow><mo>(</mo><msup><mi>s</mi><mrow><mi mathvariant="normal">′</mi></mrow></msup><mo>)</mo></mrow><mrow><mn>3</mn></mrow></msup></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo separator="true">,</mo><mspace width="2em"></mspace><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>X</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>Y</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>Z</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><msup><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">1</mn></msub></mrow><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>×</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>l</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>m</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>s</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{pmatrix} l' \\ m' \\ s' \end{pmatrix} = \mathbf{M_2}^{-1} \times \begin{pmatrix} L \\ a \\ b \end{pmatrix},\qquad \begin{pmatrix} l \\ m \\ s \end{pmatrix} = \begin{pmatrix} {(l')}^{3} \\ {(m')}^{3} \\ {(s')}^{3} \end{pmatrix},\qquad \begin{pmatrix} X \\ Y \\ Z \end{pmatrix} = \mathbf{M_1}^{-1} \times \begin{pmatrix} l \\ m \\ s \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.0905em;"></span><span class="strut bottom" style="height:3.681em;vertical-align:-1.5905000000000002em;"></span><span class="uncramped textstyle displaystyle base"><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">m</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">s</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class=""><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="vlist"><span style="top:-0.41300000000000003em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord">−</span><span class="mord mathrm">1</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mbin">×</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">L</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">a</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">b</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mord mspace qquad"></span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.01968em;">l</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">m</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">s</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2235em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord uncramped textstyle displaystyle"><span class="mopen">(</span><span class="mord"><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mclose">)</span></span><span class="vlist"><span style="top:-0.41589200000000004em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">3</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:0.0035000000000005582em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord uncramped textstyle displaystyle"><span class="mopen">(</span><span class="mord"><span class="mord mathit">m</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mclose">)</span></span><span class="vlist"><span style="top:-0.41589200000000004em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">3</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:1.2305000000000001em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord uncramped textstyle displaystyle"><span class="mopen">(</span><span class="mord"><span class="mord mathit">s</span><span class="vlist"><span style="top:-0.413em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">′</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mclose">)</span></span><span class="vlist"><span style="top:-0.41589200000000004em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord mathrm">3</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mord mspace qquad"></span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.07847em;">X</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.22222em;">Y</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.07153em;">Z</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class=""><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="vlist"><span style="top:-0.41300000000000003em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord uncramped scriptstyle"><span class="mord">−</span><span class="mord mathrm">1</span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span><span class="mbin">×</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.01968em;">l</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">m</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">s</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><br><blockquote><h5 id="table-of-example-xyz-and-oklab-pairs">Table of example XYZ and Oklab pairs <a href="#table-of-example-xyz-and-oklab-pairs" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h5><p>Provided to test Oklab implementations. Computed by transforming the XYZ coordinates to Oklab and rounding to three decimals.</p><table><thead><tr><th>X</th><th>Y</th><th>Z</th><th>L</th><th>a</th><th>b</th></tr></thead><tbody><tr><td>0.950</td><td>1.000</td><td>1.089</td><td>1.000</td><td>0.000</td><td>0.000</td></tr><tr><td>1.000</td><td>0.000</td><td>0.000</td><td>0.450</td><td>1.236</td><td>-0.019</td></tr><tr><td>0.000</td><td>1.000</td><td>0.000</td><td>0.922</td><td>-0.671</td><td>0.263</td></tr><tr><td>0.000</td><td>0.000</td><td>1.000</td><td>0.153</td><td>-1.415</td><td>-0.449</td></tr></tbody></table></blockquote><br><h4 id="converting-from-linear-srgb-to-oklab">Converting from linear sRGB to Oklab <a href="#converting-from-linear-srgb-to-oklab" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h4><p>Since this will be a common use case, here is the code to convert linear sRGB values to Oklab and back. To compute linear sRGB values, see <a href="https://bottosson.github.io/posts/colorwrong/#what-can-we-do%3F">my previous post</a>.</p><p>The code is in C++, but without any fancy features so should be easy to translate. The code is available in public domain, feel free to use it any way you please. It is also available under an MIT licensee if you for some reason can’t or don’t want to use public domain software. The license text <a href="https://bottosson.github.io/misc/License.txt">is available here</a></p><pre class="language-cpp"><code class="language-cpp"><span class="token keyword">struct</span> <span class="token class-name">Lab</span> <span class="token punctuation">{</span><span class="token keyword">float</span> L<span class="token punctuation">;</span> <span class="token keyword">float</span> a<span class="token punctuation">;</span> <span class="token keyword">float</span> b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br><span class="token keyword">struct</span> <span class="token class-name">RGB</span> <span class="token punctuation">{</span><span class="token keyword">float</span> r<span class="token punctuation">;</span> <span class="token keyword">float</span> g<span class="token punctuation">;</span> <span class="token keyword">float</span> b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br>Lab <span class="token function">linear_srgb_to_oklab</span><span class="token punctuation">(</span>RGB c<span class="token punctuation">)</span> <br><span class="token punctuation">{</span><br> <span class="token keyword">float</span> l <span class="token operator">=</span> <span class="token number">0.4122214708f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>r <span class="token operator">+</span> <span class="token number">0.5363325363f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>g <span class="token operator">+</span> <span class="token number">0.0514459929f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>b<span class="token punctuation">;</span><br> <span class="token keyword">float</span> m <span class="token operator">=</span> <span class="token number">0.2119034982f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>r <span class="token operator">+</span> <span class="token number">0.6806995451f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>g <span class="token operator">+</span> <span class="token number">0.1073969566f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>b<span class="token punctuation">;</span><br> <span class="token keyword">float</span> s <span class="token operator">=</span> <span class="token number">0.0883024619f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>r <span class="token operator">+</span> <span class="token number">0.2817188376f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>g <span class="token operator">+</span> <span class="token number">0.6299787005f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>b<span class="token punctuation">;</span><br><br> <span class="token keyword">float</span> l_ <span class="token operator">=</span> <span class="token function">cbrtf</span><span class="token punctuation">(</span>l<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token keyword">float</span> m_ <span class="token operator">=</span> <span class="token function">cbrtf</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token keyword">float</span> s_ <span class="token operator">=</span> <span class="token function">cbrtf</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token keyword">return</span> <span class="token punctuation">{</span><br> <span class="token number">0.2104542553f</span><span class="token operator">*</span>l_ <span class="token operator">+</span> <span class="token number">0.7936177850f</span><span class="token operator">*</span>m_ <span class="token operator">-</span> <span class="token number">0.0040720468f</span><span class="token operator">*</span>s_<span class="token punctuation">,</span><br> <span class="token number">1.9779984951f</span><span class="token operator">*</span>l_ <span class="token operator">-</span> <span class="token number">2.4285922050f</span><span class="token operator">*</span>m_ <span class="token operator">+</span> <span class="token number">0.4505937099f</span><span class="token operator">*</span>s_<span class="token punctuation">,</span><br> <span class="token number">0.0259040371f</span><span class="token operator">*</span>l_ <span class="token operator">+</span> <span class="token number">0.7827717662f</span><span class="token operator">*</span>m_ <span class="token operator">-</span> <span class="token number">0.8086757660f</span><span class="token operator">*</span>s_<span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><br><br>RGB <span class="token function">oklab_to_linear_srgb</span><span class="token punctuation">(</span>Lab c<span class="token punctuation">)</span> <br><span class="token punctuation">{</span><br> <span class="token keyword">float</span> l_ <span class="token operator">=</span> c<span class="token punctuation">.</span>L <span class="token operator">+</span> <span class="token number">0.3963377774f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>a <span class="token operator">+</span> <span class="token number">0.2158037573f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>b<span class="token punctuation">;</span><br> <span class="token keyword">float</span> m_ <span class="token operator">=</span> c<span class="token punctuation">.</span>L <span class="token operator">-</span> <span class="token number">0.1055613458f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>a <span class="token operator">-</span> <span class="token number">0.0638541728f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>b<span class="token punctuation">;</span><br> <span class="token keyword">float</span> s_ <span class="token operator">=</span> c<span class="token punctuation">.</span>L <span class="token operator">-</span> <span class="token number">0.0894841775f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>a <span class="token operator">-</span> <span class="token number">1.2914855480f</span> <span class="token operator">*</span> c<span class="token punctuation">.</span>b<span class="token punctuation">;</span><br><br> <span class="token keyword">float</span> l <span class="token operator">=</span> l_<span class="token operator">*</span>l_<span class="token operator">*</span>l_<span class="token punctuation">;</span><br> <span class="token keyword">float</span> m <span class="token operator">=</span> m_<span class="token operator">*</span>m_<span class="token operator">*</span>m_<span class="token punctuation">;</span><br> <span class="token keyword">float</span> s <span class="token operator">=</span> s_<span class="token operator">*</span>s_<span class="token operator">*</span>s_<span class="token punctuation">;</span><br><br> <span class="token keyword">return</span> <span class="token punctuation">{</span><br> <span class="token operator">+</span><span class="token number">4.0767416621f</span> <span class="token operator">*</span> l <span class="token operator">-</span> <span class="token number">3.3077115913f</span> <span class="token operator">*</span> m <span class="token operator">+</span> <span class="token number">0.2309699292f</span> <span class="token operator">*</span> s<span class="token punctuation">,</span><br> <span class="token operator">-</span><span class="token number">1.2684380046f</span> <span class="token operator">*</span> l <span class="token operator">+</span> <span class="token number">2.6097574011f</span> <span class="token operator">*</span> m <span class="token operator">-</span> <span class="token number">0.3413193965f</span> <span class="token operator">*</span> s<span class="token punctuation">,</span><br> <span class="token operator">-</span><span class="token number">0.0041960863f</span> <span class="token operator">*</span> l <span class="token operator">-</span> <span class="token number">0.7034186147f</span> <span class="token operator">*</span> m <span class="token operator">+</span> <span class="token number">1.7076147010f</span> <span class="token operator">*</span> s<span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span></code></pre><blockquote><p>The matrices were updated 2021-01-25. The new matrices have been derived using a higher precision sRGB matrix and with exactly matching D65 values. The old matrices are available <a href="https://bottosson.github.io/misc/srgb_to_oklab_old.txt">here</a> for reference. The values only differ after the first three decimals.</p><p>Depending on use case you might want to use the sRGB matrices your application uses directly instead of the ones provided here.</p></blockquote><p>This is everything you need to use the Oklab color space! If you need a simple perceptual color space, try it out.</p><p>The rest of the post will go into why a new color space was needed, how it has been constructed and how it compares with existing color spaces.</p><hr><h1 id="motivation-and-derivation-of-oklab">Motivation and derivation of Oklab <a href="#motivation-and-derivation-of-oklab" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h1><p>What properties does a perceptual color space need to satisfy to be useful for image processing? The answer to this is always going to be a bit subjective, but based on my experience, these are a good set of requirements:</p><blockquote><ul><li><strong>Should be an opponent color space</strong>, similar to for example <a href="https://en.wikipedia.org/wiki/CIELAB_color_space">CIELAB</a>.</li><li><strong>Should predict lightness, chroma and hue well</strong>. <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi></mrow><annotation encoding="application/x-tex">L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>C</mi></mrow><annotation encoding="application/x-tex">C</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07153em;">C</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">h</span></span></span></span> should be perceived as orthogonal, so one can be altered without affecting the other two. This is useful for things like turning an image black and white and increasing colorfulness without introducing hue shifts etc.</li><li><strong>Blending two colors should result in even transitions</strong>. The transition colors should appear to be in between the blended colors (e.g. passing through a warmer color than either original color is not good).</li><li><strong>Should assume a D65 whitepoint</strong>. This is what common color spaces like sRGB, rec2020 and Display P3 uses.</li><li><strong>Should behave well numerically</strong>. The model should be easy to compute, numerically stable and differentiable.</li><li><strong>Should assume normal well lit viewing conditions</strong>. The complexity of supporting different viewing conditions is not practical in most applications. Information about absolute luminance and background luminance adaptation does not normally exist and the viewing conditions can vary.</li><li><strong>If the scale/exposure of colors are changed, the perceptual coordinates should just be scaled by a factor</strong>. To handle a large dynamic range without requiring knowledge of viewing conditions all colors should be modelled as if viewed under normal viewing conditions and as if the eye is adapted to roughly the luminance of the color. This avoids a dependence on scaling.</li></ul></blockquote><h3 id="what-about-existing-models%3F">What about existing models? <a href="#what-about-existing-models%3F" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h3><p>Let’s look at existing models and how they stack up against these requirements. Further down there are graphs that illustrate some of these issues.</p><blockquote><ul><li><strong><a href="https://en.wikipedia.org/wiki/CIELAB_color_space">CIELAB</a> and <a href="https://en.wikipedia.org/wiki/CIELUV">CIELUV</a></strong> – Largest issue is their inability to predict hue. In particular blue hues are predicted badly. Other smaller issues exist as well</li><li><strong><a href="https://en.wikipedia.org/wiki/CIECAM02">CIECAM02-UCS</a> and the newer CAM16-UCS</strong> – Does a good job at being perceptually uniform overall, but doesn’t meet other requirements: Bad numerical behavior, it is not scale invariant and blending does not behave well because of its compression of chroma. Hue uniformity is decent, but other models predict it more accurately.</li><li><strong><a href="https://en.wikipedia.org/wiki/OSA-UCS">OSA-UCS</a></strong> – Overall does a good job. The transformation to OSA-UCS lacks an analytical inverse unfortunately which makes it impractical.</li><li><strong><a href="https://scholarworks.rit.edu/theses/2858/">IPT</a></strong> – Does a great job modelling hue uniformity. Doesn’t predict lightness and chroma well unfortunately, but meets all other requirements. Is simple computationally and does not depend on the scale/exposure.</li><li><strong><a href="https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-25-13-15131&id=368272">JzAzBz</a></strong> – Overall does a fairly good job. Designed to have uniform scaling of lightness for HDR data. While useful in some cases this introduces a dependence on the scale/exposure that makes it hard to use in general cases.</li><li><strong><a href="https://en.wikipedia.org/wiki/HSL_and_HSV">HSV</a> representation of sRGB</strong> – Only on this list because it is widely used. Does not meet any of the requirements except having a D65 whitepoint.</li></ul></blockquote><p>So, all in all, all these existing models have drawbacks.</p><p>Out of all of these, two models stand out: CAM16-UCS, for being the model with best properties of perceptual uniformity overall, and IPT for having a simple computational structure that meets all the requirements besides predicting lightness and chroma well.</p><p>For this reason it is reasonable to try to make a new color space, with the same computational structure as IPT, but that performs closer to CAM16-UCS in terms of predicting lightness and chroma. This exploration resulted in Oklab.</p><h3 id="how-oklab-was-derived">How Oklab was derived <a href="#how-oklab-was-derived" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h3><p>To derive Oklab, three datasets were used:</p><ul><li>A generated data set of pairs of colors with the same lightness but random hue and chroma, generated using CAM16 and normal viewing conditions. Colors were limited to be within Pointer’s Gamut – the set of possible surface colors.</li><li>A generated data set of pairs of colors with the same chroma but random hue and lightness, generated using CAM16 and normal viewing conditions. Colors were limited to be within Pointer’s Gamut</li><li>The <a href="https://github.com/coloria-dev/color-data/tree/main/ebner-fairchild">uniform perceived hue</a> data used to derive IPT. From this data, colors were combined into pairs of colors with equal perceived hue.</li></ul><p>These datasets can be used to test prediction of lightness, chroma and hue respectively. If a color space accurately models <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi></mrow><annotation encoding="application/x-tex">L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>C</mi></mrow><annotation encoding="application/x-tex">C</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07153em;">C</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">h</span></span></span></span>, then all pairs in lightness dataset should have the same value for <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi></mrow><annotation encoding="application/x-tex">L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span></span></span></span>, all pairs in the chroma dataset the same value for <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>C</mi></mrow><annotation encoding="application/x-tex">C</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07153em;">C</span></span></span></span> and all pairs in the hue dataset the same values for <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">h</span></span></span></span>.</p><p>To test a color space it is not possible to simply check the distance in predictions in the tested color space however, since that will depend on the scaling of the color space. It is also not desirable to exactly predict ground truth values for <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi></mrow><annotation encoding="application/x-tex">L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span></span></span></span>, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>C</mi></mrow><annotation encoding="application/x-tex">C</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.07153em;">C</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">h</span></span></span></span>, since it is more important that our model has perceptually orthogonal coordinates, than that the model has the same spacing within each coordinate.</p><p>Instead the following approach was used to create an error metric independent of the color space:</p><ul><li>For each dataset all the pairs are converted to the tested color space.</li><li>Coordinates that are supposed to be the same within a pair are swapped to generate a new set of altered pairs:<ul><li>For the lightness dataset, the L coordinates are swapped between the pairs, and so on.</li><li>These altered pair would be equal to the original pair if the model predicts the datasets perfectly.</li></ul></li><li>The perceived distance between the original colors and the altered colors are are computed using <a href="https://en.wikipedia.org/wiki/Color_difference">CIEDE2000</a>.</li><li>The error for each pair is given as the minimum of the two color differences.</li><li>The error for the entire dataset is the root mean squared error of the color differences.</li></ul><p>Oklab was derived by optimizing the parameters of a color space with the same structure as IPT, to get a low error on all the datasets. For completeness, here is the structure of the color space – the parameters to optimize are the 3x3 matrices <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">1</mn></msub></mrow></mrow><annotation encoding="application/x-tex">\mathbf{M_1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68611em;"></span><span class="strut bottom" style="height:0.83611em;vertical-align:-0.15em;"></span><span class="uncramped textstyle base"><span class="mord uncramped textstyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">2</mn></msub></mrow></mrow><annotation encoding="application/x-tex">\mathbf{M_2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68611em;"></span><span class="strut bottom" style="height:0.83611em;vertical-align:-0.15em;"></span><span class="uncramped textstyle base"><span class="mord uncramped textstyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span> and the positive number <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>γ</mi></mrow><annotation encoding="application/x-tex">\gamma</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.05556em;">γ</span></span></span></span>.</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>l</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>m</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>s</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">1</mn></msub></mrow><mo>×</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>X</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>Y</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>Z</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{pmatrix} l \\ m \\ s \end{pmatrix} = \mathbf{M_1} \times \begin{pmatrix} X \\ Y \\ Z \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.05002em;"></span><span class="strut bottom" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="uncramped textstyle displaystyle base"><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.01968em;">l</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">m</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">s</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">1</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mbin">×</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.07847em;">X</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.22222em;">Y</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit" style="margin-right:0.07153em;">Z</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><mi>L</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>a</mi></mrow></mtd></mtr><mtr><mtd><mrow><mi>b</mi></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><msub><mi mathvariant="bold">M</mi><mn mathvariant="bold">2</mn></msub></mrow><mo>×</mo><mrow><mo fence="true">(</mo><mtable><mtr><mtd><mrow><msup><mi>l</mi><mi>γ</mi></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>m</mi><mi>γ</mi></msup></mrow></mtd></mtr><mtr><mtd><mrow><msup><mi>s</mi><mi>γ</mi></msup></mrow></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{pmatrix} L \\ a \\ b \end{pmatrix} = \mathbf{M_2} \times \begin{pmatrix} l^\gamma \\ m^\gamma \\ s^\gamma \end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:2.05002em;"></span><span class="strut bottom" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="uncramped textstyle displaystyle base"><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">L</span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">a</span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord mathit">b</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="mrel">=</span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathbf">M</span><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="reset-textstyle scriptstyle cramped"><span class="mord mathbf">2</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mbin">×</span><span class="uncramped textstyle displaystyle minner"><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎝</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎛</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist"><span style="top:-1.2099999999999997em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit" style="margin-right:0.01968em;">l</span><span class="vlist"><span style="top:-0.41300000000000003em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord mathit" style="margin-right:0.05556em;">γ</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:-0.00999999999999951em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">m</span><span class="vlist"><span style="top:-0.41300000000000003em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord mathit" style="margin-right:0.05556em;">γ</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span style="top:1.1900000000000006em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="mord uncramped textstyle displaystyle"><span class="mord"><span class="mord mathit">s</span><span class="vlist"><span style="top:-0.41300000000000003em;margin-right:0.05em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="uncramped reset-textstyle scriptstyle"><span class="mord mathit" style="margin-right:0.05556em;">γ</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span><span class="uncramped textstyle reset-textstyle style-wrap"><span class="delimsizing mult"><span class="vlist"><span style="top:0.9049999999999999em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎠</span></span></span><span style="top:-0.89502em;"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span><span class="delim-size4 delimsizinginner"><span>⎞</span></span></span><span class="baseline-fix"><span class="reset-size5 size5 fontsize-ensurer"><span style="font-size:0em;"></span></span></span></span></span></span></span></span></span></span></span></p><p>A couple of extra constraints were also added, since this error doesn’t alone determine the scale and orientation of the color model.</p><ul><li>Positive b is oriented to the same yellow color as CAM16</li><li>D65 (normalized with <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>Y</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">Y=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.68333em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.22222em;">Y</span><span class="mrel">=</span><span class="mord mathrm">1</span></span></span></span>) should transform to <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi><mo>=</mo><mn>1</mn><mo separator="true">,</mo><mi>a</mi><mo>=</mo><mn>0</mn><mo separator="true">,</mo><mi>b</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">L=1, a=0, b=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="uncramped textstyle base"><span class="mord mathit">L</span><span class="mrel">=</span><span class="mord mathrm">1</span><span class="mpunct">,</span><span class="mord mathit">a</span><span class="mrel">=</span><span class="mord mathrm">0</span><span class="mpunct">,</span><span class="mord mathit">b</span><span class="mrel">=</span><span class="mord mathrm">0</span></span></span></span> and</li><li>The <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.43056em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">a</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">b</span></span></span></span> plane is scaled so that around 50% gray the ratio of color differences along the lightness axis and the <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.43056em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">a</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.69444em;"></span><span class="strut bottom" style="height:0.69444em;vertical-align:0em;"></span><span class="uncramped textstyle base"><span class="mord mathit">b</span></span></span></span> plane is the same as the ratio for color differences predicted by CIEDE2000.</li></ul><p>Using these constraints a fairly good model was found, but based on the results two more changes was made. The <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>γ</mi></mrow><annotation encoding="application/x-tex">\gamma</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.05556em;">γ</span></span></span></span> value ended up very close to 1/3, 0.323, and when looking at the sRGB gamut, the blue colors folded in on themselves slightly, resulting in a non-convex sRGB gamut. By forcing the value of <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>γ</mi></mrow><annotation encoding="application/x-tex">\gamma</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="strut" style="height:0.43056em;"></span><span class="strut bottom" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="uncramped textstyle base"><span class="mord mathit" style="margin-right:0.05556em;">γ</span></span></span></span> to 1/3 and adding a constraint the blue colors to not fold inwards, the final Oklab model was derived. The error was not noticeably affected by these restrictions.</p><h3 id="comparison-with-other-color-spaces">Comparison with other color spaces <a href="#comparison-with-other-color-spaces" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h3><p>Here are the errors for the three different datasets across color spaces, given both as root mean square error and as the 95th percentile. The best performing result is highlighted in <em>bold</em> in each row (ignoring CAM16 since it is the origin of the test data). Since the lightness and chroma data was generated using CAM16 rather than being data from experiments, this data can’t be used to say which model best matches human perception. What can be said is that Oklab does a good job at predicting hue and its predictions for chroma and lightness are close to those of CAM16-UCS.</p><table><thead><tr><th></th><th>Oklab</th><th>CIELAB</th><th>CIELUV</th><th>OSA-UCS</th><th>IPT</th><th>JzAzBz</th><th>HSV</th><th>CAM16-UCS</th></tr></thead><tbody><tr><td>L RMS</td><td><strong>0.20</strong></td><td>1.70</td><td>1.72</td><td>2.05</td><td>4.92</td><td>2.38</td><td>11.59</td><td><em>0.00</em></td></tr><tr><td>C RMS</td><td><strong>0.81</strong></td><td>1.84</td><td>2.32</td><td>1.28</td><td>2.18</td><td>1.79</td><td>3.38</td><td><em>0.00</em></td></tr><tr><td>H RMS</td><td>0.49</td><td>0.69</td><td>0.68</td><td>0.49</td><td>0.48</td><td><strong>0.43</strong></td><td>1.10</td><td>0.59</td></tr><tr><td>L 95</td><td><strong>0.44</strong></td><td>3.16</td><td>3.23</td><td>4.04</td><td>9.89</td><td>4.55</td><td>23.17</td><td><em>0.00</em></td></tr><tr><td>C 95</td><td><strong>1.78</strong></td><td>3.96</td><td>5.03</td><td>2.73</td><td>4.64</td><td>3.77</td><td>7.51</td><td><em>0.00</em></td></tr><tr><td>H 95</td><td>1.06</td><td>1.56</td><td>1.51</td><td>1.08</td><td>1.02</td><td><strong>0.92</strong></td><td>2.42</td><td>1.31</td></tr></tbody></table><blockquote><p>To be able to include HSV in these comparisons, a Lab-like color space has been defined based on it, by interpreting HSV as a cylindrical color space and converting to a regular grid.</p><p>JzAzBz has been used with white scaled so that Y=100. This matches the graphs in the original paper, but it is unclear if this is how it is intended to be used. (See <a href="https://github.com/nschloe/colorio/issues/41">this colorio Github issue</a> for a discussion of the topic)</p></blockquote><h4 id="munsell-data">Munsell data <a href="#munsell-data" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h4><p>Here is <a href="https://www.rit.edu/science/munsell-color-science-lab-educational-resources#munsell-renotation-data">Munsell color chart data</a> (with V=5) plotted in the various color spaces. If a color space has a chroma prediction that matches that of the Munsell data, the rings formed by the data should appear as perfect circles. The quality of this data is a bit hard to assess, since it isn’t directly using experimental data, it is a color chart created from experimental data back in the 1940s.</p><p>Oklab and CAM16-UCS seem to predict the Munsell data well, while other spaces squash the circles in the dataset in various ways, which would indicate that Oklab does a better job than most of the color spaces of predicting chroma.</p><div class="columns has-background-white-ter"><div class="column"><p><strong>Oklab</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/oklab_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 394px) min(calc(var(--main-width) * 0.7055837563451777), 278px);" width="394"></p></div><div class="column"><p><strong>CIELAB</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/cielab_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 391px) min(calc(var(--main-width) * 0.710997442455243), 278px);" width="391"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>CIELUV</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/cieluv_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 391px) min(calc(var(--main-width) * 0.710997442455243), 278px);" width="391"></p></div><div class="column"><p><strong>OSA-UCS</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/osa_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 391px) min(calc(var(--main-width) * 0.710997442455243), 278px);" width="391"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>IPT</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/ipt_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 384px) min(calc(var(--main-width) * 0.7239583333333334), 278px);" width="384"></p></div><div class="column"><p><strong>JzAzBz</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/jzazbz_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 401px) min(calc(var(--main-width) * 0.6932668329177057), 278px);" width="401"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>HSV</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/hsv_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 394px) min(calc(var(--main-width) * 0.7055837563451777), 278px);" width="394"></p></div><div class="column"><p><strong>CAM16-UCS</strong><br><img alt="Munsell plot" decoding="async" height="278" loading="lazy" src="/img/oklab/cam16_munsell.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 391px) min(calc(var(--main-width) * 0.710997442455243), 278px);" width="391"></p></div></div><h4 id="luo-rigg-dataset-and-full-gamut">Luo-Rigg dataset and full gamut <a href="#luo-rigg-dataset-and-full-gamut" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h4><p>These plots show three things, ellipses, scaled based on perception of color differences from the <a href="https://github.com/coloria-dev/color-data/tree/main/luo-rigg">Luo-Rigg</a> dataset, the shape of the full visible gamut (the black line corresponds to pure single wavelength lights) and a slice of the sRGB gamut.</p><p>A few interesting observations are:</p><ul><li>The shape of the full gamut is quite odd in CIELAB and OSA-UCS, which likely means that their predictions are quite bad for highly saturated colors</li><li>Except for CAM16-UCS the ellipses are stretched out as chroma increases. CAM16 explicitly compresses chroma to better match experimental data, which makes this data look good, but makes color blending worse</li></ul><div class="columns has-background-white-ter"><div class="column"><p><strong>Oklab</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/oklab_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 394px) min(calc(var(--main-width) * 0.7055837563451777), 278px);" width="394"></p></div><div class="column"><p><strong>CIELAB</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/cielab_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 397px) min(calc(var(--main-width) * 0.7002518891687658), 278px);" width="397"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>CIELUV</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/cieluv_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 397px) min(calc(var(--main-width) * 0.7002518891687658), 278px);" width="397"></p></div><div class="column"><p><strong>OSA-UCS</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/osa_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 391px) min(calc(var(--main-width) * 0.710997442455243), 278px);" width="391"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>IPT</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/ipt_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 391px) min(calc(var(--main-width) * 0.710997442455243), 278px);" width="391"></p></div><div class="column"><p><strong>JzAzBz</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/jzazbz_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 401px) min(calc(var(--main-width) * 0.6932668329177057), 278px);" width="401"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>HSV</strong><br><em>Data missing. Plot broken since HSV does not handle colors outside sRGB gamut</em></p></div><div class="column"><p><strong>CAM16-UCS</strong><br><img alt="Luo-Rigg plot" decoding="async" height="278" loading="lazy" src="/img/oklab/cam16_luo_rigg.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 393px) min(calc(var(--main-width) * 0.7073791348600509), 278px);" width="393"></p></div></div><h4 id="blending-colors">Blending colors <a href="#blending-colors" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h4><p>Here are plots of white blended with a blue color, using the various color spaces tested. The blue color has been picked since it is the hue with the most variation between spaces. CIELAB, CIELUV and HSV all show hue shifts towards purple. CAM16 has a different issue, with the color becoming desaturated quickly, resulting in a transition that doesn’t look as even as some of the other ones.</p><div class="columns has-background-white-ter"><div class="column"><p><strong>Oklab</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/oklab_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div><div class="column"><p><strong>CIELAB</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/cielab_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div><div class="column"><p><strong>CIELUV</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/cieluv_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div><div class="column"><p><strong>OSA-UCS</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/osa_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div></div><div class="columns has-background-white-ter"><div class="column"><p><strong>IPT</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/ipt_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div><div class="column"><p><strong>JzAzBz</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/jzazbz_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div><div class="column"><p><strong>HSV</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/hsv_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div><div class="column"><p><strong>CAM16-UCS</strong><br><img alt="Blend plot" decoding="async" height="160" loading="lazy" src="/img/oklab/cam16_blend.png" style="background-size:cover;contain-intrinsic-size: min(var(--main-width), 349px) min(calc(var(--main-width) * 0.4584527220630373), 160px);" width="349"></p></div></div><h2 id="conclusion">Conclusion <a href="#conclusion" class="anchor-link"><span class="icon is-small"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 512 512" version="1.1" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813 l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0 l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219 c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0 C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0 c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125 c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0 l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594 C274.561,395.092,246.42,392.342,220.326,382.186z"></path></svg><span></span></span></a></h2><p>This post has introduced the Oklab color space, a perceptual color space for image processing. Oklab is able to predict perceived lightness, chroma and hue well, while being simple and well-behaved numerically and easy to adopt.</p><p>In future posts I want to look into using Oklab to build a better perceptual color picker and more.</p><hr><blockquote><p><em>Oklab and the images in this post have been made using <a href="https://www.python.org/">python</a>, <a href="https://jupyter.org/">jupyter</a>, <a href="https://numpy.org/">numpy</a>, <a href="https://www.scipy.org/">scipy</a> <a href="https://matplotlib.org/">matplotlib</a>, <a href="https://github.com/nschloe/colorio">colorio</a> and <a href="https://github.com/colour-science/colour">colour</a>.</em></p></blockquote><hr><p>If you liked this article, it would be great if you considered sharing it:</p><div class="buttons"><a href="https://twitter.com/intent/tweet/?text=A%20perceptual%20color%20space%20for%20image%20processing&url=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F" class="is-small button resp-sharing-button--twitter" rel="noopener" target="_blank" aria-label="Share on Twitter"><span class="icon resp-sharing-button__icon resp-sharing-button__icon--solid"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M23.44 4.83c-.8.37-1.5.38-2.22.02.93-.56.98-.96 1.32-2.02-.88.52-1.86.9-2.9 1.1-.82-.88-2-1.43-3.3-1.43-2.5 0-4.55 2.04-4.55 4.54 0 .36.03.7.1 1.04-3.77-.2-7.12-2-9.36-4.75-.4.67-.6 1.45-.6 2.3 0 1.56.8 2.95 2 3.77-.74-.03-1.44-.23-2.05-.57v.06c0 2.2 1.56 4.03 3.64 4.44-.67.2-1.37.2-2.06.08.58 1.8 2.26 3.12 4.25 3.16C5.78 18.1 3.37 18.74 1 18.46c2 1.3 4.4 2.04 6.97 2.04 8.35 0 12.92-6.92 12.92-12.93 0-.2 0-.4-.02-.6.9-.63 1.96-1.22 2.56-2.14z"></path></svg> </span></a><a href="mailto:?subject=A%20perceptual%20color%20space%20for%20image%20processing&body=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F" class="is-small button resp-sharing-button--email" rel="noopener" target="_self" aria-label="Share by E-Mail"><span class="icon resp-sharing-button__icon resp-sharing-button__icon--solid"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M22 4H2C.9 4 0 4.9 0 6v12c0 1.1.9 2 2 2h20c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM7.25 14.43l-3.5 2c-.08.05-.17.07-.25.07-.17 0-.34-.1-.43-.25-.14-.24-.06-.55.18-.68l3.5-2c.24-.14.55-.06.68.18.14.24.06.55-.18.68zm4.75.07c-.1 0-.2-.03-.27-.08l-8.5-5.5c-.23-.15-.3-.46-.15-.7.15-.22.46-.3.7-.14L12 13.4l8.23-5.32c.23-.15.54-.08.7.15.14.23.07.54-.16.7l-8.5 5.5c-.08.04-.17.07-.27.07zm8.93 1.75c-.1.16-.26.25-.43.25-.08 0-.17-.02-.25-.07l-3.5-2c-.24-.13-.32-.44-.18-.68s.44-.32.68-.18l3.5 2c.24.13.32.44.18.68z"></path></svg> </span></a><a href="https://reddit.com/submit/?url=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F&resubmit=true&title=A%20perceptual%20color%20space%20for%20image%20processing" class="is-small button resp-sharing-button--reddit" rel="noopener" target="_blank" aria-label="Share on Reddit"><span class="icon resp-sharing-button__icon resp-sharing-button__icon--solid"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M24 11.5c0-1.65-1.35-3-3-3-.96 0-1.86.48-2.42 1.24-1.64-1-3.75-1.64-6.07-1.72.08-1.1.4-3.05 1.52-3.7.72-.4 1.73-.24 3 .5C17.2 6.3 18.46 7.5 20 7.5c1.65 0 3-1.35 3-3s-1.35-3-3-3c-1.38 0-2.54.94-2.88 2.22-1.43-.72-2.64-.8-3.6-.25-1.64.94-1.95 3.47-2 4.55-2.33.08-4.45.7-6.1 1.72C4.86 8.98 3.96 8.5 3 8.5c-1.65 0-3 1.35-3 3 0 1.32.84 2.44 2.05 2.84-.03.22-.05.44-.05.66 0 3.86 4.5 7 10 7s10-3.14 10-7c0-.22-.02-.44-.05-.66 1.2-.4 2.05-1.54 2.05-2.84zM2.3 13.37C1.5 13.07 1 12.35 1 11.5c0-1.1.9-2 2-2 .64 0 1.22.32 1.6.82-1.1.85-1.92 1.9-2.3 3.05zm3.7.13c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2zm9.8 4.8c-1.08.63-2.42.96-3.8.96-1.4 0-2.74-.34-3.8-.95-.24-.13-.32-.44-.2-.68.15-.24.46-.32.7-.18 1.83 1.06 4.76 1.06 6.6 0 .23-.13.53-.05.67.2.14.23.06.54-.18.67zm.2-2.8c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm5.7-2.13c-.38-1.16-1.2-2.2-2.3-3.05.38-.5.97-.82 1.6-.82 1.1 0 2 .9 2 2 0 .84-.53 1.57-1.3 1.87z"></path></svg> </span></a><a href="https://news.ycombinator.com/submitlink?u=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F&t=A%20perceptual%20color%20space%20for%20image%20processing" class="is-small button resp-sharing-button--hackernews" rel="noopener" target="_blank" aria-label="Share on Hacker News"><span class="icon resp-sharing-button__icon resp-sharing-button__icon--solid"><svg viewBox="0 0 140 140" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M60.94 82.314L17 0h20.08l25.85 52.093c.397.927.86 1.888 1.39 2.883.53.994.995 2.02 1.393 3.08.265.4.463.764.596 1.095.13.334.262.63.395.898.662 1.325 1.26 2.618 1.79 3.877.53 1.26.993 2.42 1.39 3.48 1.06-2.254 2.22-4.673 3.48-7.258 1.26-2.585 2.552-5.27 3.877-8.052L103.49 0h18.69L77.84 83.308v53.087h-16.9v-54.08z" fill-rule="evenodd"></path></svg> </span></a><a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F&title=A%20perceptual%20color%20space%20for%20image%20processing&source=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F" class="is-small button resp-sharing-button--linkedin" rel="noopener" target="_blank" aria-label="Share on LinkedIn"><span class="icon resp-sharing-button__icon resp-sharing-button__icon--solid"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M6.5 21.5h-5v-13h5v13zM4 6.5C2.5 6.5 1.5 5.3 1.5 4s1-2.4 2.5-2.4c1.6 0 2.5 1 2.6 2.5 0 1.4-1 2.5-2.6 2.5zm11.5 6c-1 0-2 1-2 2v7h-5v-13h5V10s1.6-1.5 4-1.5c3 0 5 2.2 5 6.3v6.7h-5v-7c0-1-1-2-2-2z"></path></svg> </span></a><a href="https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fbottosson.github.io%2Fposts%2Foklab%2F" class="is-small button resp-sharing-button--facebook" rel="noopener" target="_blank" aria-label="Share on Facebook"><span class="icon resp-sharing-button__icon resp-sharing-button__icon--solid"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M18.77 7.46H14.5v-1.9c0-.9.6-1.1 1-1.1h3V.5h-4.33C10.24.5 9.5 3.44 9.5 5.32v2.15h-3v4h3v12h5v-12h3.85l.42-4z"></path></svg></span></a></div><p></p><p>For discussions and feedback, <a href="https://twitter.com/bjornornorn" rel="noopener" target="_blank">ping me on Twitter.</a></p><script type="application/ld+json">{"@context":"https://schema.org","@type":"Article","headline":"A perceptual color space for image processing","image":["https://bottosson.github.io/img/oklab/hue_oklab.png","https://bottosson.github.io/img/oklab/hue_hsv.png","https://bottosson.github.io/img/oklab/hue_hsv_lightness.png","https://bottosson.github.io/img/oklab/oklab_munsell.png","https://bottosson.github.io/img/oklab/cielab_munsell.png","https://bottosson.github.io/img/oklab/cieluv_munsell.png","https://bottosson.github.io/img/oklab/osa_munsell.png","https://bottosson.github.io/img/oklab/ipt_munsell.png","https://bottosson.github.io/img/oklab/jzazbz_munsell.png","https://bottosson.github.io/img/oklab/hsv_munsell.png","https://bottosson.github.io/img/oklab/cam16_munsell.png","https://bottosson.github.io/img/oklab/oklab_luo_rigg.png","https://bottosson.github.io/img/oklab/cielab_luo_rigg.png","https://bottosson.github.io/img/oklab/cieluv_luo_rigg.png","https://bottosson.github.io/img/oklab/osa_luo_rigg.png","https://bottosson.github.io/img/oklab/ipt_luo_rigg.png","https://bottosson.github.io/img/oklab/jzazbz_luo_rigg.png","https://bottosson.github.io/img/oklab/cam16_luo_rigg.png","https://bottosson.github.io/img/oklab/oklab_blend.png","https://bottosson.github.io/img/oklab/cielab_blend.png","https://bottosson.github.io/img/oklab/cieluv_blend.png","https://bottosson.github.io/img/oklab/osa_blend.png","https://bottosson.github.io/img/oklab/ipt_blend.png","https://bottosson.github.io/img/oklab/jzazbz_blend.png","https://bottosson.github.io/img/oklab/hsv_blend.png","https://bottosson.github.io/img/oklab/cam16_blend.png"],"author":"Björn Ottosson","genre":"","publisher":{"@type":"Organization","name":"Björn Ottosson","logo":{"@type":"ImageObject","url":"/img/favicon/favicon-192x192.png?hash=98293e6f87"}},"url":"https://bottosson.github.io/posts/oklab/","mainEntityOfPage":"https://bottosson.github.io/posts/oklab/","datePublished":"2020-12-23","dateModified":"2021-01-27","description":"A perceptual color space for image processing A perceptual color space is desirable when doing many kinds of image processing. It is useful..."}</script><p>Published <time datetime="2020-12-23">23 Dec 2020</time></p></div></article></main></body></html>