sampling parameters in bilateral blur

Hallo, is there any explanation for the sampling parameters in the bilateral command?

DanielDD

Welcome back, @DanielDD.

EDIT: Provided maximum down sampling parameter. 0.5 < down sampling < 20 is probably the practical range. Really small down sampling (0.1 < ds < 0.2) can incur a buffer overflow.

These are optimization parameters which control how much down sampling takes place on both the selected image and the given edge guide before these are convolved by the “spatial” and “range” (edge) gaussian kernels. Bigger arguments mean more down sampling, faster operation and less accurate results. You may set the down sampling amount independently for both the kernels. Here’s a demonstration script (spatial=5, range=1,maxdownsample=12):
$ gmic -command bilateral.gmic explorebilateralsampling 5,1,12

bilateral.gmic

explorebilateralsampling: -check "${1=5}>=1 && ${2=2}>=1 && ${3=20}"
   spatial=$1
   range=$2
   maxds=$3
   -sample cat,256
   -name cat

# Edge mask. Leave this image out and bilateral will derive its own edge mask.
   +gradient_norm[cat]
   -name. mask
   -apply_gamma[mask] 1.25
   -normalize[mask] 0,255

 # Animation to demonstrate how image degrades as downsampling increases
   -repeat 300
      downsample={0.5+$maxds*$>/300}
      -local[mask,cat]
        +bilateral[cat] [mask],$spatial,$range,$downsample,$downsample
	-text. "Sample size:"{round($downsample,0.001,0)},3%,3%,15,1,255,255,255
	-verbose +
	-echo[] $>", "$downsample
	-verbose -
      -done
   -done
   -remove[cat,mask]
   -reverse
   -output bisample.mp4,30,h264

If you run this script in a shell, the initial 20 frames can take an excruciatingly long time to render, then the speed picks up as larger and larger down sampling amounts are put in play. The final 20 frames render very quickly, but probably aren’t very useful. The animation provides a sense of how down sampling greater amounts degrades the results (though, artistically, the degraded effect can be interesting).

  1. G’MIC’s bilateral command is a builtin implemented in CImg.h. It is based on work by S. Paris and F. Durand, who have written a reference implementation..
  2. OpenCV introduction to bilateral filtering: Bilateral Filtering
  3. A Gentle Introduction to Bilateral Filtering and its Applications by Sylvain Paris, Pierre Kornprobst, Jack Tumblin, and Frédo Durand
1 Like

Thanks. So it seems to be more complicated than I thought. I should make some experiments.

May I suggest a not-too-complicated starting point?

# Arbitrary image source. -input or -sample or -portrait whatever you want....
-sample cat,256
-name cat

# Edge mask. For straightforward work, leave this and the next step out and
# run -bilateral without a edge (aka guide) mask. When not given a a edge mask, -bilateral 
# simply duplicates the input image (here, cat) and uses that for an edge mask.
# Leave these two steps in if you are adventurous; you can manipulate the edge mask in various
# ways for different effects.

+luminance[cat]
-name edgemask

# Nearly basic use of bilateral. Using a -luminance version for an edge mask and omitting
# down sampling on spatial and range kernels. -luminance will estimate down sampling guides.

+bilateral[cat] [edgemask],7,20
-name. softcat
-keep[cat,softcat]

Practically, down sampling lets you trade time for quality. If -bilateral is running way too long, then provide explicit down sampling parameters — start with 1 and march up by increments of one, down by one half, and so on. Settle on the largest down sampling number that still furnishes acceptable quality. Note that you can vary down sampling numbers independently for the spatial and range kernels. Down sampling is optional. More than half the time, rendering is fast enough and you need not even bother with choosing down sampling amounts.

Also, practically, half the time you need not furnish an edge guide mask. But if you do provide a
mask, then you can use it as a spring board to various artistic effects. One example:

gmic -sample cat,256 name. cat +luminance[cat] name edgemask apply_gamma[edgemask] 2 unsharp[edgemask] 7,20 cut[edgemask] 0,255 +bilateral[cat] [edgemask],2,10 -name. cartooncat -normalize[edgemask] 0.7,1 to_rgb[edgemask] -mul[edgemask,cartooncat]

Have fun!