Skip to content

akilmarshall/procedural-image-generation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Procedural Image Generation

How can I turn a single image into more images that are somewhat like it?

Todo

  • implement tile sheet dump [rust]
  • implement neighbor function visual dump [rust]
  • write code to make animated gifs from MCI algorithms

Constrained Backtracking Search

(this example uses this image as input)

Also known as Wave Function Collapse (tiled model)

When tasked with completing a blank image this algorithm's run time and output is enormous (2x2 and sometimges 3x3 can be computable). It is often more interesting to provide it with a "seeded" image:

-->

5x5 fix (3, 3) with the door tile

This door tile only appears once in the original image thus a large portion of the image space is constrained, however an enormous amount of variety is still observed in the outputs.

-->

5x5 fix several bike paths

I was curious to see what would happen with the bike paths. In this example their generation is more constrained then I expected but this may not hold up to further testing.

-->

5x5 fix (3, 3) with a mud slide tile

I wanted to see what kind of areas could be placed around the mud slide. I expected that the path in and out would be fairly constrained and the left and right allowed to vary wildly, it was in fact the opposite.

-->

4x4 fix corner lake tiles

I wanted to see what the algorithm was able to come up with given minimal input and I am quite pleased with the output.

-->

14x5 fix several corner roof tiles

I wanted to test building a larger image leaning on the algorithm to fill in large areas. Initially I believed that sucessively building an image and feeding larger and larger inputs would be the work flow, however this only increasese the search space over "every" (read many) variation which is theoritically comforting but practically useless. Edge exapnding and filling in small areas with fixed sections feels like the correct way to use this tool.

Examples

Using the following image as input

minimal input example

Made up of the following tileset

It's neighbor functions are visualized below

For this incredibly minimal input image each algorithm produced only 10 outputs each. Each algorithm was able to produce the original image, in fact each algorithm produced the exact same output. This is not to be expected and is perhaps an artifact of the simplicity of the input image, the exact reasons are currently unknown.

The images are in no particular order.

CENTER algorithm output

CORNER algorithm output

SIDE algorithm output

  1. Begin with an image
  2. Select the tile with the least conformity (halt if all conforming or done)
  3. change it's neighbors to tiles from it's neighbor sets (force conformity)
  4. goto 2

Several runs of this naive algorithm produce the following select output

10x10 fitness score 50

10x10 fitness score 220

10x10 fitness score 130

A perfect image would have a score of 400.