Markov Chain Image Generator

Youmingzhang
3 min readNov 6, 2020

--

I learned the Markov chain which is used to generate text based on probability. It basically encodes each character after the first one into a dictionary based on the character’s positions. For example, the word “apple” encode to the Markov chain will be:

{a: p , p: p, p:l, e:l}. This is for only one character at a time. And using this dictionary I can create new words. Let's say I randomly picked p then I pick the next character will be l or p. If I picked l then this is my word — “pl” or if I picked an as starting character I may have something “ apple” or “apl”.

I think incorporating this idea with images is fun to explore. I found the algorithm from google to implement the Markov chain

Read in a training `image` into an array of pixelsCreate a mapping `colourMap` from pixel colour to a pixel counter colour.
For each `pixel` in `image`:
For each `neighbour` of `pixel`:
`mapping[pixel.colour][neighbour.colour] += 1`
Create a blank `newImage`
Choose a random `startingPosition` within the bounds of `newImage`
Choose a random `startingState` from `mapping`
Create a `stack` with `[startingPosition]`
`image[startingPosition] = startingState`
while `stack` is not empty:
`pixel = stack.pop()`
For each `neighbour` of `pixel`:
if `neighbour.isColoured`:
continue
`neighbour.isColoured = true`
Push `neighbour` to `stack`
`neighbour.colour = ` randomly chosen colour from `mapping[pixel.colour].keys()`. Probability distribution is `mapping[pixel.colour].counts() / sum(mapping[pixel.colour].counts())`
Display `newImage`

The idea is to first encode all pixels from an image. Just like text, I used the pixels adjacent to that pixel within the range of 1 and put them into the dictionary. Then generate an image from it. I pick a random color at a random position and fill some other pixels using its neighbor. The result is a noised image with colored background from the original image which is quite interesting.

This is the original image:

These are generated ones:

Debugging code took me some time. I also noticed that using img.set(x,y,color()) too so much time and it made my program froze. I changed the method to set image pixels using array and it run much faster.

--

--

No responses yet