def objectiveFunDef(self, a0, rhot, Afft, withTrajectory = False, withJacobian=False, Init = None, display=False): if Init == None: x0 = self.x0 else: x0 = Init[0] param = self.param timeStep = 1.0/self.Tsize dim2 = self.dim**2 A = [np.zeros([self.Tsize, self.dim, self.dim]), np.zeros([self.Tsize, self.dim])] if self.affineDim > 0: for t in range(self.Tsize): AB = np.dot(self.affineBasis, Afft[t]) A[0][t] = AB[0:dim2].reshape([self.dim, self.dim]) A[1][t] = AB[dim2:dim2+self.dim] #print a0.shape if withJacobian: (xt, at, Jt) = evol.secondOrderEvolution(x0, a0, rhot, param.KparDiff, withJacobian=True,affine=A) else: (xt, at) = evol.secondOrderEvolution(x0, a0, rhot, param.KparDiff, affine=A) #print xt[-1, :, :] #print obj obj0 = 0.5 * (a0 * param.KparDiff.applyK(x0,a0)).sum() obj1 = 0 obj2 =0 for t in range(self.Tsize): rho = np.squeeze(rhot[t, :, :]) obj1 += timeStep* self.controlWeight * (rho**2).sum()/2 if self.affineDim > 0: obj2 += timeStep * (self.affineWeight.reshape(Afft[t].shape) * Afft[t]**2).sum()/2 #print xt.sum(), at.sum(), obj obj = obj1+obj2+obj0 if display: logging.info('deformation terms: init %f, rho %f, aff %f'%(obj0,obj1,obj2)) if withJacobian: return obj, xt, at, Jt elif withTrajectory: return obj, xt, at else: return obj
def __init__(self, Template=None, Targets=None, fileTempl=None, fileTarg=None, param=None, initialMomentum=None, maxIter=1000, regWeight = 1.0, verb=True, typeRegression='spline2', affine = 'none', controlWeight = 1.0, affineWeight = 1.0, rotWeight = None, scaleWeight = None, transWeight = None, subsampleTargetSize=-1, testGradient=True, saveFile = 'evolution', outputDir = '.'): if Template==None: if fileTempl==None: print 'Please provide a template surface' return else: self.fv0 = surfaces.Surface(filename=fileTempl) else: self.fv0 = surfaces.Surface(surf=Template) if Targets==None: if fileTarg==None: print 'Please provide a list of target surfaces' return else: self.fv1 = [] ; for f in fileTarg: self.fv1.append(surfaces.Surface(filename=f)) else: self.fv1 = [] ; for s in Targets: self.fv1.append(surfaces.Surface(surf=s)) self.nTarg = len(self.fv1) self.saveRate = 10 self.iter = 0 self.outputDir = outputDir if not os.access(outputDir, os.W_OK): if os.access(outputDir, os.F_OK): print 'Cannot save in ' + outputDir return else: os.mkdir(outputDir) self.dim = self.fv0.vertices.shape[1] self.maxIter = maxIter self.verb = verb self.testGradient = testGradient self.regweight = regWeight self.affine = affine if self.affine=='euclidean' or self.affine=='translation': self.saveCorrected = True else: self.saveCorrected = False self.affB = AffineBasis(self.dim, affine) self.affineDim = self.affB.affineDim self.affineBasis = self.affB.basis self.affineWeight = affineWeight * np.ones(self.affineDim) if (len(self.affB.rotComp) > 0) & (rotWeight != None): self.affineWeight[self.affB.rotComp] = rotWeight if (len(self.affB.simComp) > 0) & (scaleWeight != None): self.affineWeight[self.affB.simComp] = scaleWeight if (len(self.affB.transComp) > 0) & (transWeight != None): self.affineWeight[self.affB.transComp] = transWeight self.affw = affineWeight self.controlWeight = controlWeight self.typeRegression = 'affine' self.typeRegressionSave = typeRegression if param==None: self.param = SurfaceMatchingParam() else: self.param = param self.fv0Fine = surfaces.Surface(surf=self.fv0) if (subsampleTargetSize > 0): self.fv0.Simplify(subsampleTargetSize) v0 = self.fv0.surfVolume() for s in self.fv1: v1 = s.surfVolume() if (v0*v1 < 0): s.flipFaces() print 'simplified template', self.fv0.vertices.shape[0] self.x0 = self.fv0.vertices self.fvDef = [] for k in range(self.nTarg): self.fvDef.append(surfaces.Surface(surf=self.fv0)) self.npt = self.x0.shape[0] self.Tsize1 = int(round(1.0/self.param.timeStep)) self.Tsize = self.nTarg*self.Tsize1 self.rhot = np.zeros([self.Tsize, self.x0.shape[0], self.x0.shape[1]]) if initialMomentum==None: self.xt = np.tile(self.x0, [self.Tsize+1, 1, 1]) self.a0 = np.zeros([self.x0.shape[0], self.x0.shape[1]]) self.at = np.tile(self.a0, [self.Tsize+1, 1, 1]) else: self.a0 = initialMomentum (self.xt, self.at) = evol.secondOrderEvolution(self.x0, self.a0, self.rhot, self.param.KparDiff) self.v = np.zeros([self.Tsize+1, self.npt, self.dim]) self.rhotTry = np.zeros([self.Tsize, self.x0.shape[0], self.x0.shape[1]]) self.a0Try = np.zeros([self.x0.shape[0], self.x0.shape[1]]) self.Afft = np.zeros([self.Tsize, self.affineDim]) self.AfftTry = np.zeros([self.Tsize, self.affineDim]) self.obj = None self.objTry = None self.gradCoeff = self.fv0.vertices.shape[0] self.saveFile = saveFile self.fv0.saveVTK(self.outputDir+'/Template.vtk') for k,s in enumerate(self.fv1): s.saveVTK(self.outputDir+'/Target'+str(k)+'.vtk') self.affBurnIn = 50 self.coeffAff1 = 1 self.coeffAff2 = 10. self.coeffAff = self.coeffAff1 z= self.fv0.surfVolume() if (z < 0): self.fv0ori = -1 else: self.fv0ori = 1
def endOfIteration(self): self.iter += 1 if self.iter >= self.affBurnIn: self.typeRegression = self.typeRegressionSave self.affine = 'none' #self.coeffAff = self.coeffAff2 if (self.iter % self.saveRate == 0): logging.info('Saving surfaces...') (obj1, self.xt, self.at) = self.objectiveFunDef(self.a0, self.rhot, self.Afft, withTrajectory=True, display=True) for k in range(self.nTarg): self.fvDef[k].updateVertices(np.squeeze(self.xt[(k+1)*self.Tsize1, :, :])) dim2 = self.dim**2 A = [np.zeros([self.Tsize, self.dim, self.dim]), np.zeros([self.Tsize, self.dim])] if self.affineDim > 0: for t in range(self.Tsize): AB = np.dot(self.affineBasis, self.Afft[t]) A[0][t] = AB[0:dim2].reshape([self.dim, self.dim]) A[1][t] = AB[dim2:dim2+self.dim] (xt, at, ft, Jt) = evol.secondOrderEvolution(self.x0, self.a0, self.rhot, self.param.KparDiff, affine=A, withPointSet = self.fv0Fine.vertices, withJacobian=True) if self.saveCorrected: f = surfaces.Surface(surf=self.fv0Fine) X = self.affB.integrateFlow(self.Afft) displ = np.zeros(self.x0.shape[0]) dt = 1.0 /self.Tsize ; atCorr = np.zeros(at.shape) for t in range(self.Tsize+1): U = la.inv(X[0][t,...]) yyt = np.dot(self.xt[t,...] - X[1][t, ...], U.T) zt = np.dot(xt[t,...] - X[1][t, ...], U.T) if t < self.Tsize: a = np.dot(self.at[t,...], X[0][t,...]) atCorr[t,...] = a vt = self.param.KparDiff.applyK(yyt, a, firstVar=zt) vt = np.dot(vt, U.T) f.updateVertices(zt) vf = surfaces.vtkFields() ; vf.scalars.append('Jacobian') ; vf.scalars.append(np.exp(Jt[t, :])-1) vf.scalars.append('displacement') vf.scalars.append(displ) vf.vectors.append('velocity') ; vf.vectors.append(vt) nu = self.fv0ori*f.computeVertexNormals() displ += dt * (vt*nu).sum(axis=1) f.saveVTK2(self.outputDir +'/'+self.saveFile+'Corrected'+str(t)+'.vtk', vf) (foo,zt) = evol.landmarkDirectEvolutionEuler(self.x0, atCorr, self.param.KparDiff, withPointSet = self.fv0Fine.vertices) for t in range(self.Tsize+1): f.updateVertices(zt[t,...]) f.saveVTK(self.outputDir +'/'+self.saveFile+'CorrectedCheck'+str(t)+'.vtk') (foo,foo2,zt) = evol.secondOrderEvolution(self.x0, atCorr[0,...], self.rhot, self.param.KparDiff, withPointSet = self.fv0Fine.vertices) for t in range(self.Tsize+1): f.updateVertices(zt[t,...]) f.saveVTK(self.outputDir +'/'+self.saveFile+'CorrectedCheckBis'+str(t)+'.vtk') for k,fv in enumerate(self.fv1): f = surfaces.Surface(surf=fv) U = la.inv(X[0][(k+1)*self.Tsize1]) yyt = np.dot(f.vertices - X[1][(k+1)*self.Tsize1, ...], U.T) f.updateVertices(yyt) f.saveVTK(self.outputDir +'/Target'+str(k)+'Corrected.vtk') fvDef = surfaces.Surface(surf=self.fv0Fine) AV0 = fvDef.computeVertexArea() nu = self.fv0ori*self.fv0Fine.computeVertexNormals() #v = self.v[0,...] displ = np.zeros(self.npt) dt = 1.0 /self.Tsize ; v = self.param.KparDiff.applyK(ft[0,...], self.at[0,...], firstVar=self.xt[0,...]) for kk in range(self.Tsize+1): fvDef.updateVertices(np.squeeze(ft[kk, :, :])) AV = fvDef.computeVertexArea() AV = (AV[0]/AV0[0])-1 vf = surfaces.vtkFields() ; vf.scalars.append('Jacobian') ; vf.scalars.append(np.exp(Jt[kk, :])-1) vf.scalars.append('Jacobian_T') ; vf.scalars.append(AV[:,0]) vf.scalars.append('Jacobian_N') ; vf.scalars.append(np.exp(Jt[kk, :])/(AV[:,0]+1)-1) vf.scalars.append('displacement') vf.scalars.append(displ) displ += dt * (v*nu).sum(axis=1) if kk < self.Tsize: nu = self.fv0ori*fvDef.computeVertexNormals() v = self.param.KparDiff.applyK(ft[kk,...], self.at[kk,...], firstVar=self.xt[kk,...]) #v = self.v[kk,...] kkm = kk else: kkm = kk-1 vf.vectors.append('velocity') ; vf.vectors.append(self.v[kkm,:]) fvDef.saveVTK2(self.outputDir +'/'+ self.saveFile+str(kk)+'.vtk', vf) else: (obj1, self.xt, self.at) = self.objectiveFunDef(self.a0, self.rhot, self.Afft, withTrajectory=True, display=True) for k in range(self.nTarg): self.fvDef[k].updateVertices(np.squeeze(self.xt[(k+1)*self.Tsize1, :, :]))