Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve LUTs support. #500

Closed
KelSolaar opened this issue Sep 14, 2019 · 7 comments
Closed

Improve LUTs support. #500

KelSolaar opened this issue Sep 14, 2019 · 7 comments

Comments

@KelSolaar
Copy link
Member

KelSolaar commented Sep 14, 2019

Starting this issue to track down some of the work @nick-shaw, @jdvandenberg and I were doing with respect to LUTs and before we forget.

@zachlewis
Copy link
Contributor

Heya -- so, I think I may be able to contribute some stuff here. Over the past few months, on and off, I've been messing around with creating additional LUTSequenceOperators, sort of frankensteining together work from Nick's CLF branch and Thomas's various lut-related feature branches, and trying my hand at... uh, reimplementing in numpy much of the work contributed by the OCIO2 crew and the AMPAS gang to their respective projects.

Regretfully, I hadn't anticipated where my experimental operators would take me, so I hadn't been working in my colour library fork; so I have some stuff to extract and refactor, and certainly some documentation and testing to... document and test, but I'd be happy to share some code and ideas to do with as you please.

For your consideration...

  • I've put together an ExponentWithLinear Operator, based on an early OCIO2 contribution; need to revisit in light of recent CLF 2.0 VWG discussions...

  • I did something similar with the various flavors of Log Operators contributed to OCIO2 -- I have separate LogCTF, LogAffine, and LogCamera operators, which should probably be refactored into a single Log Operator. My parametric camera log implementation isn't quite as fancy as Doug's proposal -- it expects six coefficients in addition to a 'linSideBreak' point and a base parameter (which I've reduced to five on paper)... but even though my math seems to check out, it might be worth waiting to see where things are going with the CLF implementation, if parity is important.

  • I put together a couple of "Shaper" operators -- a LG2Shaper Operator (a la aces-dev/OCIO), and a PQShaper Operator, both parameterized the same way (min_exposure_value, max_exposure_value, middle_grey kwargs); as well as, perhaps unnecessarily, an AllocationTransform Operator, parameterized like the OCIO Transform. The PQShaper and LG2Shaper Ops each include 'shape_cube' instance methods that sample a function to a LUT3D "wrapped" in reverse and forward shapers as a concatenated 1D +3D LUTSequence. The AllocationTransform Op likewise has a handy class method for computing allocation vars for a given function, for a given range. domain? range, i think. Bonus classmethod factory that does the same thing for an RGB_Colourspace, via its decoding_cctf. Man, it's gonna be exciting checking my work.

  • Somewhere, I put a fair amount of work into wrapping my head around (speedy) HalfDomain LUT inversion, but I kept ending up with an offset that shouldn't be. I'll have to give that another go. HalfDomain LUTs kinda blow my mind a little, and having a vectorized implementation is immensely satisfying, I gotta say....

  • Oh, I added 'direction' and 'bypass' kwargs to the AbstractLUTSequenceOperator class... I was a little apprehensive about making the classes particularly 'stateful'; but I think it's worth being able to apply each operator in a given direction. Oh, each operator can be applied in reverse via a 'reverse' method that does the inverse of whatever the 'apply' method is doing, which, itself, is contingent on whether the operator's direction is set to 'forward' or 'inverse'. (LUT3Ds and HalfDomain operators pending, of course),

  • I created a NoOp Operator. Don't think of me as a hero.

  • I actually went through and implemented all the FixedFunctionTransform styles / operations, which ends up being a pretty hefty part of the AMPAS CTL code base. So, there's that.

  • Added a couple of other operators based on various ACES CTL snippets -- a CompressHighlights operator (as used by the ACES 1.1 OutputTransform...uh, transform, to prevent simulated whitepoints from clipping), as well as a 'gamut restrict' operator...

  • An experimental Sympy-based Expression operator that needs more love, and some methods for constructing and 'lambdifying' piecewise functions and solving for their inverses [or failing to do so 50% of the time, cuz i'm not great with sympy]

  • I definitely screwed up somewhere trying to create an entire OutputTransform operator / Segmented Spline / SSTS operators.

  • A couple other odds and ends, like a painfully slow OCIOProcessor Operator, if OCIO is available.... various Matrixy convenience operators -- "GamutConvert", "(De)saturation", "Fit", and so forth, which really just use Nick's Matrix Operator under the hood...

...and... perhaps other stuff I'm almost definitely forgetting.

anyway, I'll start extracting / refactoring these jams if you guys are interested; happy to share gists of where things are now, too, if you'd rather discuss / deliberate / reject stuff before I go too far with refactoring for public consumption. Anyway. More soon. Cheers!

@KelSolaar
Copy link
Member Author

Hey @zachlewis,

That is quite an awesome and fat list! Might be useful to slice that down into multiple PRs down the road. I will have a careful read tomorrow or end of week.

Tagging @nick-shaw !

@nick-shaw
Copy link
Contributor

Great work indeed! I had parked my CLF work until the VWG finished the spec for CLF 2.0, but you have made a major head start on support for that.

@nick-shaw
Copy link
Contributor

Just noting here for posterity (even though you are probably well aware of it) that my CLF stuff was very experimental and tentative, and only pushed to colour-science so others could have a look. There is a lot missing, even from CLF 1.0 spec. The major gaps are:

  1. There is no bit-depth support – it just assumes everything is float.
  2. The Range operator (as well as missing the bit-depth based stuff) has none of the special case handling for single-ended ranges to do one sided clamping. But this may well change in CLF 2.0 anyway.
  3. As noted by Greg Cotten on ACES Central, there was an error in my logic for the half-domain lookup. I believe that is fixed by my recent commits.
  4. Metadata is mostly ignored. There are plans for more metadata support in Colour, and I left out metadata handling for CLF until if could be integrated with that.
  5. The CLF branch has not been rebased on the recent changes to develop which include changes to the names of some LUT classes. I plan to do that over the next couple of days.

I'm sure there's plenty more!

@zachlewis
Copy link
Contributor

Holy crap, I wrote far too many words. Sorry about that, it seemed like less at the time.

Yeah, I definitely didn't mean to suggest that I'd dump all that goodness in a single PR! That would be kind of a nightmare. No, it's gonna take me some time just to get everything fully refactored and migrated over into meaningful feature branches; and even after that, I've got my work cut out for me in terms of documentation / citation / test..ation. The good news is, I've been using the colour-science yapf config, and it makes saving documents the most satisfying part of my day.

In any case, I figured the first thing I'd do is kill a few birds with one stone with a colab notebook focusing on just one or two of these operators demonstrating a handful of ideas worth considering for separate PRs; and at the same time, I'd like to use the opportunity to demonstrate some sympy stuff, cuz it dovetails with the 'need for speed' thread (i'll elaborate further there), among other reasons.

Nick, I'm definitely picking up what you're putting down. As I recall, your branch sprouted rather organically during the halcyon days of 0.3.12 dev, as the LUTSequence and LUT Operators provided enough meat-and-bones to hang a CLF proof-of-concept off of -- and I think what you've put together is remarkable. And educational. And useful. Also, generating half-domain LUTs in milliseconds is kind of a religious experience.

That said, I do agree with you, spending time trying to implement a spec that's still under active development doesn't make a whole lot of sense. On the other hand, given the lack of urgency, I'm not averse to treating CLF as something to chip away at and mold into place as the spec crystalizes, with the understanding that "experimental and tentative" is the name of the game. As it is, my Log and Exponent ops are months old, and also need to be updated to incorporate the more late-breaking features.

More to say, but enough wordage for now.

@nick-shaw
Copy link
Contributor

FWIW, feature/CLF is now rebased on develop in my fork, as of yesterday.

@KelSolaar KelSolaar modified the milestones: v0.3.14, v0.3.15 Oct 26, 2019
@KelSolaar KelSolaar modified the milestones: v0.3.15, v0.3.16 Jan 25, 2020
@KelSolaar
Copy link
Member Author

Closing this one as most of it is implemented and I will create a new one for CLF.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants