gmic-py icon indicating copy to clipboard operation
gmic-py copied to clipboard

Add Numpy, PIL, Scikit-Image support

Open myselfhimself opened this issue 3 years ago • 16 comments

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)

myselfhimself avatar Sep 02 '20 16:09 myselfhimself

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)..

myselfhimself avatar Sep 21 '20 08:09 myselfhimself

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).

myselfhimself avatar Sep 29 '20 12:09 myselfhimself

In gmic-2.9.1-alpha1, presets and options are mixing up their effects. Will be fixed (checkbox added in the TODO above)

myselfhimself avatar Sep 29 '20 12:09 myselfhimself

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.

myselfhimself avatar Oct 02 '20 22:10 myselfhimself

  • 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

myselfhimself avatar Oct 08 '20 10:10 myselfhimself

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

myselfhimself avatar Oct 13 '20 16:10 myselfhimself

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.

myselfhimself avatar Oct 14 '20 17:10 myselfhimself

presets as module-level constants will probably be removed... in favor of no presets at all and just per-framework conversion helper functions

myselfhimself avatar Oct 19 '20 15:10 myselfhimself

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

myselfhimself avatar Oct 19 '20 16:10 myselfhimself

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)

myselfhimself avatar Oct 20 '20 16:10 myselfhimself

simplified above checkboxes TODO list with future method names

myselfhimself avatar Oct 20 '20 17:10 myselfhimself

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...

myselfhimself avatar Oct 21 '20 17:10 myselfhimself

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

myselfhimself avatar Oct 22 '20 08:10 myselfhimself

Rearranged TODO list into 3 distinct numpy, PIL, scikit sections at the top of this issue

myselfhimself avatar Oct 22 '20 08:10 myselfhimself

  • 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)

myselfhimself avatar Oct 23 '20 14:10 myselfhimself

Come on come on!!! A few TODO checkboxes remaining and we are close to the goal!!!

myselfhimself avatar Oct 28 '20 09:10 myselfhimself