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 estimateMultimodalDiffeomorphicField3DMultiScale(movingPyramid, fixedPyramid, initAffine, lambdaParam, maxOuterIter, level=0, displacementList=None): n = len(movingPyramid) quantizationLevels = 256 if (level == (n - 1)): displacement = estimateNewMultimodalDiffeomorphicField3D( movingPyramid[level], fixedPyramid[level], initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], None, level == 0) if (displacementList != None): displacementList.insert(0, displacement) return displacement subAffine = initAffine.copy() #subAffine=initAffine.copy()*0.5 subAffine[:3, 3] *= 0.5 subDisplacement = estimateMultimodalDiffeomorphicField3DMultiScale( movingPyramid, fixedPyramid, subAffine, lambdaParam, maxOuterIter, level + 1, displacementList) sh = np.array(fixedPyramid[level].shape).astype(np.int32) upsampled = np.array(tf.upsample_displacement_field3D(subDisplacement, sh)) * 2 newDisplacement = estimateNewMultimodalDiffeomorphicField3D( movingPyramid[level], fixedPyramid[level], initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], upsampled, level == 0) newDisplacement += upsampled if (displacementList != None): displacementList.insert(0, newDisplacement) return newDisplacement
def estimateMonomodalDiffeomorphicField3DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level, displacementList): n = len(movingPyramid) if (level == (n - 1)): displacement = estimateNewMonomodalDiffeomorphicField3D( movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], None, level == 0) if (displacementList != None): displacementList.insert(0, displacement) return displacement subDisplacement = estimateMonomodalDiffeomorphicField3DMultiScale( movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level + 1, displacementList) sh = np.array(movingPyramid[level].shape) upsampled = np.array(tf.upsample_displacement_field3D(subDisplacement, sh)) * 2 newDisplacement = estimateNewMonomodalDiffeomorphicField3D( movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], upsampled, level == 0) newDisplacement += upsampled if (displacementList != None): displacementList.insert(0, newDisplacement) return np.array(newDisplacement)
def estimateMultimodalSyN3DMultiScale(movingPyramid, fixedPyramid, initAffine, lambdaParam, maxOuterIter, level=0): n = len(movingPyramid) quantizationLevels = 256 if (level == (n - 1)): totalF, totalFInv, totalM, totalMInv = estimateNewMultimodalSyNField3D( movingPyramid[level], fixedPyramid[level], None, None, None, None, initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], level == 0) return totalF, totalFInv, totalM, totalMInv subAffine = initAffine.copy() subAffine[:3, 3] *= 0.5 subF, subFInv, subM, subMInv = estimateMultimodalSyN3DMultiScale( movingPyramid, fixedPyramid, subAffine, lambdaParam, maxOuterIter, level + 1) sh = np.array(fixedPyramid[level].shape).astype(np.int32) upF = np.array(tf.upsample_displacement_field3D(subF, sh)) * 2 upFInv = np.array(tf.upsample_displacement_field3D(subFInv, sh)) * 2 upM = np.array(tf.upsample_displacement_field3D(subM, sh)) * 2 upMInv = np.array(tf.upsample_displacement_field3D(subMInv, sh)) * 2 del subF del subFInv del subM del subMInv totalF, totalFInv, totalM, totalMInv = estimateNewMultimodalSyNField3D( movingPyramid[level], fixedPyramid[level], upF, upFInv, upM, upMInv, initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], level == 0) if level == 0: totalF = np.array(tf.compose_vector_fields3D( totalF, totalMInv)) #Multiply bw by 0.5?? totalM = np.array(tf.compose_vector_fields3D( totalM, totalFInv)) #Multiply bw by 0.5?? return totalM, totalF return totalF, totalFInv, totalM, totalMInv
def estimateMultimodalSyN3DMultiScale(movingPyramid, fixedPyramid, initAffine, lambdaParam, maxOuterIter, level=0): n=len(movingPyramid) quantizationLevels=256 if(level==(n-1)): totalF, totalFInv, totalM, totalMInv=estimateNewMultimodalSyNField3D(movingPyramid[level], fixedPyramid[level], None, None, None, None, initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], level==0) return totalF, totalFInv, totalM, totalMInv subAffine=initAffine.copy() subAffine[:3,3]*=0.5 subF, subFInv, subM, subMInv=estimateMultimodalSyN3DMultiScale(movingPyramid, fixedPyramid, subAffine, lambdaParam, maxOuterIter, level+1) sh=np.array(fixedPyramid[level].shape).astype(np.int32) upF=np.array(tf.upsample_displacement_field3D(subF, sh))*2 upFInv=np.array(tf.upsample_displacement_field3D(subFInv, sh))*2 upM=np.array(tf.upsample_displacement_field3D(subM, sh))*2 upMInv=np.array(tf.upsample_displacement_field3D(subMInv, sh))*2 del subF del subFInv del subM del subMInv totalF, totalFInv, totalM, totalMInv=estimateNewMultimodalSyNField3D(movingPyramid[level], fixedPyramid[level], upF, upFInv, upM, upMInv, initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], level==0) if level==0: totalF=np.array(tf.compose_vector_fields3D(totalF, totalMInv))#Multiply bw by 0.5?? totalM=np.array(tf.compose_vector_fields3D(totalM, totalFInv))#Multiply bw by 0.5?? return totalM, totalF return totalF, totalFInv, totalM, totalMInv
def estimateMonomodalDiffeomorphicField3DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level, displacementList): n=len(movingPyramid) if(level==(n-1)): displacement=estimateNewMonomodalDiffeomorphicField3D(movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], None, level==0) if(displacementList!=None): displacementList.insert(0,displacement) return displacement subDisplacement=estimateMonomodalDiffeomorphicField3DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, level+1, displacementList) sh=np.array(movingPyramid[level].shape) upsampled=np.array(tf.upsample_displacement_field3D(subDisplacement, sh))*2 newDisplacement=estimateNewMonomodalDiffeomorphicField3D(movingPyramid[level], fixedPyramid[level], lambdaParam, maxOuterIter[level], upsampled, level==0) newDisplacement+=upsampled if(displacementList!=None): displacementList.insert(0, newDisplacement) return np.array(newDisplacement)
def estimateMultimodalDiffeomorphicField3DMultiScale(movingPyramid, fixedPyramid, initAffine, lambdaParam, maxOuterIter, level=0, displacementList=None): n=len(movingPyramid) quantizationLevels=256 if(level==(n-1)): displacement=estimateNewMultimodalDiffeomorphicField3D(movingPyramid[level], fixedPyramid[level], initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], None, level==0) if(displacementList!=None): displacementList.insert(0, displacement) return displacement subAffine=initAffine.copy() #subAffine=initAffine.copy()*0.5 subAffine[:3,3]*=0.5 subDisplacement=estimateMultimodalDiffeomorphicField3DMultiScale(movingPyramid, fixedPyramid, subAffine, lambdaParam, maxOuterIter, level+1, displacementList) sh=np.array(fixedPyramid[level].shape).astype(np.int32) upsampled=np.array(tf.upsample_displacement_field3D(subDisplacement, sh))*2 newDisplacement=estimateNewMultimodalDiffeomorphicField3D(movingPyramid[level], fixedPyramid[level], initAffine, lambdaParam, quantizationLevels, maxOuterIter[level], upsampled, level==0) newDisplacement+=upsampled if(displacementList!=None): displacementList.insert(0, newDisplacement) return newDisplacement
def w_cycle_3d(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_SSD3D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field3D(residual)) del residual #solve at coarcer grid subsigma_field = None if sigma_field != None: subsigma_field = tf.downsample_scalar_field3D(sigma_field) subdelta_field = tf.downsample_scalar_field3D(delta_field) subgradient_field = np.array( tf.downsample_displacement_field3D(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) sub_displacement = np.zeros( shape = ((shape[0]+1)//2, (shape[1]+1)//2, (shape[2]+1)//2, 3 ), dtype = np.float64) sublambda_param = lambda_param*0.25 w_cycle_3d(n-1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth+1) displacement += np.array( tf.upsample_displacement_field3D(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field3D(residual)) del residual sub_displacement[...] = 0 w_cycle_3d(n-1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth+1) displacement += np.array( tf.upsample_displacement_field3D(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy
def single_cycle_3d(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_SSD3D(delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_field3D(sigma_field) subdelta_field = tf.downsample_scalar_field3D(delta_field) subgradient_field = np.array( tf.downsample_displacement_field3D(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) sub_displacement = np.zeros( shape = ((shape[0]+1)//2, (shape[1]+1)//2, (shape[2]+1)//2, 3 ), dtype = np.float64) sublambda_param = lambda_param*0.25 single_cycle_3d(n-1, k, subdelta_field, subsigma_field, subgradient_field, sublambda_param, sub_displacement, depth+1) displacement += np.array( tf.upsample_displacement_field3D(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy
def w_cycle_3d(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_SSD3D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field3D(residual)) del residual #solve at coarcer grid subsigma_field = None if sigma_field != None: subsigma_field = tf.downsample_scalar_field3D(sigma_field) subdelta_field = tf.downsample_scalar_field3D(delta_field) subgradient_field = np.array( tf.downsample_displacement_field3D(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) sub_displacement = np.zeros(shape=((shape[0] + 1) // 2, (shape[1] + 1) // 2, (shape[2] + 1) // 2, 3), dtype=np.float64) sublambda_param = lambda_param * 0.25 w_cycle_3d(n - 1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth + 1) displacement += np.array( tf.upsample_displacement_field3D(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement, None) sub_residual = np.array(tf.downsample_displacement_field3D(residual)) del residual sub_displacement[...] = 0 w_cycle_3d(n - 1, k, subdelta_field, subsigma_field, subgradient_field, sub_residual, sublambda_param, sub_displacement, depth + 1) displacement += np.array( tf.upsample_displacement_field3D(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D( delta_field, sigma_field, gradient_field, target, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy
def single_cycle_3d(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_SSD3D( delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_field3D(sigma_field) subdelta_field = tf.downsample_scalar_field3D(delta_field) subgradient_field = np.array( tf.downsample_displacement_field3D(gradient_field)) shape = np.array(displacement.shape).astype(np.int32) sub_displacement = np.zeros(shape=((shape[0] + 1) // 2, (shape[1] + 1) // 2, (shape[2] + 1) // 2, 3), dtype=np.float64) sublambda_param = lambda_param * 0.25 single_cycle_3d(n - 1, k, subdelta_field, subsigma_field, subgradient_field, sublambda_param, sub_displacement, depth + 1) displacement += np.array( tf.upsample_displacement_field3D(sub_displacement, shape)) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D( delta_field, sigma_field, gradient_field, None, lambda_param, displacement) if printEnergy and depth == 0: energy = tf.compute_energy_SSD3D(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_SSD3D(delta_field, sigma_field, gradient_field, lambda_param, displacement) return energy