You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
3.9 KiB

import random
import numpy as np
from maskedImage import MaskedImage
class Nnf:
def __init__(self,input,output,patchSize):
self.input = input
self.output = output
self.patchSize = patchSize
def randomize(self):
self.field = np.zeros((self.input.height, self.input.width, 3), dtype=int)
for x in range(self.input.width):
for y in range(self.input.height):
self.field[y,x,0] = random.randint(0,self.output.width)# peut être un -1 sur les random
self.field[y,x,1] = random.randint(0,self.output.height)
self.field[y,x,2] = MaskedImage.DSCALE
self.initialize()
def initializeFromNnf(self,nnf):
self.field = np.zeros((self.input.height, self.input.width, 3), dtype=int)
fx = int(self.input.width/nnf.input.width)
fy = int(self.input.height/nnf.input.height)
for y in range(self.input.height):
for x in range(self.input.width):
xl = min(int(x/fx),nnf.input.width-1)
yl = min(int(y/fy),nnf.input.height-1)
self.field[y,x,0] = nnf.field[yl,xl,0]*fx
self.field[y,x,1] = nnf.field[yl,xl,1]*fy
self.field[y,x,2] = MaskedImage.DSCALE
self.initialize()
def initialize(self):
for y in range(self.input.height):
for x in range(self.input.width):
self.field[y,x,2] = self.distance(x,y,self.field[y,x,0],self.field[y,x,1])
iter=0
maxIter =20
while (self.field[y,x,2] == MaskedImage.DSCALE and iter<maxIter):
self.field[y,x,0] = random.randint(0,self.output.width)
self.field[y,x,1] = random.randint(0,self.output.height)
self.field[y,x,2] = self.distance(x,y,self.field[y,x,0],self.field[y,x,1])
iter += 1
def minimize(self,nbPass):
for i in range(nbPass):
for y in range(self.input.height-1):
for x in range(self.input.width-1):
if (self.field[y,x,2]>0):
self.minimizeLink(x,y,1)
for y in range(self.input.height-1,0,-1):
for x in range(self.input.width-1,0,-1):
if (self.field[y,x,2]>0):
self.minimizeLink(x,y,-1)
def minimizeLink(self,x,y,direction):
# horizontale
if (0<x-direction<self.input.width):
xp = self.field[y,x-direction,0] +direction
yp = self.field[y,x-direction,1]
dp = self.distance(x,y,xp,yp)
if (dp<self.field[y,x,2]):
self.field[y,x,0] = xp
self.field[y,x,1] = yp
self.field[y,x,2] = dp
# verticale
if (0<y-direction<self.input.height):
xp = self.field[y-direction,x,0]
yp = self.field[y-direction,x,1] + direction
dp = self.distance(x,y,xp,yp)
if (dp<self.field[y,x,2]):
self.field[y,x,0] = xp
self.field[y,x,1] = yp
self.field[y,x,2] = dp
# recherche random
zoneRecherche = max(self.output.height,self.output.width)
while zoneRecherche>0:
xp = self.field[y,x,0] + random.randint(0,2*zoneRecherche)-zoneRecherche
xp = self.field[y,x,1] + random.randint(0,2*zoneRecherche)-zoneRecherche
xp = max(0,min(self.output.width-1,xp))
yp = max(0,min(self.output.height-1,yp))
dp = self.distance(x,y,xp,yp)
if (dp<self.field[y,x,2]):
self.field[y,x,0] = xp
self.field[y,x,1] = yp
self.field[y,x,2] = dp
zoneRecherche = int(zoneRecherche/2)
def distance(self,x,y,xp,yp):
return MaskedImage.distance(self.input,x,y,self.output,xp,yp,self.patchSize)