Piet Mondrian is best known for his paintings of simple rectangular forms and lines. Since they appear fairly straightforward, I thought it would be possible to develop some code to make lookalike images.
I made some choices in the code below to make things a little easier. After first creating an empty, white image, positions for all horizontal and vertical lines are chosen, with the limit that they must be at least five pixels apart and five pixels from the edge. Next about half are chosen to be full-length lines. Then, the remaining lines are given endpoints either at the edge or on one of the full-length lines.
Once the lines are drawn, a loop chooses a random white point in the image and finds its dimensions, defining a rectangle. That rectangle is then filled with a random choice from the palette defined near the beginning.
Depending on the parameters chosen, the result can be Mondrian-like, or something very different.
from PIL import Image
import random
####################
#Parameters
####################
mond_size_x = 200
mond_size_y = 200
num_lines_x = 10
num_lines_y = 10
fields_wanted = 15
images_wanted = 1
#####################
#Some color definitions
#####################
blue = (0,0,255)
red = (255,0,0)
yellow = (255,255,0)
illini_blue_bold = (0,60,125)
illini_orange_bold = (244,127,36)
illini_blue_prof = (110,139,191)
illini_orange_prof = (239,138,28)
darkgreen = (0,100,0)
darkred = (139,0,0)
forestgreen = (34,139,34)
rand1 = (random.randrange(0,255), random.randrange(0,255), random.randrange(0,255))
###################
#Palette choice
###################
final_palette = [yellow, blue, red,]
##################
#Image production
##################
imagecounter = 1
while images_wanted >= imagecounter:
###Makes empty image
Mond1 = Image.new("RGB",(mond_size_x,mond_size_y))
Mond1_pixels = Mond1.load()
for i in range(0,mond_size_x):
for j in range(0,mond_size_y):
Mond1_pixels[i,j] = (255,255,255)
###Pick line positions
good = 0
vind = []
hind = []
while good < 1:
poss_index_x = range(4,mond_size_x-6)
for j in range(num_lines_x):
thisx = random.choice(poss_index_x)
vind.append(thisx)
for q in range(thisx - 5, thisx + 5):
if q in poss_index_x:
poss_index_x.remove(q)
poss_index_y = range(4,mond_size_y-6)
for j in range(num_lines_y):
thisy = random.choice(poss_index_y)
poss_index_y.remove(thisy)
hind.append(thisy)
for q in range(thisy - 5, thisy + 5):
if q in poss_index_y:
poss_index_y.remove(q)
good = 1
shorth=[]
shortv=[]
fullh = random.sample(hind,num_lines_y/2)
fullv = random.sample(vind,num_lines_x/2)
for j in fullh:
for r in range(mond_size_x):
Mond1_pixels[r,j] = (0,0,0)
for j in fullv:
for r in range(mond_size_y):
Mond1_pixels[j,r] = (0,0,0)
hends = [0,mond_size_y]
vends = [0, mond_size_x]
for j in fullv:
vends.append(j)
for j in fullh:
hends.append(j)
for j in vind:
if j not in fullv:
shortv.append(j)
for j in hind:
if j not in fullh:
shorth.append(j)
for k in shorth:
ends = random.sample(vends,2)
ends.sort()
for p in range(ends[0] ,ends[1] ):
Mond1_pixels[p,k] = (0,0,0)
for k in shortv:
ends = random.sample(hends,2)
ends.sort()
for p in range(ends[0],ends[1]):
Mond1_pixels[k,p] = (0,0,0)
###Fill the fields
total_fields = 0
while total_fields < fields_wanted:
###Pick random white pixel
done = 0
while done != 1:
rand_row = random.randrange(0,mond_size_y)
rand_col = random.randrange(0,mond_size_x)
if Mond1_pixels[rand_col,rand_row] == (255,255,255):
done = 1
###Grow down
this_pixel_row = rand_row
this_pixel_column = rand_col
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
while this_pixel_color == (255,255,255):
if this_pixel_row < (mond_size_y - 1):
this_pixel_row = this_pixel_row + 1
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
else:
this_pixel_color = (0,0,0)
this_pixel_row = this_pixel_row + 1
bottom_white_row = this_pixel_row-1
###Grow up
this_pixel_row = rand_row
this_pixel_column = rand_col
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
while this_pixel_color == (255,255,255):
if this_pixel_row > 0:
this_pixel_row = this_pixel_row - 1
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
else:
this_pixel_color = (0,0,0)
this_pixel_row = this_pixel_row - 1
top_white_row = this_pixel_row+1
###Grow right
this_pixel_row = rand_row
this_pixel_column = rand_col
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
while this_pixel_color == (255,255,255):
if this_pixel_column < (mond_size_x - 1):
this_pixel_column = this_pixel_column + 1
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
else:
this_pixel_color = (0,0,0)
this_pixel_column = this_pixel_column + 1
right_white_column = this_pixel_column-1
###Grow left
this_pixel_row = rand_row
this_pixel_column = rand_col
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
while this_pixel_color == (255,255,255):
if this_pixel_column > 0:
this_pixel_column = this_pixel_column - 1
this_pixel_color = Mond1_pixels[this_pixel_column,this_pixel_row]
else:
this_pixel_color = (0,0,0)
this_pixel_column = this_pixel_column - 1
left_white_column = this_pixel_column+1
###Pick field color
this_color = random.choice(final_palette)
###Fill field
for i in range(top_white_row,bottom_white_row+1):
for j in range(left_white_column,right_white_column+1):
#Mond1_pixels[j,i] = random.choice(avail_colors) #This is freaky
Mond1_pixels[j,i] = this_color
total_fields = total_fields + 1
imagename = "Mond"+str(imagecounter)+".png"
Mond1.save(imagename,'PNG')
imagecounter = imagecounter + 1
Some examples...
First, a 50 pixel by 50 pixel image.
500 by 500:
And something for Christmas:
Hello, do you still have your tutorial for viewing light curves in python?
ReplyDeleteThanks
I've put it back up. It's pretty out-of-date; try astropy in place of PyFITS. It should work about the same.
Delete