Skip to end of metadata
Go to start of metadata


In this project I wrote an application that makes impressionist style paintings from photographs.

I hear birds chirping outside. Is this a bad thing?

Explanation of Algorithms

One of the most prominent characteristics of impressionist paintings is the relatively small, thin, yet visible brush strokes. My program aims to simulate this style.

Each stroke is represented by a Stroke object, which consists of the following information:

The stylization process consists of several steps:

Stroke Initialization

In this process, a grid of strokes is created. Each location in the grid corresponds to a pixel location in the source image. We loop through the grid and initialize each stroke with length, orientation and thickness. These values are randomly generated around a certain anchor values. The color of the stroke is the same as the color at the corresponding pixel location. The orientation can also be generated according to the gradient at the pixel location.

The gradient image can be calculated quickly using image filters that scipy provides.


In this process, with the stroke information, we loop through the output image and draw lines with the given location, thickness and orientation from the initialization process.

Stylize 3D

Prof Maxwell gives me the idea of simulating the "bumpy" effect on paintings due to the variation in the amount of paint across the image. To do this, I use a depth map - an 2D array of the same dimensions as the output image. The values in this array indicate how thick the paint is at each pixel location. To do this, every time I draw a stroke into the output image, I draw a stroke with the same size, thickness and location on the depth map. The only difference is the color is (1,1,1).

An example of a depth map. Brigher pixels indicate thicker paint.

A light direction vector is then specified, which determines which sides of the "hills" will be bright and which will be dark.


The pictures on the left are original, on the right are generate by my program.

Left to right: Original, Result with orientation and thickness generated randomly (I think I have to make it more random to achieve to angle variation), Result with orientation according to gradient.



Bumpy painting:

  • No labels