arrayfire / arrayfire-rust

Rust wrapper for ArrayFire
BSD 3-Clause "New" or "Revised" License
815 stars 58 forks source link

bilateral filter #152

Closed ghost closed 7 years ago

ghost commented 7 years ago

Hi,

I need some confirmations on the behavior of bilateral's filter as documentation doesn't tell much about it.

I've dig the code a little bit and it seems the radius is forced to 1.5 x spatial_sigma, and spatial_sigma seems clamped to 11.5 on the CPU backend, and not clamped on GPU (but with visibles artefacts or a runtime error on high values my tests)

So basically, it means it can only provides strong filtering on small images.

Can someone confirm that, or update the documentation ?

9prady9 commented 7 years ago

@ultimaRatio If there is discrepancy in behaviour between CPU backend and GPU backend, then it seems to me like a bug in the code. Can you please raise this issue at upstream repo with the following information. I will look into it.

Than you.

ghost commented 7 years ago

@9prady9 : thanks for the link. I'm working on examples but before I want to reproduce the artefacts on others configurations (maybe a driver related bug or something like this).

For the discrepancy in behaviour, i'm sure it's not a bug. It's just that higher values will eat too much cpu and take to long to execute to be usable. The code used for the bilateral filter is correct, but it's the simplest way to code a bilateral. Take no offence from my words, because more efficient ways to code a bilateral are also way more complicated to code, even on a cpu. And if you don't need to run strong bilateral on big images, the simplest code is good enough.

ghost commented 7 years ago

done. https://github.com/arrayfire/arrayfire/issues/1827

one more thing, with strong values (spatial_sigma >=25 for example), i've got this message :

thread 'main' panicked at 'Error message: Unsupported operation/parameter option', /home/frank/.cargo/registry/src/github.com-1ecc6299db9ec823/arrayfire-3.4.3/src/error.rs:66
9prady9 commented 7 years ago

@ultimaRatio That is because the neighbourhood of current pixel is loaded into local(shared in CUDA) memory of the GPU for fast neighbourhood pixel access in a given work group(block in CUDA). There is a limit to how much shared(local) memory is available on each GPU. We check for this in each function's kernel implementation and throw unsupported operation if the size goes beyond what the hardware can support. Current bilateral's implementation doesn't have any fallback implementation for neighbourhood sizes that don't fit on shared(local) memory.