220 likes | 408 Views
Painterly Rendering with Curved Brush Strokes of Multiple Sizes. Aaron Hertzman, NYU Presented by: Shreeganesh Ramanan. Introduction. Painterly Rendering is a method of reproducing artistic style and expression of a painting using a source image and/or 3D models An Image Space Technique
E N D
Painterly Rendering with Curved Brush Strokes of Multiple Sizes Aaron Hertzman, NYU Presented by: Shreeganesh Ramanan
Introduction • Painterly Rendering is a method of reproducing artistic style and expression of a painting using a source image and/or 3D models • An Image Space Technique • A few steps beyond what PhotoshopTM offers.
Things to discuss • “curved brush strokes of multiple sizes” • Implementation details(as little as possible ) • Various parameters and what they can do
So you want to be an artist ? • Do you have lot of time ? • A huge smattering of skill ? • That elusive thing called talent • And some canvas, paints, a subject, and a dirty rag you call work clothes
Previous Work… • One brush size only • No multiple passes to refine style • Support for one style only • Image looks “flattened”
Previous Work.. • But details need different sized strokes
Advantages • Faster than painting • Can be used for interactive rendering • Multiple brush sizes allow for varying detail and continuous color regions • Multipass method similar to how artist paint • Different parameters create different styles
Main Loop function paint (sourceImage, R1 … Rn) { canvas := a new constant color image // paint the canvas foreach brush radius Ri, from largest to smallest do { // apply Gaussian blur referenceImage = sourceImage * G(fσRi) // paint a layer paintLayer(canvas, referenceImage, Ri) } returncanvas }
Painting a Layer function paintLayer(canvas, referenceImage, R) { S := a new set of strokes, initially empty D := difference(canvas, referenceImage) grid := fg R forx=0 to imageWidth stepsize grid do{ fory=0 to imageHeight stepsize grid do{ M := the region(x-grid/2…x+grid/2, y-grid/2…y+grid/2) areaError := sumOfError(M, D) / grid2 if (areaError > T) then { (x1, y1) := maxPoint(areaError) stroke := makeStroke(R, x1, y1, referenceImage) add stroke to S } } } paint all strokes S on canvas – random order }
Curved Brush Strokes • Anti-aliased cubic B-Splines • Each stroke models the color gradient of reference image • Representation • Control Points • Color • Size of brush
Spline Stroke Algorithm function makeSplineStroke(x0, y0, R, refImage) { strokeColor = refImage.color(x0, y0) K := new stroke, radius R, color strokeColor add point (x0, y0) to K (x, y) := (x0, y0) (lastDx, lastDy) := (0, 0) fori=1 to maxStrokeLength do{ if (i > minStrokeLength and(|refImage.color(x,y) – canvas.color(x,y)| < |refImage.color(x,y)- strokeColor)) thenreturnK if (refImage.gradientMag(x,y) ==0) thenreturn K (gx, gy) := refImage.gradientDirection(x, y) (dx, dy) := (-gy, gx) if (lastDx * dx + lastDy * dy < 0) then (dx, dy) = (-dx, -dy) (dx, dy) := fc * (dx,dy) + (1-fc) * (lastDx,lastDy) (dx, dy) := (dx,dy)/(dx2 + dy2)1/2 (x, y) := (x + R*dx, y + R*dy) (lastDx, lastDy) := (dx, dy) add the point (x, y) to K } return K }
G1 (x2, y2) θ1 G0 (x1, y1) G2 θ0 (x0, y0) Calculating Control Points D1 D0
Parameters of Style • Approximation Threshold (T) • Brush Sizes – Smallest (Ri), Number (n), Size Ratio (Ri-1/Ri) • Curvature Filter (fc) • Blur Factor (fσ) • Min and max stroke lengths (minLength, maxLength) • Opacity (α) • Grid size (fg) • Color Jitter (jh, js, jv, jr, jg, jb)
Experiments in Style Source Image
Experiments in Style Impressionist
Experiments in Style Expressionist
Experiments in Style Colorist Wash
Experiments in Style Pointillist