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
| import matplotlib.image as mi
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')
class Color :
def __init__(self, R=0, V=0, B=0, tuple=None) :
if tuple : self.R, self.V, self.B = tuple
else :
self.R = R
self.V = V
self.B = B
def __add__(self, other) : # Addition
r,v,b = self.R+other.R, self.V+other.V, self.B+other.B
return Color(r,v,b)
def __truediv__(self, k) : # Division
r, v, b = self.R/k, self.V/k, self.B/k
return Color(r,v,b)
# Shortcuts
def __iadd__(self, other) : return self+other
def __itruediv__(self, k) : return self/k
# Euclidian distance to another color
def absolute_distance(self, other) :
r = (self.R-other.R)**2
v = (self.V-other.V)**2
b = (self.B-other.B)**2
return (r+v+b)**.5
# Closest color according dictionary
def closest_color(self) :
min_dist, color = 1, 'black'
for color,code in colors.items() :
dist = self.absolute_distance(code)
if dist < min_dist : min_dist, match = dist, color
return match
# Return 4-items array to fill imread
def tolist(self) : return [self.R, self.V, self.B, 1]
#Defining arbitrary colors
colors = {
'background':Color(0,0,1),
'brown':Color(88/255,41/255,0),
'green':Color(0,1,0),
'white':Color(1,1,1),
'yellow':Color(1,1,0),
'black':Color(0,0,0),
'red':Color(1,0,0),
'orange':Color(1,.5,0)
}
# Loading images
goodleaf = mi.imread('goodleaf.png')
badleaf = mi.imread('badleaf.png')
# Defining green-reference / Not really useful for this animation...
#C = 256
#r,v,b,n = 0,0,0,0
#for i in range(goodleaf.shape[0]) :
# for j in range(goodleaf.shape[1]) :
# R,V,B,_ = goodleaf[i][j]
# if R>40/C and B<200/C and V>40/C :
# r += R
# v += V
# b += B
# n += 1
#
#greenColor = (r/n,v/n,b/n)
#colors['green'] = Color(tuple=greenColor)
# Create matrix, transform RGB color to [0,1,2] color
matrix = []
infected = []
cleanedleaf = badleaf.copy()
for i in range(badleaf.shape[0]) :
line = []
for j in range(badleaf.shape[1]) :
R,V,B,_ = badleaf[i,j]
closest = Color(R,V,B).closest_color()
cleanedleaf[i,j] = colors[closest].tolist() # Determine the closes color
if closest == 'background' : line.append(0)
elif closest == 'white' :
line.append(2)
infected.append((i,j))
else : line.append(1)
matrix.append(line)
# Propagation
rounds = 20
for r in range(rounds) :
new_infected = [] # Creating a tuple-list of new infected for next iteration
for px,py in infected :
for i in [-1,0,1] :
for j in [-1,0,1] :
if i==j : continue # Squeeze the center, which is already equals to 2
pxi, pyj = px+i, py+j
if matrix[pxi][pyj] == 1 : # If was not infected, not it is !
matrix[pxi][pyj] = 2
new_infected.append((pxi, pyj))
cleanedleaf[pxi,pyj] = [1,1,1,1] # Infected cell in RGB is white
infected = new_infected # Update infected list
# Animation of propagation
plt.imshow(cleanedleaf)
plt.title('Iteration n°%d'%r)
plt.pause(0.1) |