art with code

2008-09-01

Adaptive blur filter Mandelbrot

To finish off today's Mandelbrot madness, here's a version that does a ghetto 2D box filter with kernel size controlled by the second image (i.e. blur more where second image is white, don't blur where it's black.) Using a second core gives an 80% speed boost.



open Prelude

let niter = 255
let limit = 4.0

let mandelbrot x y w h =
let cr = 2.0 *. x /. w -. 1.5 in
let ci = 2.0 *. y /. h -. 1.0 in
let rec aux i zr zi = if i >= niter then 0 else
let nzr = zr *. zr -. zi *. zi +. cr
and nzi = 2.0 *. zr *. zi +. ci in
if nzr *. nzr +. nzi *. nzi > limit then 255-i
else aux (i+1) nzr nzi in
aux 0 0.0 0.0

let draw_fractal xoff yoff w h =
pbinit (fun i ->
let y, x = quot_rem i w in
mandelbrot (float (xoff+x)) (float (yoff+y)) (float w) (float h)
) (w*h)

let blend a b w h =
let c = pbinit (fun i ->
let y, x = quot_rem i w in
let r = ord (suget b i) / 32 in
let x1 = max (x-r) 0
and x2 = min (x+r) (w-1) in
saverage (ssub (y*w+x1) (x2-x1+1) a)
) (slen a) in
pbinit (fun i ->
let y, x = quot_rem i w in
let r = ord (suget b i) / 32 in
let y1 = max (y-r) 0
and y2 = min (y+r) (h-1) in
saverage (ssubStride w (y1*w+x) (y2-y1+1) c)
) (slen a)

let square_fractal d =
let frac1 = draw_fractal 0 0 d d in
let frac2 = draw_fractal (d/4) (-d/4) d d in
let header = sprintf "P5 %i %i 255\n" d d in
header ^ (blend frac1 frac2 d d)

let () =
let img = square_fractal (parseInt Sys.argv.(1)) in
output_string stdout img
Post a Comment

Blog Archive

About Me

My photo

Built art installations, web sites, graphics libraries, web browsers, mobile apps, desktop apps, media player themes, many nutty prototypes, much bad code, much bad art.

Have freelanced for Verizon, Google, Mozilla, Warner Bros, Sony Pictures, Yahoo!, Microsoft, Valve Software, TDK Electronics.

Ex-Chrome Developer Relations.