Painterly Rendering with Curved Brush Strokes
Learn a method to recreate painting styles using images and 3D models, emphasizing curved brush strokes of various sizes for artistic expression. Discuss implementation details and parameters for different styles.
Painterly Rendering with Curved Brush Strokes
E N D
Presentation Transcript
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