gmic-py
gmic-py copied to clipboard
Add Numpy, PIL, Scikit-Image support
Matrix layout and (de)interleaving presets: ~~- [x] add presets to G'MIC module and add validator GmicImage class method~~
- [x] set up Jupyter Lab document for simpler testing than Pytest and RFC-ing of presets to the numpy, PIL and and scikitimage communities ~~- [x] parameters mutual-exclusion: prevent from/to_numpy_array parameters tuning (except for as_type) if a preset is used, raise GmicException in such cases~~
Numpy I/O support
~~- [x] add 'a': a third letter for the 'i'/'d' (de)interleaving option to have no effect on channels pixel format. 'a' for agnostic~~
-
[x] from_numpy() - deinterleaving input
- [x] code
- [x] docstring
- [x] pytest
-
[x] to_numpy() - interleaving output
- [x] code
- [x] docstring
- [x] pytest
-
[x] solidify GmicImage.to_numpy_helper()
- [x] remove preset= parameter
- [ ] up-to-date C docstring
- [x] permute='xyzc' parameter
- [x] cpython code
- [x] pytest
- [x] interleave=False:bool parameter
- [x] cpython code
- [x] pytest
- [x] squeeze_shape=False:bool parameter
- [x] cpython code
- [x] pytest
- [x] astype=None:numpy.dtype parameter
- [x] cpython code
- [x] pytest
-
[ ] solidify GmicImage.from_numpy_helper()
- [ ] up-to-date C docstring
- [ ] deinterleave=False:bool parameter
- [x] cpython code
- [ ] pytest
- [ ] permute='xyzc':bool parameter
- [x] cpython code
- [ ] pytest
Scikit-image I/O support
- [ ] Scikit-image support documentation section
- [x] from_scikit()
- [x] pure-python code
- [ ] well-documented C string
- [x] cpython code
- [x] pytest
- [ ] advanced pytest with skimage module
- [x] to_scikit()
- [x] pure-python code
- [ ] well-documented C string
- [x] cpython code
- [x] pytest
- [ ] advanced pytest with skimage module
PIL I/O support
- [x] PIL support documentation section
- [x] from_PIL()
- [x] pure-python code
- [x] well-documented C string
- [x] cpython code
- [x] pytest (PIL output to image+G'MIC output to image + pixel-to-pixel comparisons)
- [x] to_PIL()
- [x] pure-python code
- [x] well-documented C string
- [x] cpython code
- [x] pytest (PIL output to image+G'MIC output to image + pixel-to-pixel comparisons)
Let me try to write the pytest cases for input-output conversion in pure Python / Numpy to the various toolkits and code the conversion operations in C/Python when they work... (scaffolding in the biological cellular sense)..
An early presets design specification (premute, interleave) config tuples has been submitted for RFC in our lab: https://colab.research.google.com/drive/1bZzJDqdEvtoIgGrx3GchPwu95SgFM8D7?usp=sharing (public Google Colab sheet)
I might push this sheet on Twitter and Pixls.us for more RFC, when there are working examples for each preset (eg. pure Python transposes from vanilla from_/to_numpy_array() calls in order to reach a display in PIL/ScikitImage/Numpy-Matplot).
In gmic-2.9.1-alpha1, presets and options are mixing up their effects. Will be fixed (checkbox added in the TODO above)
Created an editable RFC of conversion presets on Google Colab, also backed up here on Github. It both gives preset specifications and code blocks exemplify and testing them.
Uploading fresher and fresher wheels to pypi.org
will allow to write those tests within the notebook.
- Skimage user and PIL user found and interviewed over Twitter, they have been helping to lower the number of cases to cover for now, and will be our first testers
- PIL pure-Python implementation seems OK but awaits testing by the related person on Twitter
- will implement the Skimage pure-python implementation on the Google Colab sheet today and have it tested as well
the GmicImage.to_numpy_array(permute='')
parameter which resolves into a np.ndarray.transpose((0-n tuple))
still gives me issues.. eg. permute='yxz'
=> transpose((1,0,2,3))
is ok, but it then gives a shape for a different transposition eg. 2,0,1,3 or so... one more day needed
GmicImage.to_numpy_array(permute='xyzc') where the optional permute string must be a 5-letters string made up of x,y,z,c only in any order, now properly triggers internally a numpy.ndarray.transpose() operation. Pytests for this are coming up next.
presets as module-level constants will probably be removed... in favor of no presets at all and just per-framework conversion helper functions
to_numpy_array()
is renamed to to_numpy_helper()
understood as a very generic factory method for outputting numpy arrays, which has g'mic-like defaults : no interleaving, w,h,d,s and float32 type without squeezing.
some other method, maybe to_numpy()
will be introduced to have default flipped shape and interleaving... something numpy-like and easily showable in matplotlib
WIP from_PIL:
import gmic
import PIL.Image
PIL_apples_filename = "PIL_apples.png"
PIL_leno_filename = "PIL_leno.png"
gmic.run("sp leno output " + PIL_leno_filename)
PIL_leno = PIL.Image.open(PIL_leno_filename)
leno = gmic.GmicImage.from_PIL(PIL_leno)
gmic.run("display", leno)
gmic.run("sp apples output " + PIL_apples_filename)
PIL_apples = PIL.Image.open(PIL_apples_filename)
apples = gmic.GmicImage.from_PIL(PIL_apples)
gmic.run("display", apples)
- [x] fix Segmentation fault (core dumped) after exit following a gmic.run("display", apples)
simplified above checkboxes TODO list with future method names
Work on the post-from_PIL()
exit-time segfault helped writing this public Github Gist on debugging both C/Python module and Python core code from shell and the CLion IDE. A drop of help in the ocean for people with similar issues in the future...
gmic-py 2.9.1 alpha 2 with PIL I/O and solidified numpy I/O is released at: https://pypi.org/project/gmic/2.9.1a2/
- will update the docs (Numpy support page) and add a new PIL support page as well on the https://gmic-py.readthedocs.io/ website
- tutorials and examples are slated for November-December 2020 instead
Rearranged TODO list into 3 distinct numpy, PIL, scikit sections at the top of this issue
- discarded to_numpy_gmic and from_numpy_gmic converters (ie. for non (de)-interleaved non-permuted numpy<->g'mic array conversion), in favour of just to_/from_numpy_helper's default parameters as they are now (and locked in their behaviour by current unit tests..)
- discarding the idea of module-level per-toolkit preset constants.. those string constants in a home-made format could have been replaced by dictionaries for calling to_/from_numpy_helper (ie. function kwargs).. but I am chosing to keep things even simpler for now, especially I do not want to force numpy import at module-instantiation time, and the PIL preset would require this (ie. casting to uint8 using numpy.uint8)
Come on come on!!! A few TODO checkboxes remaining and we are close to the goal!!!