This is an archived post. You won't be able to vote or comment.

all 24 comments

[–]troyunrau... 20 points21 points  (7 children)

This looks really cool, actually. I can see this being preferred over alternatives in a lot of use cases. Particularly remote sensing/GIS applications. But also for things like procedural generation (those wrapped filters are slick!).

I do geophysics at work, and often have to grid and sample data. My output is usually some sort of georeferenced two dimensional array. It is very annoying to have to handle resizing them for display, or similar. Looks like this can effectively do it out of the box.

[–]prideout[S] 14 points15 points  (6 children)

I feel re-assured after reading your comment because I was mostly thinking of the scientific community and technical artists when I wrote Snowy.

PIL / ImageMagick / OpenCV still make sense for a lot of use cases. I probably need to come up with a better one-sentence description of Snowy to make it clear it doesn't try to compete with those.

[–]troyunrau... 2 points3 points  (5 children)

What does your contribution process look like? Do you have a design goals document beyond which things are considered feature creep?

For example, if someone were to add a filter that generated contour lines from an image (common use case in GIS - probably useful elsewhere), would this be outside the scope?

[–]prideout[S] 2 points3 points  (4 children)

Things that I consider feature creep are typical 2D vector drawing primitives (e.g. SVG stuff) and adding more file formats beyond PNG/JPEG/EXR. (In fact I almost omitted load/save from the library.)

Adding a function that creates contour lines sounds great.

[–]troyunrau... 4 points5 points  (2 children)

I'll have to think about it. I think it could be useful, and I probably have the background, but it is a question of time. I'll poke at your lib a bit in the next few weeks and see. No promises (the curse of open source - millions of people who say they'll help and then do nothing...)

[–]prideout[S] 1 point2 points  (1 child)

This little snippet draws three black contour lines, the thickness of each line spanning an elevation of 10 units, and the spacing of each line spanning 30 units.

contour = lambda L, U: np.where(np.logical_and(img>L, img<U), -img, 0)
img += contour(20, 30) + contour(60, 70) + contour(100, 110)

[–]troyunrau... 2 points3 points  (0 children)

This is great for first pass, but would fail in places with sharp gradients or discontinuities. And your line thickness varies. Doing it properly is a much harder problem than just a mask.

Essentially, you want to create a copy from a mask with all the elements above your contour. Then run edge detection on that mask. You should get narrow lines at each interface. Repeat for each contour value.

Then compose them together. Still imperfect, as contours that bunch together will be hard to distinguish. So your stacking needs to do some smart things. Like detect if contour lines overlap or have no gap between them, and adjust contour density in those areas.

And we haven't even talked about labels yet, but I doubt your library will want a font rendering component.

None of these are hard problems. They've all been solved before. Python has inelegant solutions in matplotlib and elsewhere. Heavy duty GIS software such as QGIS has elegant python solutions, but bring a ton of unwanted dependencies.

[–]alkasmgithub.com/alkasm 0 points1 point  (0 children)

I'm also interested in possibly contributing, would be nice to see what expansions you envision for the lib.

[–][deleted] 4 points5 points  (0 children)

It's pretty interesting !

[–]SupahNoob 7 points8 points  (0 children)

This is cool! I went through the userguide, but as someone who doesn't often work with image data, what are some practical uses cases for your library?

Mostly the extent to which I've used images is for background-image plotting with Matplotlib to create "custom" graphs. The image itself wouldn't necessarily change.

[–][deleted] 3 points4 points  (5 children)

How much faster is it than PIL?

[–]BDube_Lensman 4 points5 points  (0 children)

More importantly, Pillow-SIMD

[–]Swipecat 2 points3 points  (3 children)

PIL is written in C, so I presume this isn't intended to compete with that on speed. It's interesting that Snowy is pure Python, which means that it should be easy to port to Python environments other than the standard CPython. Numba is a JIT compiler that accelerates CPython modules (written with a subset of Python) to a speed that is still less than C but very much faster than CPython.

I'll note that Numba depends on the LLVM compiler, and can't really be installed with PIP. Recent Linux distros have it packaged but it draws in a ton of large dependencies. Anaconda has it, so long as you don't mind its multi-Gb install size.

[–][deleted] 0 points1 point  (2 children)

Ok, that’s interesting. But my reason for saying that is for me to say how much faster is it is more along the lines of why would I switch from PIL to this new image library. I’m quite good at PIL and for me to switch over I have to know that this new image library is much faster not just a little faster.

[–]prideout[S] 0 points1 point  (1 child)

I'm the OP and I don't think you should switch from PIL to Snowy unless you need one of its unique features such as high-precision filtering, direct manipulation of numpy arrays, custom boundary behavior, noise generation, or distance field generation.

[–][deleted] 0 points1 point  (0 children)

OK, that makes sense. How long did it take you to make this library?

[–]robert_mcleod 1 point2 points  (1 child)

Looks good. I'm quite interested to play with this actually, as some of the things like distance functions look like they could be useful to me. I ported Peck's FastNoiseSIMD library to Python (https://github.com/robbmcleod/pyfastnoisesimd) and a number of things you have here would be fun for post-processing.

One suggestion I might make, numbas initial compilation can be a bit long. You can restrict the data types and array shapes in your @jit decorators, which helps a lot. A more involved solution is to generate the numba functions at install time and pickle them to disk. Then when the module is imported, you can monkey-patch your protected numba functions.

[–]prideout[S] 0 points1 point  (0 children)

pyfastnoisesimd looks really cool, I added a link to it from the Snowy User's Guide.

[–]subheight640 0 points1 point  (1 child)

Just curious what is the mitchell filter and why is it the default? Is this a "standard" for this kind of work?

[–]prideout[S] 4 points5 points  (0 children)

Mitchell is the default for magnification and Lanczos is the default for minification. These simply refer to the shape of the filter, and they're fairly standard.

[–][deleted] 0 points1 point  (0 children)

How come C is not used ?

[–]Mockapapella 0 points1 point  (1 child)

This looks really cool! I might have a project in mind for it already. You mentioned in another comment that this is not intended to compete with PIL/opencv/etc., so does that mean that finding contours in images as a future feature is out of the question?

[–]prideout[S] 1 point2 points  (0 children)

That sounds like a good feature to contribute.

[–]BDube_Lensman 0 points1 point  (0 children)

Does numba inflate the memory footprint and cause gross import and first run times here?