Markov_Image_Generator/Generate Markov Image (alte...

8.0 KiB

In [ ]:
import numpy as np
from PIL import Image
import random
import re
from collections import defaultdict

#Converts image to "text"
def img_to_text(img_val):
    words = []
    for i in img_val:
        #              r                 g               b
        outword = str(i[0]) + ',' + str(i[1]) + ',' + str(i[2])
        words.append(outword)
    return words

#init corpus
corpus = []
#load first image
im = Image.open("bauhaus.jpg", "r")
#Get img text
pix_val = list(im.getdata())
img_text = img_to_text(pix_val)
corpus = corpus + img_text

#load first image
im = Image.open("bauhaus2.jpg", "r")
#Get img text
pix_val = list(im.getdata())
img_text = img_to_text(pix_val)
corpus = corpus + img_text

#load first image
im = Image.open("bauhaus3.jpg", "r")
#Get img text
pix_val = list(im.getdata())
img_text = img_to_text(pix_val)
corpus = corpus + img_text


#markov model
markov_graph = defaultdict(lambda: defaultdict(int))
tokenized_text = corpus
last_word = tokenized_text[0].lower()
for word in tokenized_text[1:]:
  word = word.lower()
  markov_graph[last_word][word] += 1
  last_word = word

# Preview graph.
limit = 3
for first_word in ('the', 'by', 'who'):
  next_words = list(markov_graph[first_word].keys())[:limit]
  for next_word in next_words:
    print(first_word, next_word)

def walk_graph(graph, distance=5, start_node=None):
  """Returns a list of words from a randomly weighted walk."""
  if distance <= 0:
    return []
  
  # If not given, pick a start node at random.
  if not start_node:
    start_node = random.choice(list(graph.keys()))
  
  
  weights = np.array(
      list(markov_graph[start_node].values()),
      dtype=np.float64)
  # Normalize word counts to sum to 1.
  weights /= weights.sum()

  # Pick a destination using weighted distribution.
  choices = list(markov_graph[start_node].keys())
  chosen_word = np.random.choice(choices, None, p=weights)
  
  return [chosen_word] + walk_graph(
      graph, distance=distance-1,
      start_node=chosen_word)
  
chain = []
for i in range(10000):
    chain = chain + walk_graph(markov_graph, distance=12)
print(chain)
In [11]:
def chain_to_rgbbytes(ctext):
    out_list = []
    #for each generated pixel
    for i in ctext:
        #split out values
        i = i.split(",")
        #for each value in a pixel, add the int to the list
        for x in i:
            out_list.append(int(x))
    #return and convert to bytes:
    return out_list
In [12]:
#generate images!

colors = bytes(chain_to_rgbbytes(chain))
img = Image.frombytes('RGB', (100, 100), colors)
img.show()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-d1de3a1e6f5d> in <module>
      2 
      3 colors = bytes(chain_to_rgbbytes(chain))
----> 4 img = Image.frombytes('RGB', (1000, 1000), colors)
      5 img.show()

~\anaconda3\lib\site-packages\PIL\Image.py in frombytes(mode, size, data, decoder_name, *args)
   2656 
   2657     im = new(mode, size)
-> 2658     im.frombytes(data, decoder_name, args)
   2659     return im
   2660 

~\anaconda3\lib\site-packages\PIL\Image.py in frombytes(self, data, decoder_name, *args)
    795 
    796         if s[0] >= 0:
--> 797             raise ValueError("not enough image data")
    798         if s[1] != 0:
    799             raise ValueError("cannot decode image data")

ValueError: not enough image data
In [ ]: