def upsample(self, new_domain_forward, new_domain_backward): r''' Upsamples the displacement fields and scales the affine pre- and post-multiplication affine matrices by a factor of 2. The final outcome is that this transformation can be used in an upsampled domain. ''' if self.dim == 2: if self.forward != None: self.forward = 2*np.array( tf.upsample_displacement_field( self.forward, np.array(new_domain_forward).astype(np.int32))) if self.backward != None: self.backward = 2*np.array( tf.upsample_displacement_field( self.backward, np.array(new_domain_backward).astype(np.int32))) else: if self.forward != None: self.forward = 2*np.array( tf.upsample_displacement_field3D( self.forward, np.array(new_domain_forward).astype(np.int32))) if self.backward != None: self.backward = 2*np.array( tf.upsample_displacement_field3D( self.backward, np.array(new_domain_backward).astype(np.int32))) self.scale_affines(2.0)
def estimateMonomodalSyNField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level, displacementList): n = len(movingPyramid) if (level == (n - 1)): totalF, totalFInv, totalM, totalMInv = estimateNewMonomodalSyNField2D( movingPyramid[level], fixedPyramid[level], None, None, None, None, lambdaParam, maxOuterIter[level]) if (displacementList != None): displacementList.insert(0, totalM) return totalF, totalFInv, totalM, totalMInv subF, subFInv, subM, subMInv = estimateMonomodalSyNField2DMultiScale( movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level + 1, displacementList) sh = np.array(fixedPyramid[level].shape).astype(np.int32) upF = np.array(tf.upsample_displacement_field(subF, sh)) * 2 upFInv = np.array(tf.upsample_displacement_field(subFInv, sh)) * 2 upM = np.array(tf.upsample_displacement_field(subM, sh)) * 2 upMInv = np.array(tf.upsample_displacement_field(subMInv, sh)) * 2 totalF, totalFInv, totalM, totalMInv = estimateNewMonomodalSyNField2D( movingPyramid[level], fixedPyramid[level], upF, upFInv, upM, upMInv, lambdaParam, maxOuterIter[level]) if (displacementList != None): displacementList.insert(0, totalM) if (level == 0): totalF = np.array(tf.compose_vector_fields(totalF, totalMInv)) totalM = np.array(tf.compose_vector_fields(totalM, totalFInv)) return totalM, totalF return totalF, totalFInv, totalM, totalMInv
def estimateMonomodalDiffeomorphicField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level, displacementList): n = len(movingPyramid) if (level == (n - 1)): #displacement=estimateNewMonomodalDeformationField2D(movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], None) displacement, inverse = estimateNewMonomodalDiffeomorphicField2D( movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], None, None) if (displacementList != None): displacementList.insert(0, displacement) return displacement, inverse subDisplacement, subDisplacementInverse = estimateMonomodalDiffeomorphicField2DMultiScale( movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level + 1, displacementList) sh = np.array(fixedPyramid[level].shape) upsampled = np.array(tf.upsample_displacement_field(subDisplacement, sh)) * 2 upsampledInverse = np.array( tf.upsample_displacement_field(subDisplacementInverse, sh)) * 2 newDisplacement, newDisplacementInverse = estimateNewMonomodalDiffeomorphicField2D( movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], upsampled, upsampledInverse) if (displacementList != None): displacementList.insert(0, newDisplacement) return np.array(newDisplacement), np.array(newDisplacementInverse)
def estimateMonomodalDiffeomorphicField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level, displacementList): n=len(movingPyramid) if(level==(n-1)): #displacement=estimateNewMonomodalDeformationField2D(movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], None) displacement, inverse=estimateNewMonomodalDiffeomorphicField2D(movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], None, None) if(displacementList!=None): displacementList.insert(0,displacement) return displacement, inverse subDisplacement, subDisplacementInverse=estimateMonomodalDiffeomorphicField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level+1, displacementList) sh=np.array(fixedPyramid[level].shape) upsampled=np.array(tf.upsample_displacement_field(subDisplacement, sh))*2 upsampledInverse=np.array(tf.upsample_displacement_field(subDisplacementInverse, sh))*2 newDisplacement, newDisplacementInverse=estimateNewMonomodalDiffeomorphicField2D(movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], upsampled, upsampledInverse) if(displacementList!=None): displacementList.insert(0, newDisplacement) return np.array(newDisplacement), np.array(newDisplacementInverse)
def estimateMonomodalSyNField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level, displacementList): n=len(movingPyramid) if(level==(n-1)): totalF, totalFInv, totalM, totalMInv=estimateNewMonomodalSyNField2D(movingPyramid[level], fixedPyramid[level], None, None, None, None, lambdaParam, maxOuterIter[level]) if(displacementList!=None): displacementList.insert(0,totalM) return totalF, totalFInv, totalM, totalMInv subF, subFInv, subM, subMInv=estimateMonomodalSyNField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level+1, displacementList) sh=np.array(fixedPyramid[level].shape).astype(np.int32) upF=np.array(tf.upsample_displacement_field(subF, sh))*2 upFInv=np.array(tf.upsample_displacement_field(subFInv, sh))*2 upM=np.array(tf.upsample_displacement_field(subM, sh))*2 upMInv=np.array(tf.upsample_displacement_field(subMInv, sh))*2 totalF, totalFInv, totalM, totalMInv=estimateNewMonomodalSyNField2D(movingPyramid[level], fixedPyramid[level], upF, upFInv, upM, upMInv, lambdaParam, maxOuterIter[level]) if(displacementList!=None): displacementList.insert(0, totalM) if(level==0): totalF=np.array(tf.compose_vector_fields(totalF, totalMInv)) totalM=np.array(tf.compose_vector_fields(totalM, totalFInv)) return totalM, totalF return totalF, totalFInv, totalM, totalMInv
def w_cycle_2d(n, k, delta_field, sigma_field, gradient_field, target, lambda_param, displacement, depth = 0): r''' Multi-resolution Gauss-Seidel solver: solves the linear system by performing two v-cycles at each resolution, which corresponds to the w-cycle scheme proposed by Bruhn and Weickert[1]. [1] Andres Bruhn and Joachim Weickert, "Towards ultimate motion estimation: combining highest accuracy with real-time performance", 10th IEEE International Conference on Computer Vision, 2005. ICCV 2005. ''' #presmoothing for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i+1, ' [first]:', energy if n == 0: return error residual = tf.compute_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field(residual)) del residual #solve at coarcer grid subsigma_field = None if sigma_field != None: subsigma_field = tf.downsample_scalar_field(sigma_field) subdelta_field = tf.downsample_scalar_field(delta_field) subgradient_field = np.array( tf.downsample_displacement_field(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) #sub_displacement = np.array(tf.downsample_displacement_field(displacement)) sub_displacement = np.zeros(shape = ((shape[0]+1)//2, (shape[1]+1)//2, 2 ), dtype = np.float64) sublambda_param = lambda_param*0.25 w_cycle_2d(n-1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth+1) displacement += np.array( tf.upsample_displacement_field(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after low-res iteration[first]:', energy #post-smoothing (second smoothing) for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i+1, ' [second]:', energy residual = tf.compute_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field(residual)) del residual #sub_displacement = np.array(tf.downsample_displacement_field(displacement)) sub_displacement = np.zeros(shape = ((shape[0]+1)//2, (shape[1]+1)//2, 2 ), dtype = np.float64) w_cycle_2d(n-1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth+1) displacement += np.array( tf.upsample_displacement_field(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after low-res iteration[second]:', energy for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i+1, ' [third]:', energy try: energy except NameError: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy
def single_cycle_2d(n, k, delta_field, sigma_field, gradient_field, lambda_param, displacement, depth = 0): r''' One-pass multi-resolution Gauss-Seidel solver: solves the SSD-like linear system starting at the coarcer resolution and then refining at the finer resolution. ''' if n == 0: for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i+1, ' [unique]:', energy return error #solve at coarcer grid subsigma_field = None if sigma_field != None: subsigma_field = tf.downsample_scalar_field(sigma_field) subdelta_field = tf.downsample_scalar_field(delta_field) subgradient_field = np.array( tf.downsample_displacement_field(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) sub_displacement = np.zeros( shape = ((shape[0]+1)//2, (shape[1]+1)//2, 2 ), dtype = np.float64) sublambda_param = lambda_param*0.25 single_cycle_2d(n-1, k, subdelta_field, subsigma_field, subgradient_field, sublambda_param, sub_displacement, depth+1) displacement += np.array( tf.upsample_displacement_field(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after low-res iteration:', energy #post-smoothing for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D(delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i+1, ' [unique]:', energy try: energy except NameError: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy
def w_cycle_2d(n, k, delta_field, sigma_field, gradient_field, target, lambda_param, displacement, depth=0): r''' Multi-resolution Gauss-Seidel solver: solves the linear system by performing two v-cycles at each resolution, which corresponds to the w-cycle scheme proposed by Bruhn and Weickert[1]. [1] Andres Bruhn and Joachim Weickert, "Towards ultimate motion estimation: combining highest accuracy with real-time performance", 10th IEEE International Conference on Computer Vision, 2005. ICCV 2005. ''' #presmoothing for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i + 1, ' [first]:', energy if n == 0: return error residual = tf.compute_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field(residual)) del residual #solve at coarcer grid subsigma_field = None if sigma_field != None: subsigma_field = tf.downsample_scalar_field(sigma_field) subdelta_field = tf.downsample_scalar_field(delta_field) subgradient_field = np.array( tf.downsample_displacement_field(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) #sub_displacement = np.array(tf.downsample_displacement_field(displacement)) sub_displacement = np.zeros(shape=((shape[0] + 1) // 2, (shape[1] + 1) // 2, 2), dtype=np.float64) sublambda_param = lambda_param * 0.25 w_cycle_2d(n - 1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth + 1) displacement += np.array( tf.upsample_displacement_field(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after low-res iteration[first]:', energy #post-smoothing (second smoothing) for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i + 1, ' [second]:', energy residual = tf.compute_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field(residual)) del residual #sub_displacement = np.array(tf.downsample_displacement_field(displacement)) sub_displacement = np.zeros(shape=((shape[0] + 1) // 2, (shape[1] + 1) // 2, 2), dtype=np.float64) w_cycle_2d(n - 1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth + 1) displacement += np.array( tf.upsample_displacement_field(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after low-res iteration[second]:', energy for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i + 1, ' [third]:', energy try: energy except NameError: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy
def single_cycle_2d(n, k, delta_field, sigma_field, gradient_field, lambda_param, displacement, depth=0): r''' One-pass multi-resolution Gauss-Seidel solver: solves the SSD-like linear system starting at the coarcer resolution and then refining at the finer resolution. ''' if n == 0: for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i + 1, ' [unique]:', energy return error #solve at coarcer grid subsigma_field = None if sigma_field != None: subsigma_field = tf.downsample_scalar_field(sigma_field) subdelta_field = tf.downsample_scalar_field(delta_field) subgradient_field = np.array( tf.downsample_displacement_field(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) sub_displacement = np.zeros(shape=((shape[0] + 1) // 2, (shape[1] + 1) // 2, 2), dtype=np.float64) sublambda_param = lambda_param * 0.25 single_cycle_2d(n - 1, k, subdelta_field, subsigma_field, subgradient_field, sublambda_param, sub_displacement, depth + 1) displacement += np.array( tf.upsample_displacement_field(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after low-res iteration:', energy #post-smoothing for i in range(k): error = tf.iterate_residual_displacement_field_SSD2D( delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) print 'Energy after top-level iter', i + 1, ' [unique]:', energy try: energy except NameError: energy = tf.compute_energy_SSD2D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy