1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import random
- import copy
-
- import numpy as np
- from skimage.restoration import estimate_sigma
-
- from .expr import *
- from .fractdim import *
-
- alpha=32
- calpha = lambda n, c=255, a=10: -int(((c*a/255)-c)*(1-(1-a/255)**n))
- calphas = [[calpha(i, c, alpha) for i in range(0x1000)]
- for c in range(256)]
-
- class IFS2(object):
- """ @brief 1 Variable IFS with X,Y decomposition """
-
-
- #height=width=1024
- height=width=512
-
- def __init__(self, nexpr=4, init_sz=1, world=None, alpha=16):
- self._alpha = alpha
- self._nexpr = nexpr
- self._expr = [RpnExpr(sz=init_sz, nvar=1)
- 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._position = [self.height//2, self.width//2]
-
- @classmethod
- def get_world(cls):
- return np.zeros((cls.height,cls.width), dtype=np.uint32)
-
- def raz_world(self):
- for i in range(self.height):
- for j in range(self.width):
- self._world[i][j] = 0
-
- def __str__(self):
- return ";".join([str(e) for e in self._expr])
-
- def __copy__(self):
- ret = IFS2(nexpr=self._nexpr, world=self._world)
- ret._expr = [copy.copy(e) for e in self._expr]
- #ret._world = copy.deepcopy(self._world)
- return ret
-
- def mutation(self, n=1, rand=True):
- n = 1 if n <= 1 else random.randint(1,n)
- for _ in range(n):
- random.choice(self._expr).mutation()
-
- def step(self):
- arg = self._position[0]
- arg <<=32
- arg += self._position[1]
-
- ret = int(random.choice(self._expr).eval(arg))
-
- self._position[1] = (ret & 0xFFFFFFFF)%self.width
- ret >>= 32
- self._position[0] = (ret & 0xFFFFFFFF)%self.height
-
- self._world[self._position[0]][self._position[1]] += 1
-
- def get_image(self, color=(0,0xFF,0x0)):
- return np.array([[[calpha(n, c, self._alpha) if n and c else 0 for c in color]
- for n in line]
- for line in self._world], dtype=np.uint8)
-
-
- def score(self):
- #maxi = self._world.max()
- #mini = self._world.min()
- #gray = np.array((self._world - mini)/(maxi-mini)*255, dtype=np.uint8)
- gray = np.array([[calpha(n, 255, self._alpha) if n else 0
- for n in line]
- for line in self._world], dtype=np.uint8)
- sigma = estimate_sigma(gray, multichannel=False, average_sigmas=True)
- sigma = 0 if np.isnan(sigma) else sigma
- score = fractal_dimension(gray, 128)
-
- if sigma and sigma > 5:
- score /= sigma/5
- return score
|