stev47 / StaticKernels.jl

Julia-native non-allocating kernel operations on arrays
Other
25 stars 0 forks source link

Troubles with median #4

Open mileslucas opened 4 years ago

mileslucas commented 4 years ago

I was checking this package out and seeing if it would be able to replace some simple median-filtering code I've got in a package. Previously, I was using ImageFiltering.jl's mapwindow(median!, ...) to accomplish this. My solution using StaticKernels is

using StaticKernels
k = Kernel{(-5:5,-5:5)}(median!)
map(k, extend(img, StaticKernels.ExtensionReplicate()))

This fails due to the lack of Base.iterate for the window view passed to median! (similarly fails for median. If I try Kernel{...}(w -> median(Tuple(w))) the runtime explodes (like, I have to sigint the REPL).

Am I missing something here?

stev47 commented 4 years ago

A couple of notes here:

mileslucas commented 4 years ago

Wow, what a thorough, well-put, and intelligent response. Thanks, this answers a lot of questions, even ones I didn't know I had! I suppose I'll be keeping an eye out on this package and let it mature and seep into the various ecosystems.

RoyiAvital commented 1 year ago

Is there a non allocating non mutating median without pre allocated buffer? Maybe an idea is that map() will allow sending kwargs into the kernel function? So in that case a buffer can be used.

stev47 commented 1 year ago

There is one in this old pull request.

I would want to avoid changing map syntax too much, but you can definitely use a buffer in your window function already by creating a closure.

RoyiAvital commented 1 year ago

What's blocking the pull request?

I am not sure I get what you mean, maybe an example? Will closure be optimal performance wise?

stev47 commented 1 year ago

It says "Review required".

I'm saying that you can reference a buffer from within your window function like this:

const buf = zeros(3)
k = Kernel{(-1:1,)}(@inline w -> (copyto!(buf, Tuple(w)); median!(buf))

It should be as fast as you get using a heap-allocated buffer, but please benchmark for yourself.