Introduction
Introduction
Main algorithm
Image Abstraction
Image Moments
StrokeAreaImage
ColorDifferenceImage
StrokePositionsImage
StrokeParameters
Scale/Rotate
Blend
The Program
Gallery
Download


This project was develop by 

for the Image Processing for Vision and Graphics course at IMPA.

This work is about a technique to automatically render images with painterly aspect. It is based on Shiraishi and Yamaguchi's paper. There have been some changes to the original work in our implementation. In the following section we will present the results of our work.

The painterly rendering process described in this work basically tries to reproduce the painting process; bigger strokes comes first, later being refined by smaller strokes. In other words, this method tries to automatically approximate a given region of the image by one or more strokes.

The process includes finding the right place, size, orientation, color and scheduling for each stroke to be painted is seen below.

 

Main Algorithm

The main function creates a painted version from an Input image. As extra input parameters, it receives a monochrome Stroke image and two real numbers: parameter s controlling the level of detail of the generated image and parameter p, added  by the group (see StrokePositions)

PaintedImage(Input, Stroke, s, p)  begin
  Area = StrokeAreaImage(Input, s)
  Pos = StrokePositionsImage(Area, s, p)
  List = NewList()
  for P:(x, y) in Pos do
    Insert(List, StrokeParameters(Input, x, y))
  Sort(List, byArea)
  Output = NewImage(Width(Input), Height(Input), White)
  for L:(w, l, xc, yc, q, C) in List do
    Blend(Output, Rotate(Scale(Stroke, w, l), q), xc, yc, C))
  return Output
end

The algoritm calculates the distribution and position of the strokes. Then, for each stroke, it calculates the stroke parameters, storing them in a list. After sorting the list by stroke area, the algorithm paints each stroke over a blank image.

 

Image Moments

Image Moments are summations of the form:

Note that if I is a monochrome image, then M00 is the area of the image.

Momment(l, m, Input)  begin
 
mom = 0
  for x := 1 to Width(Input) do
    for y := 1 to Height(Input) do
       mom = mom + Color(Input, x, y) * Power(x, l) * Power(y, m)
  return sum

end

Image Moments are used in the computation of the StrokeAreaImage and StrokeParameters.

 

Image Abstraction

The several image manipulation operations performed by the algorithm require an image abstraction that provides support for both RGB and monochrome images, as well as fast region copy and blending capabilities.

/* pixel format: mamata */
typedef enum e_imagetype {
  IMAGE_MONO = 1,
  IMAGE_RGB = 3
} e_imagetype;

/* image data type */
typedef struct t_image {
  e_imagetype type; 
  int width, height; 
  int row;
  int reference; 
  uchar *buffer;
} t_image;

Image abstraction and structure in C

The choice was to optimize region extraction by sharing image parts instead of copying them. The abstraction also optimizes screen block transfer by storing pixels in the OS format.

 

StrokeAreaImage

The StrokeAreaImage is a non-linear high-pass filter. The result image is darker where there are high frequencies in the Input image and lighter where the frequencies are low. The parameter s controls the size of the neighborhood considered for each pixel.

StrokeAreaImage(Input, s) begin
  Output = NewImage(Width(Input), Height(Input), White)
  for (x,y) in Input do
    C = Crop(Input, x, y, s)
    D = ColorDifferenceImage(C, Color(Input, x, y))
    Set(Output, x, y, Moment(0, 0, D))
  return Output
end

Below we see several StrokeAreaImage examples.

The original image and corresponding StrokeAreaImage for values 30, 15, 10, 5 and 2 of the parameter s.