-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathillustration.py
122 lines (98 loc) · 3.68 KB
/
illustration.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""
MINERAL ILLUSTRATOR
A tool to reduce the colors of a photo to a given colorpalette.
Please provide the following inputs in your directory:
1) A photo named input.png. It is recommended to scale it down to a low resolution e.g. 300x200
2) A csv-table colors.csb where you list the desired colors. The following convention is used:
#ff444b cherry_red - f
#40cc9a darkgreen HB f
#389075 darkgreen 4H f
So the scheme is:
[html-color] [crayon] [pencil] [comment]#
[crayon]: freely chosen name of the colored pencil
[pencil]: the values -,4H, H, B, 4B are accepted, where "-" means that the crayon wasnt shaded by a pencil.
[comment]: you may add anything. I used it to distinguish between how firmly i applied pressure with the crayon.
"""
import numpy as np
import matplotlib.pyplot as plt
import csv
from PIL import Image
def html_to_rgb(html_colors):
"""
Turns the list of html strings into a list of tuple with 3 integers
"""
rgb_list = []
for color in html_colors:
color = color.lstrip('#')
rgb = (int(color[0:2], 16),int(color[2:4], 16),int(color[4:6], 16))
rgb_colors.append(rgb)
return rgb_list
#-----READING THE PALETTE-----
raw=[] #In this list, the entire row will be stored
html_colors=[] #In this list, only the color will be stored
with open("colors.csv", 'r') as file:
reader = csv.reader(file, delimiter=' ')
for row in reader:
raw.append(row)
html_colors.append(row[0])
RGB_palette = html_to_rgb(html_colors)
R,G,B=[],[],[]
for c in palette_RGB:
R.append(c[0])
G.append(c[1])
B.append(c[2])
#-----READING THE IMAGE-----
image = Image.open('input.png')
photo = image.convert('RGB')
photo = np.array(photo)
#print("Image shape:", photo.shape)
#-----POSTERIZE-----
#Initialize the arrays:
painting = np.zeros(photo.shape,dtype=int) #output image
hue = np.zeros(photo.shape,dtype=int) #crayons-only decomposition
pencil = np.zeros((len(photo),len(photo[0])),dtype=int) #pencil-only decomposition
numbers=np.zeros((len(photo),len(photo[0])),dtype=int) #the "primary keys" like in paint by numbers
used_colors=[] #To generate a list of the colors needed for the painting
for i in range(len(photo)):
for j in range(len(photo[0])):
(R_real,G_real,B_real)=photo[i][j]
#find the best match
k=0
k_ideal=0
delta=999999999
while k<len(raw):
if ((R[k]-R_real)**2)+((G[k]-G_real)**2)+((B[k]-B_real)**2)<delta:
delta=((R[k]-R_real)**2)+((G[k]-G_real)**2)+((B[k]-B_real)**2)
k_ideal=k
k+=1
painting[i][j][0]=int(R[k_ideal])
painting[i][j][1]=int(G[k_ideal])
painting[i][j][2]=int(B[k_ideal])
#find k_hue,which is the index of the color we get when stripping the pencil shading from the best matching color
for n in range(max(0,k_ideal-10),min(len(raw),k_ideal+10)):
if raw[n][1]==raw[k_ideal][1] and raw[n][2]=="-" and raw[n][3]==raw[k_ideal][3]:
k_hue=n
hue[i][j][0]=int(R[k_hue])
hue[i][j][1]=int(G[k_hue])
hue[i][j][2]=int(B[k_hue])
pencil[i][j]={"-":0,"4H":1,"H":2,"B":3,"4B":4}[raw[k_ideal][2]] #<--if other pencil hardnesses desired, change here
numbers[i][j]=k_ideal
used_colors.append(k_ideal)
#print(i,j)
#remove redundancies and sort
used_colors=set(used_colors)
used_colors=list(used_colors)
used_colors=sorted(used_colors)
#----OUTPUT----
#Display list of needed colors
for k in used_colors:
print(k,"...\t",raw[k][1],raw[k][3])
#Display results
plt.figure()
plt.imshow(pencil,cmap="binary")
plt.figure()
plt.imshow(hue)
plt.imshow(numbers, alpha=0)
plt.figure()
plt.imshow(painting)
plt.show()