-
Notifications
You must be signed in to change notification settings - Fork 17
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
Switch to new Cython-based RGB to CIE LCH_ab conversion for colorizing #122
Conversation
For performance, this script: from trollimage.colormap import Colormap
import numpy as np
cmap = Colormap(values=list(range(4)), colors=[(1.0, 1.0, 0.0), (0.0, 1.0, 1.0), (1.0, 1.0, 1.0), (0.0, 0.0, 0.0)])
data = np.random.random((3000, 3000))
colorized_image = cmap.colorize(data) I run: kernprof -l profile_colorize.py
python -m line_profiler profile_colorize.py.lprof And get:
So hcl2rgb is still the slowest individual call. |
So I started analyzing the failures of Here's what I get when I convert them to HCL: In [3]: rgb2hcl_old(1.0, 1.0, 0.0)
Out[3]: (80.17623543714927, 0.00501416179526073, -0.14337082984424737)
In [4]: rgb2hcl_old(0.0, 1.0, 1.0)
Out[4]: (169.421806448465, 0.0034564219537122592, -0.1440018813512837)
In [5]: rgb2hcl(np.array([[1.0, 1.0, 0.0]]))
Out[5]: array([[1.04719755, 0.66666667, 0.5 ]])
In [6]: rgb2hcl(np.array([[0.0, 1.0, 1.0]]))
Out[6]: array([[3.14159265, 0.66666667, 0.5 ]]) What I see here is that the new algorithm is much more consistent. For example, why is but here's the colorspace diagram: Let me see if I can generate the two versions of the colormaps as colorbars... |
I have another branch based on this one which completely reworks docs. I'd like to save that work for another PR. |
Codecov Report
@@ Coverage Diff @@
## main #122 +/- ##
==========================================
- Coverage 93.37% 91.17% -2.21%
==========================================
Files 11 11
Lines 3624 3852 +228
==========================================
+ Hits 3384 3512 +128
- Misses 240 340 +100
Flags with carried forward coverage won't be shown. Click here to find out more.
|
From what I can tell lost coverage is due to no tests for colorspaces.py and now that the hcl functions from that module aren't being used there are no tests touching them. |
Re YlGnBu, we should definitely add more intermediate colors, maybe these: https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=9 |
Yes, absolutely. Even just adding the middle color (which matches the other colors I think) made things better in this PR. I should note that the color produced by Do you have any other thoughts on the other colormap changes? Are any of those unacceptable to you if this PR were to be adopted/merged? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for putting in all the effort, it's just a bit disappointing it didn't improve the performance that much.
Tests are failing though... |
I'll spend an hour or so today seeing if I flip the logic around if it changes performance: I'm thinking if I do the for loop on the outer convert function and then passing every pixel in to the sub-functions that it should improve performance based on memory locality. I think for simplicity of code I'm going to pass pixel colors by reference instead of by value. Or at least the output. That way all functions can remain |
Oh and the tests I will fix. They are just expected color comparison failures. I'll triple check that they aren't completely different colors before changing the expected values. |
I have to admit I can't think of much right now....
One more thing I saw now when looking at the code again: could we extract methods for the rgb to and from srgb conversions? I think it would make the code a bit nicer. |
also opencv and corresponding python bindings could make things much faster if we want to test https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html |
Which ones are you referring to? |
Ah sure. I could make a little inline function for the individual component operation. I think I'll leave the simplified version as it is. |
Oh and no I haven't looked at those other libraries/tools because I was trying to avoid another dependency for only a small portion of what this library does and for such a small portion of what those libraries does (lots of extra functionality we aren't using). |
true. |
The new conversions don't seem to produce NaNs
As mentioned on slack, I will follow this PR up with an optimization PR and a PR to auto-generate the colormap images used in the docs. |
This is a replacement for #121 that adds a cython extension to trollimage. This does mean a lot more complexity to the building of trollimage, but opens up a lot of doors for more optimizations in the future.
I commented on #79 about the performance I was seeing from #121 and how it was worse.
I'm happy to say that with this new version the say test that took 1.68s in the version inThis newest implementation is faster but only barely. I will try optimizing it further in another PR.main
now takes 479ms. I still have some optimizations though.This work is heavily taken from the
rio-color
package: https://github.com/mapbox/rio-colorTODO:
Decide/determine if the failing tests are just different numbers and not necessarily wrong
Add wheel building and upload to CI
Implement rgb2hcl in Cython (currently only have hcl2grb)
Refactor, refactor, refactor
Closes Add more accurate RGB <-> HCL conversion for colorize interpolation #121, closes hcl2rgb bottleneck in colorize methods #79 (remove if there is no corresponding issue, which should only be the case for minor changes)
Tests added (for all bug fixes or enhancements)
Tests passed (for all non-documentation changes)
Passes
git diff origin/master **/*py | flake8 --diff
(remove if you did not edit any Python files)Fully documented (remove if this change should not be visible to users, e.g., if it is an internal clean-up, or if this is part of a larger project that will be documented later)