def testInversion_invertible(): displacement_clean=tf.create_invertible_displacement_field(256, 256, 0.5, 8) detJacobian=rcommon.computeJacobianField(displacement_clean) plt.figure() plt.imshow(detJacobian) print 'Range:', detJacobian.min(), detJacobian.max() X1,X0=np.mgrid[0:displacement_clean.shape[0], 0:displacement_clean.shape[1]] CS=plt.contour(X0,X1,detJacobian,levels=[0.0], colors='b') plt.clabel(CS, inline=1, fontsize=10) plt.title('det(J(displacement))') displacement=displacement_clean+np.random.normal(0.0, 1.1, displacement_clean.shape) #displacement=np.array(displacement_clean) #inverse=rcommon.invert_vector_field_fixed_point(displacement, 100, 1e-7) #inverse=np.array(tf.invert_vector_field(displacement, 0.1, 100, 1e-7)) lambdaParam=5.0 #########Jacobi########## inverse=np.array(tf.invert_vector_field(displacement, lambdaParam, 100, 1e-6)) residual, stats=tf.compose_vector_fields(displacement_clean, inverse) residual=np.array(residual) print 'Jacobi. Max:',stats[0], '. Mean:',stats[1],'Std:',stats[2] [d,invd,res, detJ]=rcommon.plotDiffeomorphism(displacement, inverse, residual, 'Jacobi', 7) #########Fixed point###### inverse=np.array(tf.invert_vector_field_fixed_point(displacement, 100, 1e-6)) residual, stats=tf.compose_vector_fields(displacement_clean, inverse) residual=np.array(residual) print 'Fixed point. Max:',stats[0], '. Mean:',stats[1],'Std:',stats[2] [d,invd,res, detJ]=rcommon.plotDiffeomorphism(displacement, inverse, residual, 'Fixed point', 7) #########TV-L2########### inverse=np.array(tf.invert_vector_field_tv_l2(displacement, lambdaParam, 3000, 1e-6)) residual, stats=tf.compose_vector_fields(displacement_clean, inverse) residual=np.array(residual) print 'TV-L2. Max:',stats[0], '. Mean:',stats[1],'Std:',stats[2] [d,invd,res, detJ]=rcommon.plotDiffeomorphism(displacement, inverse, residual, 'TV-L2', 7)
def testCircleToCMonomodalDiffeomorphic(lambdaParam): import numpy as np import tensorFieldUtils as tf import matplotlib.pyplot as plt import registrationCommon as rcommon fname0='data/circle.png' #fname0='data/C_trans.png' fname1='data/C.png' circleToCDisplacementName='circleToCDisplacement.npy' circleToCDisplacementInverseName='circleToCDisplacementInverse.npy' nib_moving=plt.imread(fname0) nib_fixed=plt.imread(fname1) moving=nib_moving[:,:,0] fixed=nib_fixed[:,:,1] moving=(moving-moving.min())/(moving.max() - moving.min()) fixed=(fixed-fixed.min())/(fixed.max() - fixed.min()) level=3 maskMoving=moving>0 maskFixed=fixed>0 movingPyramid=[img for img in rcommon.pyramid_gaussian_2D(moving, level, np.ones_like(maskMoving))] fixedPyramid=[img for img in rcommon.pyramid_gaussian_2D(fixed, level, np.ones_like(maskFixed))] rcommon.plotOverlaidPyramids(movingPyramid, fixedPyramid) displacementList=[] maxOuterIter=[10,50,100,100,100,100,100,100,100] if(os.path.exists(circleToCDisplacementName)): displacement=np.load(circleToCDisplacementName) inverse=np.load(circleToCDisplacementInverseName) else: displacement, inverse=estimateMonomodalDiffeomorphicField2DMultiScale(movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, 0,displacementList) np.save(circleToCDisplacementName, displacement) np.save(circleToCDisplacementInverseName, inverse) X1,X0=np.mgrid[0:displacement.shape[0], 0:displacement.shape[1]] detJacobian=rcommon.computeJacobianField(displacement) plt.figure() plt.imshow(detJacobian) CS=plt.contour(X0,X1,detJacobian,levels=[0.0], colors='b') plt.clabel(CS, inline=1, fontsize=10) plt.title('det(J(displacement))') print 'J range:', '[', detJacobian.min(), detJacobian.max(),']' #directInverse=np.array(tf.invert_vector_field(displacement, 0.5, 1000, 1e-7)) directInverse=np.array(tf.invert_vector_field_fixed_point(displacement, 100, 1e-7)) detJacobianInverse=rcommon.computeJacobianField(directInverse) plt.figure() plt.imshow(detJacobianInverse) CS=plt.contour(X0,X1,detJacobianInverse, levels=[0.0],colors='w') plt.clabel(CS, inline=1, fontsize=10) plt.title('det(J(displacement^-1))') print 'J^-1 range:', '[', detJacobianInverse.min(), detJacobianInverse.max(),']' #directInverse=rcommon.invert_vector_field_fixed_point(displacement, 1000, 1e-7) residual, stats=tf.compose_vector_fields(displacement, inverse) residual=np.array(residual) directResidual,stats=tf.compose_vector_fields(displacement, directInverse) directResidual=np.array(directResidual) # warpPyramid=[rcommon.warpImage(movingPyramid[i], displacementList[i]) for i in range(level+1)] # rcommon.plotOverlaidPyramids(warpPyramid, fixedPyramid) # rcommon.overlayImages(warpPyramid[0], fixedPyramid[0]) rcommon.plotDiffeomorphism(displacement, inverse, residual, 'inv-joint', 7) rcommon.plotDiffeomorphism(displacement, directInverse, directResidual, 'inv-direct', 7) tf.write_double_buffer(displacement.reshape(-1), 'displacement.bin')
def testInversion_invertible(): displacement_clean = tf.create_invertible_displacement_field( 256, 256, 0.5, 8) detJacobian = rcommon.computeJacobianField(displacement_clean) plt.figure() plt.imshow(detJacobian) print 'Range:', detJacobian.min(), detJacobian.max() X1, X0 = np.mgrid[0:displacement_clean.shape[0], 0:displacement_clean.shape[1]] CS = plt.contour(X0, X1, detJacobian, levels=[0.0], colors='b') plt.clabel(CS, inline=1, fontsize=10) plt.title('det(J(displacement))') displacement = displacement_clean + np.random.normal( 0.0, 1.1, displacement_clean.shape) #displacement=np.array(displacement_clean) #inverse=rcommon.invert_vector_field_fixed_point(displacement, 100, 1e-7) #inverse=np.array(tf.invert_vector_field(displacement, 0.1, 100, 1e-7)) lambdaParam = 5.0 #########Jacobi########## inverse = np.array( tf.invert_vector_field(displacement, lambdaParam, 100, 1e-6)) residual, stats = tf.compose_vector_fields(displacement_clean, inverse) residual = np.array(residual) print 'Jacobi. Max:', stats[0], '. Mean:', stats[1], 'Std:', stats[2] [d, invd, res, detJ] = rcommon.plotDiffeomorphism(displacement, inverse, residual, 'Jacobi', 7) #########Fixed point###### inverse = np.array( tf.invert_vector_field_fixed_point(displacement, 100, 1e-6)) residual, stats = tf.compose_vector_fields(displacement_clean, inverse) residual = np.array(residual) print 'Fixed point. Max:', stats[0], '. Mean:', stats[1], 'Std:', stats[2] [d, invd, res, detJ] = rcommon.plotDiffeomorphism(displacement, inverse, residual, 'Fixed point', 7) #########TV-L2########### inverse = np.array( tf.invert_vector_field_tv_l2(displacement, lambdaParam, 3000, 1e-6)) residual, stats = tf.compose_vector_fields(displacement_clean, inverse) residual = np.array(residual) print 'TV-L2. Max:', stats[0], '. Mean:', stats[1], 'Std:', stats[2] [d, invd, res, detJ] = rcommon.plotDiffeomorphism(displacement, inverse, residual, 'TV-L2', 7)
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 testCircleToCMonomodalDiffeomorphic(lambdaParam): import numpy as np import tensorFieldUtils as tf import matplotlib.pyplot as plt import registrationCommon as rcommon fname0 = 'data/circle.png' #fname0='data/C_trans.png' fname1 = 'data/C.png' circleToCDisplacementName = 'circleToCDisplacement.npy' circleToCDisplacementInverseName = 'circleToCDisplacementInverse.npy' nib_moving = plt.imread(fname0) nib_fixed = plt.imread(fname1) moving = nib_moving[:, :, 0] fixed = nib_fixed[:, :, 1] moving = (moving - moving.min()) / (moving.max() - moving.min()) fixed = (fixed - fixed.min()) / (fixed.max() - fixed.min()) level = 3 maskMoving = moving > 0 maskFixed = fixed > 0 movingPyramid = [ img for img in rcommon.pyramid_gaussian_2D(moving, level, np.ones_like(maskMoving)) ] fixedPyramid = [ img for img in rcommon.pyramid_gaussian_2D(fixed, level, np.ones_like(maskFixed)) ] rcommon.plotOverlaidPyramids(movingPyramid, fixedPyramid) displacementList = [] maxOuterIter = [10, 50, 100, 100, 100, 100, 100, 100, 100] if (os.path.exists(circleToCDisplacementName)): displacement = np.load(circleToCDisplacementName) inverse = np.load(circleToCDisplacementInverseName) else: displacement, inverse = estimateMonomodalDiffeomorphicField2DMultiScale( movingPyramid, fixedPyramid, lambdaParam, maxOuterIter, 0, displacementList) np.save(circleToCDisplacementName, displacement) np.save(circleToCDisplacementInverseName, inverse) X1, X0 = np.mgrid[0:displacement.shape[0], 0:displacement.shape[1]] detJacobian = rcommon.computeJacobianField(displacement) plt.figure() plt.imshow(detJacobian) CS = plt.contour(X0, X1, detJacobian, levels=[0.0], colors='b') plt.clabel(CS, inline=1, fontsize=10) plt.title('det(J(displacement))') print 'J range:', '[', detJacobian.min(), detJacobian.max(), ']' #directInverse=np.array(tf.invert_vector_field(displacement, 0.5, 1000, 1e-7)) directInverse = np.array( tf.invert_vector_field_fixed_point(displacement, 100, 1e-7)) detJacobianInverse = rcommon.computeJacobianField(directInverse) plt.figure() plt.imshow(detJacobianInverse) CS = plt.contour(X0, X1, detJacobianInverse, levels=[0.0], colors='w') plt.clabel(CS, inline=1, fontsize=10) plt.title('det(J(displacement^-1))') print 'J^-1 range:', '[', detJacobianInverse.min(), detJacobianInverse.max( ), ']' #directInverse=rcommon.invert_vector_field_fixed_point(displacement, 1000, 1e-7) residual, stats = tf.compose_vector_fields(displacement, inverse) residual = np.array(residual) directResidual, stats = tf.compose_vector_fields(displacement, directInverse) directResidual = np.array(directResidual) # warpPyramid=[rcommon.warpImage(movingPyramid[i], displacementList[i]) for i in range(level+1)] # rcommon.plotOverlaidPyramids(warpPyramid, fixedPyramid) # rcommon.overlayImages(warpPyramid[0], fixedPyramid[0]) rcommon.plotDiffeomorphism(displacement, inverse, residual, 'inv-joint', 7) rcommon.plotDiffeomorphism(displacement, directInverse, directResidual, 'inv-direct', 7) tf.write_double_buffer(displacement.reshape(-1), 'displacement.bin')