123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- import random
- import time
- import copy
-
- import numpy as np
- from skimage.restoration import estimate_sigma
-
- from .expr import *
- from .fractdim import *
-
-
- class IFS5(object):
- """ @brief 1 Variable IFS with R,G,B,A X,Y decomposition """
-
- #height=width=1024
- height=width=768
- #height=width=512
-
- def __init__(self, nexpr=4, init_sz=1, world=None):
- self._nexpr = nexpr
- self._expr = [[RpnExpr(sz=init_sz, nvar=6) for _ in range(6)]
- for _ in range(nexpr)]
- self._world = world
- if self._world is None:
- self._world = self.get_world()
- self._position = [random.randint(0, self.height-1),
- random.randint(0, self.width-1)]
- self._col = [random.randint(0, 255) for _ in range(4)]
-
- @classmethod
- def get_world(cls):
- return np.zeros((cls.height,cls.width,4), dtype=np.uint8)
-
- def raz_world(self):
- for i in range(self.height):
- for j in range(self.width):
- self._world[i][j] = [0,0,0,0]
-
- def __str__(self):
- el_lbl = 'XYrgba'
- fel = lambda el: ';'.join(['%s=(%s)' % (el_lbl[i], str(el[i]))
- for i in range(len(el))])
- ret = ';'.join(['<%s>' % fel(el) for el in self._expr])
- return ret
-
- def __copy__(self):
- ret = IFS5(nexpr=self._nexpr, world=self._world)
- ret._expr = [[copy.copy(e) for e in el]
- for el in self._expr]
- #ret._world = copy.deepcopy(self._world)
- return ret
-
- def get_image(self):
- return self._world
-
- def mutation(self, n=1, rand=True):
- n = 1 if n <= 1 else random.randint(1,n)
- for _ in range(n):
- random.choice(random.choice(self._expr)).mutation()
-
- def step(self):
- dr,dg,db,da = [int(e)
- for e in self._world[self._position[0]][self._position[1]]]
-
- cx = int((self._position[0] / self.width) * ((1<<64)-1))
- cy = int((self._position[0] / self.height) * ((1<<64)-1))
-
- args = (cx,cy,dr,dg,db,da)
- rx,ry,r,g,b,a = (int(expr.eval(*args))
- for expr in random.choice(self._expr))
- rx = (rx * (self.width-1)) // ((1<<64)-1)
- ry = (ry * (self.height-1)) // ((1<<64)-1)
- self._position[0], self._position[1] = rx, ry
- r,g,b,a = (c%256 for c in (r,g,b,a))
-
- sa = a/255
- outa = (a + da*(1-sa))/255
- if outa == 0:
- ro,go,bo = 0,0,0
- else:
- ro, go, bo = [(c*(a/255)+dc*da*(1-sa))/outa
- for c, dc in ((r,dr), (g, dg), (b, db))]
- r,g,b,a = [int(e) for e in (ro,go,bo,outa*255)]
-
-
- self._world[self._position[0]][self._position[1]] = [r,g,b,a]
-
- def score(self):
- start = time.time()
-
- colcount = len(np.unique(np.reshape(self._world[:,:,:3], (-1,3)),
- axis=0))
-
- #sigma = estimate_sigma(self._world, multichannel=True, average_sigmas=True)
- sigmas = estimate_sigma(self._world[:,:,:3], multichannel=True,
- average_sigmas=False)
-
- scores = [fractal_dimension(self._world[:,:,i]*self._world[:,:,3]/255)
- for i in range(3)]
- #alpha score
- #scores += [fractal_dimension(self._world[:,:,3])]
-
- gray = rgb2gray(self._world)
- graysigma = estimate_sigma(gray)
- grayscore = fractal_dimension(gray)
- del(gray)
-
- sigmas += [graysigma]*3
- sigmas = [0 if np.isnan(sigma) else sigma for sigma in sigmas]
-
- scores += [grayscore]*3
-
- sigma = sum(sigmas)/len(sigmas)
-
- mod = abs(scores[0]-scores[1])
- mod += abs(scores[0]-scores[2])
- mod += abs(scores[0]-scores[3])
- mod += abs(scores[1]-scores[2])
- mod += abs(scores[1]-scores[3])
- mod /= 5
-
- null_comp = 0
- for i in range(3):
- null_comp += 1 if scores[i] == 0 else 0
-
- if null_comp >= 2:
- score = 0
- mod *= 0.8
- else:
- score = sum(scores)/len(scores)
-
- score += mod
-
- if sigma and sigma > 0:
- score -= sigma/100
- #colscore = abs(colcount-1024) / 1e5
- colscore = abs(colcount-2048) / 1e5
- score -= colscore
-
- printscore = lambda arr: '['+(', '.join(['%1.3f' % e for e in arr]))+']'
- print("colscore %3.3f (%4d colors) scores time %5.2fs" % (colscore,
- colcount,
- time.time() - start))
- print("SIGMAS : %s SIGMA : %f " % (printscore(sigmas), sigma))
- print("SCORES : %s SCORE : %r" % (printscore(scores), score))
- return score
|