def estimateNewMonomodalDiffeomorphicField2D(moving, fixed, lambdaParam, maxOuterIter, previousDisplacement, previousDisplacementInverse): ''' Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1, as opposed as lambdaParam=150 used in the multimodal case ''' innerTolerance = 1e-4 displacement = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) gradientField = np.empty(shape=(moving.shape) + (2, ), dtype=np.float64) totalDisplacement = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) totalDisplacementInverse = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) if (previousDisplacement != None): totalDisplacement[...] = previousDisplacement totalDisplacementInverse[...] = previousDisplacementInverse outerIter = 0 framesToCapture = 5 maxOuterIter = framesToCapture * ( (maxOuterIter + framesToCapture - 1) / framesToCapture) itersPerCapture = maxOuterIter / framesToCapture plt.figure() while (outerIter < maxOuterIter): outerIter += 1 print 'Outer iter:', outerIter warped = np.array(tf.warp_image(moving, totalDisplacement, None)) if ((outerIter == 1) or (outerIter % itersPerCapture == 0)): plt.subplot(1, framesToCapture + 1, 1 + outerIter / itersPerCapture) rcommon.overlayImages(warped, fixed, False) plt.title('Iter:' + str(outerIter - 1)) sigmaField = np.ones_like(warped, dtype=np.float64) deltaField = fixed - warped gradientField[:, :, 0], gradientField[:, :, 1] = sp.gradient(warped) maxVariation = 1 + innerTolerance innerIter = 0 displacement[...] = 0 maxInnerIter = 200 while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)): innerIter += 1 maxVariation = tf.iterateDisplacementField2DCYTHON( deltaField, sigmaField, gradientField, lambdaParam, displacement, None) #maxDisplacement=np.max(np.abs(displacement)) expd, invexpd = tf.vector_field_exponential(displacement, True) totalDisplacement, stats = tf.compose_vector_fields( displacement, totalDisplacement) #totalDisplacement=np.array(totalDisplacement) totalDisplacementInverse, stats = tf.compose_vector_fields( totalDisplacementInverse, invexpd) #totalDisplacementInverse=np.array(totalDisplacementInverse) #if(maxDisplacement<outerTolerance): #break print "Iter: ", innerIter, "Max variation:", maxVariation return totalDisplacement, totalDisplacementInverse
def estimateNewMonomodalDiffeomorphicField2D(moving, fixed, lambdaParam, maxOuterIter, previousDisplacement, previousDisplacementInverse): ''' Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1, as opposed as lambdaParam=150 used in the multimodal case ''' innerTolerance=1e-4 displacement =np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) gradientField =np.empty(shape=(moving.shape)+(2,), dtype=np.float64) totalDisplacement=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) totalDisplacementInverse=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) if(previousDisplacement!=None): totalDisplacement[...]=previousDisplacement totalDisplacementInverse[...]=previousDisplacementInverse outerIter=0 framesToCapture=5 maxOuterIter=framesToCapture*((maxOuterIter+framesToCapture-1)/framesToCapture) itersPerCapture=maxOuterIter/framesToCapture plt.figure() while(outerIter<maxOuterIter): outerIter+=1 print 'Outer iter:', outerIter warped=np.array(tf.warp_image(moving, totalDisplacement, None)) if((outerIter==1) or (outerIter%itersPerCapture==0)): plt.subplot(1,framesToCapture+1, 1+outerIter/itersPerCapture) rcommon.overlayImages(warped, fixed, False) plt.title('Iter:'+str(outerIter-1)) sigmaField=np.ones_like(warped, dtype=np.float64) deltaField=fixed-warped gradientField[:,:,0], gradientField[:,:,1]=sp.gradient(warped) maxVariation=1+innerTolerance innerIter=0 displacement[...]=0 maxInnerIter=200 while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)): innerIter+=1 maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, gradientField, lambdaParam, displacement, None) #maxDisplacement=np.max(np.abs(displacement)) expd, invexpd=tf.vector_field_exponential(displacement, True) totalDisplacement, stats=tf.compose_vector_fields(displacement, totalDisplacement) #totalDisplacement=np.array(totalDisplacement) totalDisplacementInverse, stats=tf.compose_vector_fields(totalDisplacementInverse, invexpd) #totalDisplacementInverse=np.array(totalDisplacementInverse) #if(maxDisplacement<outerTolerance): #break print "Iter: ",innerIter, "Max variation:",maxVariation return totalDisplacement, totalDisplacementInverse
def estimateNewMonomodalSyNField2D(moving, fixed, fWarp, fInv, mWarp, mInv, lambdaParam, maxOuterIter): ''' Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1, as opposed as lambdaParam=150 used in the multimodal case ''' innerTolerance = 1e-4 outerTolerance = 1e-3 if (mWarp != None): totalM = mWarp totalMInv = mInv else: totalM = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64) totalMInv = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64) if (fWarp != None): totalF = fWarp totalFInv = fInv else: totalF = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) totalFInv = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) outerIter = 0 framesToCapture = 5 maxOuterIter = framesToCapture * ( (maxOuterIter + framesToCapture - 1) / framesToCapture) itersPerCapture = maxOuterIter / framesToCapture plt.figure() while (outerIter < maxOuterIter): outerIter += 1 print 'Outer iter:', outerIter wmoving = np.array(tf.warp_image(moving, totalMInv)) wfixed = np.array(tf.warp_image(fixed, totalFInv)) if ((outerIter == 1) or (outerIter % itersPerCapture == 0)): plt.subplot(1, framesToCapture + 1, 1 + outerIter / itersPerCapture) rcommon.overlayImages(wmoving, wfixed, False) plt.title('Iter:' + str(outerIter - 1)) #Compute forward update sigmaField = np.ones_like(wmoving, dtype=np.float64) deltaField = wfixed - wmoving movingGradient = np.empty(shape=(wmoving.shape) + (2, ), dtype=np.float64) movingGradient[:, :, 0], movingGradient[:, :, 1] = sp.gradient(wmoving) maxVariation = 1 + innerTolerance innerIter = 0 fw = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64) maxInnerIter = 1000 while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)): innerIter += 1 maxVariation = tf.iterateDisplacementField2DCYTHON( deltaField, sigmaField, movingGradient, lambdaParam, fw, None) #fw*=0.5 totalF, stats = tf.compose_vector_fields(fw, totalF) totalF = np.array(totalF) meanDispF = np.mean(np.abs(fw)) #Compute backward field sigmaField = np.ones_like(wfixed, dtype=np.float64) deltaField = wmoving - wfixed fixedGradient = np.empty(shape=(wfixed.shape) + (2, ), dtype=np.float64) fixedGradient[:, :, 0], fixedGradient[:, :, 1] = sp.gradient(wfixed) maxVariation = 1 + innerTolerance innerIter = 0 mw = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64) maxInnerIter = 1000 while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)): innerIter += 1 maxVariation = tf.iterateDisplacementField2DCYTHON( deltaField, sigmaField, fixedGradient, lambdaParam, mw, None) #mw*=0.5 totalM, stats = tf.compose_vector_fields(mw, totalM) totalM = np.array(totalM) meanDispM = np.mean(np.abs(mw)) totalFInv = np.array( tf.invert_vector_field_fixed_point(totalF, None, 20, 1e-3, None)) totalMInv = np.array( tf.invert_vector_field_fixed_point(totalM, None, 20, 1e-3, None)) totalF = np.array( tf.invert_vector_field_fixed_point(totalFInv, None, 20, 1e-3, None)) totalM = np.array( tf.invert_vector_field_fixed_point(totalMInv, None, 20, 1e-3, None)) # totalFInv=np.array(tf.invert_vector_field(totalF, 0.75, 100, 1e-6)) # totalMInv=np.array(tf.invert_vector_field(totalM, 0.75, 100, 1e-6)) # totalF=np.array(tf.invert_vector_field(totalFInv, 0.75, 100, 1e-6)) # totalM=np.array(tf.invert_vector_field(totalMInv, 0.75, 100, 1e-6)) if (meanDispM + meanDispF < 2 * outerTolerance): break print "Iter: ", innerIter, "Mean lateral displacement:", 0.5 * ( meanDispM + meanDispF), "Max variation:", maxVariation return totalF, totalFInv, totalM, totalMInv
def estimateNewMonomodalSyNField2D(moving, fixed, fWarp, fInv, mWarp, mInv, lambdaParam, maxOuterIter): ''' Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1, as opposed as lambdaParam=150 used in the multimodal case ''' innerTolerance=1e-4 outerTolerance=1e-3 if(mWarp!=None): totalM=mWarp totalMInv=mInv else: totalM=np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64) totalMInv=np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64) if(fWarp!=None): totalF=fWarp totalFInv=fInv else: totalF=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) totalFInv=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) outerIter=0 framesToCapture=5 maxOuterIter=framesToCapture*((maxOuterIter+framesToCapture-1)/framesToCapture) itersPerCapture=maxOuterIter/framesToCapture plt.figure() while(outerIter<maxOuterIter): outerIter+=1 print 'Outer iter:', outerIter wmoving=np.array(tf.warp_image(moving, totalMInv)) wfixed=np.array(tf.warp_image(fixed, totalFInv)) if((outerIter==1) or (outerIter%itersPerCapture==0)): plt.subplot(1,framesToCapture+1, 1+outerIter/itersPerCapture) rcommon.overlayImages(wmoving, wfixed, False) plt.title('Iter:'+str(outerIter-1)) #Compute forward update sigmaField=np.ones_like(wmoving, dtype=np.float64) deltaField=wfixed-wmoving movingGradient =np.empty(shape=(wmoving.shape)+(2,), dtype=np.float64) movingGradient[:,:,0], movingGradient[:,:,1]=sp.gradient(wmoving) maxVariation=1+innerTolerance innerIter=0 fw =np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64) maxInnerIter=1000 while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)): innerIter+=1 maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, movingGradient, lambdaParam, fw, None) #fw*=0.5 totalF, stats=tf.compose_vector_fields(fw, totalF) totalF=np.array(totalF); meanDispF=np.mean(np.abs(fw)) #Compute backward field sigmaField=np.ones_like(wfixed, dtype=np.float64) deltaField=wmoving-wfixed fixedGradient =np.empty(shape=(wfixed.shape)+(2,), dtype=np.float64) fixedGradient[:,:,0], fixedGradient[:,:,1]=sp.gradient(wfixed) maxVariation=1+innerTolerance innerIter=0 mw =np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64) maxInnerIter=1000 while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)): innerIter+=1 maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, fixedGradient, lambdaParam, mw, None) #mw*=0.5 totalM, stats=tf.compose_vector_fields(mw, totalM) totalM=np.array(totalM); meanDispM=np.mean(np.abs(mw)) totalFInv=np.array(tf.invert_vector_field_fixed_point(totalF, None, 20, 1e-3, None)) totalMInv=np.array(tf.invert_vector_field_fixed_point(totalM, None, 20, 1e-3, None)) totalF=np.array(tf.invert_vector_field_fixed_point(totalFInv, None, 20, 1e-3, None)) totalM=np.array(tf.invert_vector_field_fixed_point(totalMInv, None, 20, 1e-3, None)) # totalFInv=np.array(tf.invert_vector_field(totalF, 0.75, 100, 1e-6)) # totalMInv=np.array(tf.invert_vector_field(totalM, 0.75, 100, 1e-6)) # totalF=np.array(tf.invert_vector_field(totalFInv, 0.75, 100, 1e-6)) # totalM=np.array(tf.invert_vector_field(totalMInv, 0.75, 100, 1e-6)) if(meanDispM+meanDispF<2*outerTolerance): break print "Iter: ",innerIter, "Mean lateral displacement:", 0.5*(meanDispM+meanDispF), "Max variation:",maxVariation return totalF, totalFInv, totalM, totalMInv
def estimateNewMultimodalDiffeomorphicField2D(moving, fixed, lambdaDisplacement, quantizationLevels, maxOuterIter, previousDisplacement, previousDisplacementInverse): innerTolerance = 1e-4 outerTolerance = 1e-3 sh = moving.shape X0, X1 = np.mgrid[0:sh[0], 0:sh[1]] displacement = np.empty(shape=(moving.shape) + (2, ), dtype=np.float64) residuals = np.zeros(shape=(moving.shape), dtype=np.float64) gradientField = np.empty(shape=(moving.shape) + (2, ), dtype=np.float64) totalDisplacement = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) totalDisplacementInverse = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64) if (previousDisplacement != None): totalDisplacement[...] = previousDisplacement totalDisplacementInverse[...] = previousDisplacementInverse fixedQ = None grayLevels = None fixedQ, grayLevels, hist = tf.quantizePositiveImageCYTHON( fixed, quantizationLevels) fixedQ = np.array(fixedQ, dtype=np.int32) finished = False outerIter = 0 maxDisplacement = None maxVariation = None maxResidual = 0 while ((not finished) and (outerIter < maxOuterIter)): outerIter += 1 #---E step--- warped = ndimage.map_coordinates( moving, [X0 + totalDisplacement[..., 0], X1 + totalDisplacement[..., 1]], prefilter=True) movingMask = ((moving > 0) * 1.0) * ((fixed > 0) * 1.0) warpedMovingMask = ndimage.map_coordinates( movingMask, [X0 + totalDisplacement[..., 0], X1 + totalDisplacement[..., 1]], order=0, prefilter=False) warpedMovingMask = warpedMovingMask.astype(np.int32) means, variances = tf.computeMaskedImageClassStatsCYTHON( warpedMovingMask, warped, quantizationLevels, fixedQ) means[0] = 0 means = np.array(means) variances = np.array(variances) sigmaField = variances[fixedQ] deltaField = means[ fixedQ] - warped #########Delta-field using Arce's rule #--M step-- g0, g1 = sp.gradient(warped) gradientField[:, :, 0] = g0 gradientField[:, :, 1] = g1 maxVariation = 1 + innerTolerance innerIter = 0 maxInnerIter = 1000 displacement[...] = 0 while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)): innerIter += 1 maxVariation = tf.iterateDisplacementField2DCYTHON( deltaField, sigmaField, gradientField, lambdaDisplacement, totalDisplacement, displacement, residuals) opt = np.max(residuals) if (maxResidual < opt): maxResidual = opt #--accumulate displacement-- expd, invexpd = tf.vector_field_exponential(displacement) totalDisplacement = tf.compose_vector_fields(expd, totalDisplacement) totalDisplacementInverse = tf.compose_vector_fields( totalDisplacementInverse, invexpd) #--check stop condition-- nrm = np.sqrt(displacement[..., 0]**2 + displacement[..., 1]**2) #maxDisplacement=np.max(nrm) maxDisplacement = np.mean(nrm) if ((maxDisplacement < outerTolerance) or (outerIter >= maxOuterIter)): finished = True # plt.figure() # plt.subplot(1,3,1) # plt.imshow(means[fixedQ],cmap=plt.cm.gray) # plt.title("Estimated warped modality") # plt.subplot(1,3,2) # plt.imshow(fixedQ,cmap=plt.cm.gray) # plt.title("Quantized") # plt.subplot(1,3,3) # plt.plot(means) # plt.title("Means") print "Iter: ", outerIter, "Mean displacement:", maxDisplacement, "Max variation:", maxVariation, "Max residual:", maxResidual if (previousDisplacement != None): return totalDisplacement - previousDisplacement, totalDisplacementInverse return totalDisplacement, totalDisplacementInverse
def estimateNewMultimodalDiffeomorphicField2D(moving, fixed, lambdaDisplacement, quantizationLevels, maxOuterIter, previousDisplacement, previousDisplacementInverse): innerTolerance=1e-4 outerTolerance=1e-3 sh=moving.shape X0,X1=np.mgrid[0:sh[0], 0:sh[1]] displacement =np.empty(shape=(moving.shape)+(2,), dtype=np.float64) residuals=np.zeros(shape=(moving.shape), dtype=np.float64) gradientField =np.empty(shape=(moving.shape)+(2,), dtype=np.float64) totalDisplacement=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) totalDisplacementInverse=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64) if(previousDisplacement!=None): totalDisplacement[...]=previousDisplacement totalDisplacementInverse[...]=previousDisplacementInverse fixedQ=None grayLevels=None fixedQ, grayLevels, hist=tf.quantizePositiveImageCYTHON(fixed, quantizationLevels) fixedQ=np.array(fixedQ, dtype=np.int32) finished=False outerIter=0 maxDisplacement=None maxVariation=None maxResidual=0 while((not finished) and (outerIter<maxOuterIter)): outerIter+=1 #---E step--- warped=ndimage.map_coordinates(moving, [X0+totalDisplacement[...,0], X1+totalDisplacement[...,1]], prefilter=True) movingMask=((moving>0)*1.0)*((fixed>0)*1.0) warpedMovingMask=ndimage.map_coordinates(movingMask, [X0+totalDisplacement[...,0], X1+totalDisplacement[...,1]], order=0, prefilter=False) warpedMovingMask=warpedMovingMask.astype(np.int32) means, variances=tf.computeMaskedImageClassStatsCYTHON(warpedMovingMask, warped, quantizationLevels, fixedQ) means[0]=0 means=np.array(means) variances=np.array(variances) sigmaField=variances[fixedQ] deltaField=means[fixedQ]-warped#########Delta-field using Arce's rule #--M step-- g0, g1=sp.gradient(warped) gradientField[:,:,0]=g0 gradientField[:,:,1]=g1 maxVariation=1+innerTolerance innerIter=0 maxInnerIter=1000 displacement[...]=0 while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)): innerIter+=1 maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, gradientField, lambdaDisplacement, totalDisplacement, displacement, residuals) opt=np.max(residuals) if(maxResidual<opt): maxResidual=opt #--accumulate displacement-- expd, invexpd=tf.vector_field_exponential(displacement) totalDisplacement=tf.compose_vector_fields(expd, totalDisplacement) totalDisplacementInverse=tf.compose_vector_fields(totalDisplacementInverse, invexpd) #--check stop condition-- nrm=np.sqrt(displacement[...,0]**2+displacement[...,1]**2) #maxDisplacement=np.max(nrm) maxDisplacement=np.mean(nrm) if((maxDisplacement<outerTolerance)or(outerIter>=maxOuterIter)): finished=True # plt.figure() # plt.subplot(1,3,1) # plt.imshow(means[fixedQ],cmap=plt.cm.gray) # plt.title("Estimated warped modality") # plt.subplot(1,3,2) # plt.imshow(fixedQ,cmap=plt.cm.gray) # plt.title("Quantized") # plt.subplot(1,3,3) # plt.plot(means) # plt.title("Means") print "Iter: ",outerIter, "Mean displacement:", maxDisplacement, "Max variation:",maxVariation, "Max residual:", maxResidual if(previousDisplacement!=None): return totalDisplacement-previousDisplacement, totalDisplacementInverse return totalDisplacement, totalDisplacementInverse