- Weighted Voronoi Stippling
- Painterly Rendering
- mustache.js improved
- TorrentUploader
- Entropy Solitaire
- Tone Preservation with Ice Crystal Growth
- DSGrab



Official Artifact - Stencilled Stooges
The tool that was used to create renderings that are sampled in this assignment is a Java Swing application which allows the user to interactively modify all of the parameters that were described in the original paper by Hertzmann in addition to parameters associated with edge rendering for the assignment extension. The JHLabs Image Processing Filters were used to perform the Gaussian Blur filter described in the paper. The generic Convolution filter in the JHLabs package was also adapted to create the Sobel operator required for edge detection. The default JTabbedPane Swing component does not have a means of rendering the tab title rotated 90, so a small Java class which added this functionality was used (courtesy of Santhosh Kumar).
The user interface for the tool logically groups the parameters described in the paper and uses a slider based interface for modifying the parameters. Since the algorithm does not work in real time, the contents of the display pane are not updated until the user presses the “Apply Parameters” button in the interface. The interface additionally provides 4 presets which match the different painting styles that Hertzmann uses as examples on page 6 of the paper. Figure 1 shows the user interface for the painterly rendering generation tool.
Figure 1 - Screenshot of the UI in ActionIn Hertzmann’s paper the psuedocode describes clearing the canvas to a “special” colour such that the colour difference calculation returns the maximum possible value regardless of actual colour. For the purposes of this tool, this description is implemented as an additional 1-bit mask of the canvas, that is initially cleared to all 0. Whenever a stroke is placed on the canvas, the mask is set to 1. The color difference function takes this into account and returns MAX_DIFFERENCE whenever the mask is 0.
Hertzmann suggests using the OpenGL depth buffer to randomize the placement of strokes. Since the Java Graphics Library does not have a dedicated depth buffer, an alternative approach had to be taken. Each jittered grid location that is going to receive a colour is first stored in a list, and then once the entire layer has been scanned, elements are randomly pulled from the list and strokes are placed on the canvas. This is obviously a more space hungry algorithm as compared to using the Depth Buffer, but it is not as bad as buffering all of the strokes that would be painted, since the algorithm only needs to store a (x,y) coordinate in memory.
Generally speaking, the reimplemented algorithm works well. There are certain instances where this implementation seems to produce inadequate results in comparison with the initial by Hertzmann. In particular, the following areas seem to be problematic:
Interestingly, colour jittering had to be implemented before the “Expressionist”, “Colourist Wash”, and “Pointillist” gave reasonable renderings. The original intent was to not implement this portion of the paper, but inadequete results forced it.
To get edges that fit into the painting style defined by the parameters, the following algorithm was added unto the end of the original Painterly Rendering algorithm described by Hertzmann:
- Clear 1-Bit Mask so that Canvas is considered to be empty.
- Paint over Source Image in Black “Ink”
- For all (x,y) if gradient(x,y) < Te * max { all gradients } then gradient(x,y) = 0.0
- call paintLayer with the smallest brush size available.
Where Te is the edge threshold parameter.
Note that after the initial output is rendered, the image gradients that have been calculated are for the smallest brush size available, so the edge drawing algorithm can just reuse those gradients.
The bottom half of Figure 3 shows the effects of changing the Te parameters. The left plate is rendered using a higher Te value, whereas the right plate is rendered using a lower value.
The gradient can also be cleaned up a bit before using it for such a sensative operation. For instance, the gradient signal can be denoised to get rid of the black splotches from showing up, or the histrogram of the signal can be tweaked to remove outliers from the signal, producing more defined edges. A better edge detection algorithm will of course provide better hints as to which regions should be painted and which regions should be left.
This photograph was used as a test suite for the algorithm, to ensure that the algorithm gives expected results when compared against the presets defined by Hertzmann.
Both the source code and the Web Start executable are released under the Apache License, Version 2.0.
JTabbedPane extension courtesy of Santhosh Kumar